java.util.Date : 날짜와 시간을 다룰 목적으로 만들어진 클래스
java.util.Calendar : Date 클래스를 개선한 새로운 클래스
java.time 패키지 : Date와 Calendar는 날짜와 시간을 함께 다룰 수 밖에 없는 단점이 있는데 이것을 개선한 새로운 클래스들을 제공한다.(JDK 1.8 이후 부터)
추상 클래스이므로 getInstance()
를 통해 구현된 객체를 얻어야 한다.
Calendar cal = Calendar.getInstance(); // Calendar 객체 생성
int thisYear = cal.get(Calendar.YEAR);
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE);
Calendar cal = Calendar.getInstance();
: 현재 날짜와 시간으로 세팅int thisYear = cal.get(Calendar.YEAR);
: 올해가 몇년인지int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE);
: 이 달의 마지막 날필드명 | 설명 |
---|---|
YEAR | 년 |
MONTH | 월(0부터 시작) |
DATE | 일 |
WEEK_OF_YEAR | 그 해의 몇 번째 주 |
WEEK_OF_MONTH | 그 달의 몇 번째 주 |
DAY_OF_MONTH | 그 달의 몇 번째 일 |
DAY_OF_YEAR | 그 해의 몇 번째 일 |
DAY_OF_WEEK | 요일(1~7) 1 : 일요일 |
DAY_OF_WEEK_IN_MONTH | 그 달의 몇 번째 요일 |
HOUR | 시간(0~11) |
HOUR_OF_DAY | 시간(0~23) |
MINUTE | 분 |
SECOND | 초 |
MILLISECOND | 천분의 일 초 |
ZONE_OFFSET | GMT 기준 시차(천분의 일 초 단위) |
AM_PM | 오전/오후 |
Calendar date = Calendar.getInstance();
date.set(2022, 1, 22); // 2022년 2월 22일
date.set(2022, 1, 22);
: 월은 0부터 시작한다.Calendar time = Calendar.getInstance();
time.set(Calendar.HOUR_OF_DAY, 10);
time.set(Calendar.MINUTE, 20);
time.set(Calendar.SECOND, 30);
두 날짜를 천 분의 일 초 단위로 바꾸고 계산한다.
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
long difference = (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;
int differenceDay = difference / (24*60*60);
getTimeInMillis()
메서드를 통해 ms 단위로 변경 후 차이를 계산하고 1000
을 나눠서 초 단위로 바꿔준다.(24*60*60)
을 나눠준다.두 시간을 천 분의 일 초 단위로 바꾸고 계산한다.
import java.util.Calendar;
public class Ex10_3 {
public static void main(String[] args) {
final int[] TIME_UNIT = {3600, 60, 1}; // 큰 단위를 앞에 놓는다.
final String[] TIME_UNIT_NAME = {"시간 ", "분 ", "초 "};
Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
time1.set(Calendar.HOUR_OF_DAY, 10);
time1.set(Calendar.MINUTE, 20);
time1.set(Calendar.SECOND, 30); // 10시 20분 30초로 설정
time2.set(Calendar.HOUR_OF_DAY, 20);
time2.set(Calendar.MINUTE, 30);
time2.set(Calendar.SECOND, 10); // 20시 30분 10초로 설정
System.out.printf("time1 : %d시 %d분 %d초%n",
time1.get(Calendar.HOUR_OF_DAY), time1.get(Calendar.MINUTE), time1.get(Calendar.SECOND));
System.out.printf("time2 : %d시 %d분 %d초%n",
time2.get(Calendar.HOUR_OF_DAY), time2.get(Calendar.MINUTE), time2.get(Calendar.SECOND));
long difference = Math.abs(time2.getTimeInMillis() - time1.getTimeInMillis()) / 1000;
System.out.printf("두 시간의 차이는 %d초%n", difference);
String tmp = "";
for(int i = 0; i < TIME_UNIT.length; i++) {
tmp += difference/TIME_UNIT[i] + TIME_UNIT_NAME[i];
difference %= TIME_UNIT[i];
}
System.out.printf("두 시간의 차이는 %s입니다.", tmp);
}
}
time1 : 10시 20분 30초
time2 : 20시 30분 10초
두 시간의 차이는 36580초
두 시간의 차이는 10시간 9분 40초 입니다.
두 시간의 차이를 초 단위로 구한 값(difference
) : 36580
difference
를 시분초 단위로 바꾸는 법은 1시간은 3600초기 때문에 3600으로 나눈 몫이 시간, 3600으로 나눈 나머지를 또 60으로 나눈 몫이 분, 60으로 나눈 나머지가 초가 된다.
: Calendar 객체의 모든 필드를 초기화
Calendar dt = Calendar.getInstance(); // 현재 시간
System.out.println(new Date(dt.getTimeInMillis())); // 현재 시간 출력
dt.clear();
System.out.println(new Date(dt.getTimeInMillis())); // EPOCH Time으로 초기화 : 1970년 1월 1일 00:00:00
Sun Mar 05 17:08:49 KST 2023
Thu Jan 01 00:00:00 KST 1970
clear(int field) : Calendar 객체의 특정 필드를 초기화
Calendar dt = Calendar.getInstance(); // 현재 시간
System.out.println(new Date(dt.getTimeInMillis()));
dt.clear(Calendar.SECOND); // 초를 초기화
dt.clear(Calendar.MINUTE); // 분을 초기화
dt.clear(Calendar.HOUR_OF_DAY); // 시간을 초기화
dt.clear(Calendar.HOUR); // 시간을 초기화
getInstance()로 객체 생성을 한 다음 set() 메서드를 쓰기 전에 clear()로 초기화 해줘야 한다.
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
System.out.println(date1);
System.out.println(date2);
set()
메서드로 지정해주기 전에 clear()
메서드로 초기화 해줘야 한다.: 특정 필드의 값을 증가 또는 감소(다른 필드에 영향 O)
Calendar dt = Calendar.getInstance();
dt.clear();
dt.set(2023, 7, 31); // 2023년 8월 31일
dt.add(Calendar.DATE, 1); // + 1일 -> 2023년 9월 1일
dt.add(Calendar.MONTH, -8); // - 8개월 -> 2023년 1월 1일
: 특정 필드의 값을 증가 또는 감소(다른 필드에 영향 X)
Calendar dt = Calendar.getInstance();
dt.clear();
dt.set(2023, 7, 31); // 2023년 8월 31일
dt.roll(Calendar.DATE, 1); // + 1일 -> 2023년 8월 1일
dt.roll(Calendar.MONTH, -8); // - 8개월 -> 2023년 12월 1일
import java.util.*;
class Ex10_5 {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage : java Ex10_5 2019 9");
return;
}
int year = Integer.parseInt(args[0]);
int month = Integer.parseInt(args[1]);
int START_DAY_OF_WEEK = 0; // 1일의 요일
int END_DAY = 0;
Calendar sDay = Calendar.getInstance(); // 시작일
Calendar eDay = Calendar.getInstance(); // 끝일
// 월은 0이 1월, 11이 12월이기 때문에 -1을 해준다.
sDay.set(year, month - 1, 1);
eDay.set(year, month, 1);
// 끝일은 다음달 1일에서 -1을 해준다.
eDay.add(Calendar.DATE, -1);
// 1일이 무슨 요일인지 알아낸다.
START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK);
END_DAY = eDay.get(Calendar.DATE);
System.out.println(" " + year + "년 " + month + "월");
System.out.println(" SU MO TU WE TH FR SA");
for (int i = 1; i < START_DAY_OF_WEEK; i++)
System.out.print(" ");
for (int i = 1, n = START_DAY_OF_WEEK; i <= END_DAY; i++, n++) {
System.out.print((i < 10) ? " " + i : " " + i);
// 토요일이 될 때 마다 줄바꿈
if (n % 7 == 0) System.out.println();
}
}
}
Date의 메서드는 대부분 deprecated(사용하지 않을 것을 권장) 되었지만 여전히 사용
Calendar cal = Calendar.getInstance();
Date d = new Date(cal.getTimeInMillis());
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d);
: 숫자와 날짜를 형식화하여 출력하는 클래스(숫자, 날짜 -> 형식 문자열), 그 반대도 가능
java.text 패키지의 DecimalFormat, SimpleDateFormat
: 숫자를 형식화할 때 사용(숫자 -> 형식 문자열), 그 반대도 가능
기호 | 의미 | 패턴 | 결과(777.77) |
---|---|---|---|
0 | 10진수(값이 없을 때는 0) | 0 | 778 |
0.0 | 777.77 | ||
0000.000 | 0777.770 | ||
# | 10진수 | # | 778 |
#.# | 777.77 | ||
####.### | 777.77 |
숫자를 형식 문자열로 바꿀 때 사용(숫자 -> 형식 문자열)
double num = 1234567.89;
DecimalFormat df = new DecimalFormat("#.#E0"); // 지수 표현
String result = df.format(num);
result = "1.2E6"
형식 문자열에서 숫자로 변환(형식 문자열 -> 숫자)
DecimalFormat df = new DecimalFormat("#,###.##");
Number num = df.parse("1,234,567.89");
double d = num.doubleValue();
d = 1234567.89
[참고] Integer.parseInt()
는 콤마(,)가 포함된 문자열을 숫자로 변환 못시킨다.
: 날짜와 시간을 다양한 형식으로 출력할 수 있게 해준다.
Date today = new Date(); // 현재 날짜
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String result = sdf.format(today);
result = "2023-03-05"
날짜와 관련된 기호들
기호 | 의미 | 예시 |
---|---|---|
G | 연대(BC, AD) | AD |
Y | 연도 | 2023 |
M | 월 | 10, 10월, OCT |
w | 년의 몇 번째 주(1~53) | 52 |
W | 월의 몇 번째 주(1~5) | 4 |
D | 년의 몇 번째 일(1~365) | 300 |
d | 월의 몇 번째 일(1~31) | 15 |
F | 월의 몇 번째 요일(1~5) | 1 |
E | 요일 | 화 |
특정 형식으로 되어 있는 문자열에서 날짜와 시간을 뽑아낼 수 있다.
DateFormat df = new SimpleDateFormat("yyyy년 MM월 dd일");
DateFormat df2 = new SimpleDateFormat("yyyy/MM/dd");
Date d = df.parse("2022년 2월 2일");
String result = df.format(d);
String result2 = df2.format(d);
System.out.println("result = " + result);
System.out.println("result2 = " + result2);
result = 2022년 02월 02일
result2 = 2022/02/02
Date d = df.parse("2022년 2월 2일");
: 문자열을 Date 형으로 변환String result = df.format(d);
: Date 형식을 원하는 형식 문자열로 변환시간과 관련된 기호들
기호 | 의미 | 예시 |
---|---|---|
a | 오전/오후(AM, PM) | PM |
H | 시간(0~23) | 21 |
k | 시간(1~24) | 24 |
K | 시간(0~11) | 11 |
h | 시간(1~12) | 12 |
m | 분(0~59) | 55 |
s | 초(0~59) | 33 |
S | 천분의 일초(0~999) | 235 |
z | Time zone(General time zone) | GMT+9:00 |
Z | Time zone(RFC 822 time zone) | +0900 |