LANGUAGE/Java
날짜와 시간, 형식화
Doraemon_lulu
2023. 11. 23. 17:43
날짜와 시간
java.util.Date
- 정의
- java.util 패키지에 속하는 클래스
- 날짜와 시간을 다루기 위한 목적으로 만들어진 클래스 (JDK 1.0)
- Date의 메서드는 거의 deprecated 되었으나(앞으로 사용하지 않도록 권장함에 대한 의미), 여전히 많이 쓰이고 있음.
- 날짜와 시간을 항상 함께 다루어야 하는 단점이 있음.
java.util.Calendar
- 정의
- java.util 패키지에 속하는 클래스
- Date 클래스를 개선한 새로운 클래스이며, 여전히 단점이 존재함. (JDK 1.1)
- 날짜와 시간을 항상 함께 다루어야 하는 단점이 있음.
- But, 약 17년이라는 오랜 기간 사용되었음. - 특징
- 추상 클래스이며, getInstance()를 통해 구현된 객체를 얻어야 함.
- 인스턴스를 생성할 경우, 사용자들이 자유롭게 다양한 캘린더를 호출하여 사용하기 어렵기 때문에 다음과 같이 getInstance() 메서드를 호출하여 사용해야 함.
- getInstance() 메서드를 변경하여 다양한 캘린더를 사용할 수 있음.
/* 추상클래스는 인스턴스를 생성할 수 없음 */
// Calendar cal = new Calendar
/* 경우에 따라 getInstance() 메서드를 수정하여 사용할 수 있음. */
Calendar cal = Calendar.getInstance(); // 현재 날짜와 시간으로 셋팅됨.
int thisYear = cal.get(Calendar.YEAR); // 올해가 몇년도인지 확인함.
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE); // 이 달의 마지막날을 확인함.
- Calendar에 정의된 필드
- Month (월): 0(= 1월) ~ 11(= 12월)
- 그 해 (= 1월 1일 이후)
- 요일: 1(= 일요일) ~ 7(토요일)
- 날짜(Date)
필드명 | 기능 |
YEAR | 년 |
MONTH | 월 (*0부터 시작) |
DATE | 일 (= DAY_OF_MONTH) |
WEEK_OF_YEAR | 그 해의 몇 번째 주 |
WEEK_OF_MONTH | 그 달의 몇 번째 주 |
DAY_OF_YEAR | 그 해의 몇 번째일 |
DAY_OF_MONTH | 그 달의 몇 번째일 |
DAY_OF_WEEK | 요일 |
DAY_OF_WEEK_IN_MONTH | 그 달의 몇 번째 요일 |
- 시간 (Time)
필드명 | 기능 |
HOUR | 시간 (0 ~ 11) |
HOUR_OF_DAY | 시간 (0 ~ 23) - 24시간형 |
MINUTE | 분 |
SECOND | 초 |
MILLISECOND | 1/1000 초 |
ZONE_OFFSET | GMT 기준 시차 (1/1000초 단위) * KOREA: +9 (시간) |
AM_PM | 오전 / 오후 |
1) Calendar의 getInstance() 메서드 생성
Calendar today = Calendar.getInstance();
2) Calendar 객체 today의 필드 호출
today.get(Calendar.__(필드명)__)
import java.util.*;
class Ex10_1 {
public static void main(String[] args) {
/* 기본적으로 현재의 날짜 및 시간으로 설정됨. */
Calendar today = Calendar.getInstance();
System.out.println("이번 년도 : " + today.get(Calendar.YEAR));
System.out.println("이번 달 : " + today.get(Calendar.MONTH));
System.out.println("올해 몇 번째 주 : " + today.get(Calendar.WEEK_OF_YEAR));
System.out.println("이번 달 몇 번째 주 : " + today.get(Calendar.WEEK_OF_MONTH));
// Date = DAY_OF_MONTH
System.out.println("이 달의 몇 일 : " + today.get(Calendar.DATE));
System.out.println("이 달의 몇 일 : " + today.get(Calendar.DAY_OF_MONTH));
System.out.println("이번 년도의 몇 일 : " + today.get(Calendar.DAY_OF_YEAR));
System.out.println("요일 : " + today.get(Calendar.DAY_OF_WEEK));
System.out.println("이번 달의 몇 번째 요일 : " + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));
// Time
System.out.println("오전/오후 : " + today.get(Calendar.AM_PM));
System.out.println("시간 : " + today.get(Calendar.HOUR));
System.out.println("시간(24시간 기준): " + today.get(Calendar.HOUR_OF_DAY));
System.out.println("분(0 ~ 59) : " + today.get(Calendar.MINUTE));
System.out.println("초(0 ~ 59): " + today.get(Calendar.SECOND));
System.out.println("1000분의 1초(0~999): " + today.get(Calendar.MILLISECOND));
// 1000분의 1초를 시간 단위로 표현하기 위해 60X60(1시간=360초) X 1000(초)으로 계산함.
System.out.println("TimeZone(-12~+12): " + (today.get(Calendar.ZONE_OFFSET)/(60*60*1000)));
System.out.println("이달의 마지막 날 : " + today.getActualMaximum(Calendar.DATE) );
}
}
▼ [출력 결과]
올해 : 2023
이번 달 : 10
올해 몇 번째 주 : 47
이번 달 몇 번째 주 : 4
이 달의 몇 일 : 22
이 달의 몇 일 : 22
이번 년의 몇 일 : 326
요일 : 4
이번 달의 몇 번째 요일 : 4
오전/오후 : 1
시간 : 9
시간(24시간 기준): 21
분(0 ~ 59) : 44
초(0 ~ 59): 6
1000분의 1초(0~999): 313
TimeZone(-12~+12): 9
이달의 마지막 날 : 30
- set() 으로 날짜와 시간 지정
- 월(MONTH)의 경우, 0부터 시작하기 때문에 0은 1월을 의미하며 11은 12월을 의미함을 주의해야 함.
∵ 참고로 월(MONTH)의 경우 '배열'을 이용하기 때문에 0부터 시작함.
// 날짜와 시간을 지정하는 방법
void set(int field, int value);
void set(int year, int month, int date); // 년, 월, 일
void set(int hourOfDay, int minute, int second); // 시, 분, 초
Calendar date = Calender.getInstance(); // Calendar 객체(data) 생성
date.set(2023, 10, 22); // 2023년 11월 22일 (10월이 아님을 주의!!)
// void set(int field, int value); 와 같이 각각의 field 및 value 값을 사용하여 표현하는 경우
// void set(Calendar.YEAR, 2023); // 2023년
// void set(Calendar.MONTH, 10); // 11월
// void set(Calendar.DATE, 22); // 22일
- getTimeInMillis() 메서드
- 날짜 및 시간(시,분,초)을 millisecond(ms)로 변환하는 메서드 (*1/1000초로 변환; 1000ms = 1s)
- 형태: 객체명.getTimeInMillis / 1000
import java.util.*;
class Ex10_2 {
public static void main(String[] args) {
// 요일(DAY_OF_WEEK)에 대한 배열 생성
final String[] DAY_OF_WEEK = {"","일","월","화","수","목","금","토"};
// Calendar 객체들(birth, today)을 각각 생성함.
Calendar birth = Calendar.getInstance();
Calendar today = Calendar.getInstance();
// birth는 "2019년 4월 29일"로 설정함.
birth.set(2019, 3, 29);
System.out.println("birth는 " + toString(birth)
+ DAY_OF_WEEK[birth.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");
// 따로 today를 셋팅하지 않으면 현재 날짜로 출력됨.
System.out.println("오늘(today)은 " + toString(today)
+ DAY_OF_WEEK[today.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");
// 두 날짜 간의 차이를 얻기 위해서, getTimeInMillis() 1/1000초 단위로 변환해야 함.
long difference =
(today.getTimeInMillis() - birth.getTimeInMillis()) / 1000;
System.out.println("그 날(birth)은 현재(today)까지 "
+ difference + "초가 지났습니다.");
System.out.println("일(day)로 계산하면 " + difference / (24 * 60 * 60)
+ "일 입니다."); // 1일 = 24(시간) * 60(분) * 60(초)
}
// toString() 메서드 생성하여 년,월,일 호출 되도록 함.
public static String toString(Calendar date) {
return date.get(Calendar.YEAR)+"년 "+ (date.get(Calendar.MONTH)+1)
+ "월 " + date.get(Calendar.DATE) + "일 ";
}
}
- clear() 메서드
- Calendar 객체의 모든 필드를 초기화함.
→ 초기화된 값은 1970년 1월 1일 00:00:00 (0시 0분 0초) 으로 약속됨.
- clear(int field) 메서드: Calendar 객체의 특정 필드를 초기화함.
// Calendar 객체 dt 생성
Calendar dt = Calendar.getInstance();
// 현재 시간 반환됨.
System.out.println(new Date(dt.getTimeInMillis()));
dt.clear(); // Calendar 객체의 모든 필드 초기화
System.out.println(new Date(dt.getTimeInMillis())); // 1970년 1월 1일 00:00:00 반환
// 특정 필드만 초기화 하는 방법
dt.clear(Calendar.SECOND); // 초를 초기화
dt.clear(Calendar.MINUTE); // 분을 초기화
dt.clear(Calendar.HOUR_OF_DAY); // 시간을 초기화
dt.clear(Calendar.HOUR); // 시간을 초기화
- 다양한 메서드(method) 및 필드(field)의 관계 ★★★
- get(): 필드(field) 읽기
- set(): 필드(field) 변경
- clear(): 필드(field) 초기화
- add(): 특정 필드(field) 값을 증가 or 감소시킴. (다른 필드에 영향을 줄 수 있음)
- roll(): 특정 필드(field) 값을 증가 or 감소시킴. (다른 필드에 영향을 줄 수 없음)
Calendar date = Calendar.getInstance();
date.clear(); // 모든 필드(field) 초기화
date.set(2023, 10, 30); // 2023년 11월 30일로 날짜 설정
// add() 메서드의 경우, 다른 필드에 영향을 줌.
date.add(Calendar.DATE, 1); // 날짜(DATE)에서 1을 더하면 2023년 12월 1일이 됨. (월도 바뀜)
date.add(Calendar.MONTH, -8) // 월(MONTH)에서 8을 빼면 2023년 3월 30일이 됨.
// roll() 메서드의 경우, 다른 필드에 영향을 주지 않음.
date.roll(Calendar.DATE, 1) // 날짜(DATE)에서 1을 더하면 월은 바뀌지 않은 2023년 11월 1일이 됨.
- 달력 만드는 방법
- 말일 구하기: (다음 달 1일) - (1일)
- 1일의 요일 구하기 (1일이 일요일 이후인 경우, 빈 공간은 " " empty 처리 해줄 것) - Date 및 Calendar 간의 변환
- Date의 메서드는 대부분 deprecated 되었으나 여전히 사용되어지고 있음. (∵ Java는 하위 호환성이 좋기 때문에)
- Calendar를 Date로 변환하는 방법 vs Date를 Calendar로 변환하는 방법
/* Calendar를 Date로 변환 */
Calendar cal = Calendar.getInstance();
// Date의 생성자 안에서 Calender 객체의 getTimeInMillis 메서드를 호출하여 Date 객체 d에 저장함.
Date d = new Date(cal.getTimeInMillis());
/* Date를 Calendar로 변환 */
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d); // setTime 메서드를 통해 Date 객체 호출하여 Calendar 객체 cal에 저장함.
java.time 패키지
- 정의
- Date와 Calendar의 단점을 개선한 새로운 클래스들을 제공함. (JDK 1.8 = JDK 8)
- java.util.Date 및 java.util.Calendar의 경우에는 날짜와 시간을 항상 함께 다루어야 하는 단점이 있었음.
- java.time의 경우, 날짜와 시간을 독립적으로 다룰 수 있도록 개선됨.
형식화 클래스
형식화 클래스
- 정의
- java.text 패키지의 DecimalFormat (10진수 숫자로 설정), SimpleDateFormat (날짜 형식화)
- 숫자와 날짜를 원하는 형식으로 쉽게 출력하도록 함.
→ 숫자를 형식 문자열로, 혹은 날짜를 형식 문자열로 변환
- 형식 문자열에서 숫자와 날짜를 뽑아내는 기능을 하기도 함.
→ 형식 문자열을 숫자로, 혹은 형식 문자열을 날짜로 변환
DecimalFormat
- 정의
- 숫자를 형식화할 때 사용함. (→ 숫자를 형식 문자열로 변환할 때)
- 숫자 데이터를 정수, 부동소수점, 금액 등의 다양한 형식으로 표현할 수 있음. → parse(...);
- (반대로) 일정한 형식의 텍스트 데이터 또한 숫자로 변환할 수 있음. → format(...);
double number = 1234567.89;
/* 숫자 형식화 */
DecimalFormat df = new DecimalFormat("#.#E0"); // 지수 기호 사용하여 지수 형식으로 나타냄.
String result = df.format(number); // number에 저장된 double 값을 문자열로 변환하여 result에 저장
// 결과: result = 1.2E6
/* 특정 형식의 문자열을 숫자로 변환 */
DecimalFormat df = new DecimalFormat("#,###.##"); // 1,234,567.89
Number num = df.parse("1,234,567.89");
double d = num.doubleValue();
// 결과: d = 1234567.89
cf. Number: 모든 숫자 wrapper 클래스의 최고 조상임.
cf. Integer.parseInt(): 콤마(,)가 포함된 문자열은 숫자로 변환 불가함.
- 변환 시 사용하는 기호 및 의미, 패턴
기호 | 의미 | 패턴 | 결과(1234567.89) |
0 | 10진수 (*값 없는 자릿수는 0으로 채움) | 0 0.0 00000000.0000 |
1234568 (소수점 반올림하여 정수값만) 1234567.9 (소수점 첫번째 자리까지만) 001234567.8900 (빈자리 0으로 채움) |
# | 10진수 (값 없는 자리수 상관 없이 반환) | # #.# ########.#### |
1234568 (소수점 반올림하여 정수값만) 1234567.9 (소수점 첫번째 자리까지만) 1234567.89 (빈자리 그냥 넘김) |
. | 소수점 | #.# | 1234567.9 (소수점 첫번째 자리까지만) |
- | 음수 부호 | #.#- -#.# |
1234567.89- (뒤에 음수 부호 붙이기) -1234567.89 (앞에 음수 부호 붙이기) |
, | 단위 구분자 | #,###.## #,####.## |
1,234,567.89 (뒤에서부터 단위 당 자리수 맞추기) 123,4567.89 (뒤에서부터 단위 당 자리수 맞추기) |
E | 지수 기호 | #E0 0E0 ##E0 ... |
.1E7 1E6 1.2E6 ... |
SimpleDateFormat
- 정의
- 날짜와 시간을 다양한 형식으로 출력하도록 함.
- 특정 형식으로 되어있는 문자열에서 날짜 및 시간을 출력해낼 수 있음. - 활용 방법
- 원하는 출력 형식을 패턴을 작성하여 SimpleDateFormat 인스턴스를 생성함.
- 출력하고자 하는 인스턴스를 가지고 format()을 통해 호출하면 지정된 출력 형식에 맞게 변환된 문자열을 반환 받을 수 있음.
// 숫자를 문자열로 변환하여 반환
Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String result = df.format(today); // 오늘의 년,월,일을 문자열 형태로 변환하여 반환함.
// 문자열을 날짜 및 시간으로 변환하여 반환
DateFormat df1 = new StringDateFormat("yyyy년 MM월 dd일")
DateFormat df2 = new StringDateFormat("yyyy/MM/dd")
Date d = df1.parse("2023년 11월 23일"); // 문자열을 parse()를 사용하여 숫자데이터(Date)로 변환
String result = df2.format(d); // 숫자데이터(Date)를 format()을 사용하여 문자열로 변환
기호 | 의미 |
G | 연대(BC, AD) |
Y | 년도 |
M | 월 (1 ~ 12 or 1월 ~ 12월 or JAN ~ DEC) |
w | 년의 몇 번째 주 (1 ~ 53) |
W | 월의 몇 번째 주 (1 ~ 5) |
D | 년의 몇 번째 일 (1 ~ 366) |
d | 월의 몇 번째 일 (1 ~ 31) |
F | 월의 몇째 주 (몇 번째) 요일 (1 ~ 5) |
E | 요일 |
a | 오전/오후 (AM/PM) |
H | 시간 (0 ~ 23) |
k | 시간 (1 ~ 24) |
K | 시간 (0 ~ 11) |
h | 시간 (1 ~ 12) |
m | 분 (0 ~ 59) |
s | 초 (0 ~ 59) |
S | 천분의 일초 (0 ~ 999) |
z | Time zone (General time zone) (ex. GMT +9:00) |
Z | Time zone (RFC 822 time zone) |
' | escape 문자 (특수문자를 표현하는데 사용) |