[Java의 정석] 10. 날짜와 시간 & 형식화

Rowan Lee·2025년 1월 30일

자바

목록 보기
10/10

챕터10. 날짜와 시간 & 형식화


Date는 날짜와 시간을 다룰 목적으로 JDK1.0부터 제공되어온 클래스이다. 그러나 기능이 빈약하여 Calendar이라는 새로운 크래스를 JDK 1.1부터 제공했다. 그러나 이것도 단점이 있어 JDK1.8부터는 java.time패키지를 사용한다.

따라서 책에선 CalendarDate도 설명하지만 java.time클래스만 정리하겠다. 또한 필요한 시점에 다시 읽어보도록 한다.

형식화 클래스

값을 문자열로 나타내거나 문자열을 값으로 변환할때 생각보다 많은 코드가 필요하다. 이걸 편리하게 제공해주는 형식화 클래스가 자바에 존재한다.

DecimalFormat - 숫자 출력 format

DecimalFormat은 숫자를 형식화하여 출력하는데 사용된다. 숫자 데이터를 정수, 부동소수점, 금액등 다양한 형식으로 표현할 수 있게 해준다.

double number = 1234567.89;
DecimalFormat df = new DecimalFormat("#.#E0");
String result = df.format(number);

/* 예시
0 : 1234568
# : 1234568
0.0 : 1234567.9
#.# : 1234567.9
...
*/

SimpleDateFormat - 날짜 출력 format

Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); // M만 대문자인 이유는 소문자 m이 이미 분(minitue)으로 사용중이라 월(month)는 M이다.
df.format(today);

마찬가지로 날짜를 형식화해서 문자열로 만들거나 문자열을 날짜로 바꿔준다.

java.time 패키지

JDK1.8부터 추가된 현존 날짜와 시간을 다루는 최신 패키지이다. 패키지 개수는 많지만 핵심적인 클래스는 많지 않다.

패키지설명
java.time날짜와 시간을 다루는데 필요한 핵심 클래스들을 제공
java.time.chrono표준(ISO)이 아닌 달력 시스템을 위한 클래스들을 제공
java.time.format날짜와 시간을 파싱하고, 형식화하기 위한 클래스들을 제공
java.time.temporal날짜와 시간의 필드(field)와 단위(unit)를 위한 클래스들을 제공
java.time.zone시간대와 관련된 클래스들을 제공

위 패키지들의 가장 큰 특징은 불변(immutable)하다는 것이다. 이는 스레드 안전을 위한 것이다.

java.time 패키지의 핵심 클래스

LocalDate는 날짜를 다루며 LocalTime는 시간을 다룬다. LocalDateTime클래스는 날짜와 시간을 모두 함께 다룬다.

여기에 time-zone까지 다뤄야한다면 ZoneDateTime을 사용한다.

LocalDate(날짜) + LocalTime(시간) = LocalDateTime(날짜 & 시간)
LocalDateTime + time-zone = ZoneDateTime

Period & Duration

Period는 두 날짜간의 차이를 표현하기 위함. (날짜 - 날짜)
Duration은 시간의 차이를 표현하기 위함. (시간 - 시간)

now(), of()

java.time 패키지에 속한 클래스의 객체를 생성하는 가장 기본적인 방법 두가지이다.
now()은 현재 시간을 인스턴스로 가져오는 메서드이며, of()는 특정 시간을 매개변수로 입력해서 생성한다.

LocalDate date = LocalDate.now(); // 2015-11-23
LocalTime time = LocalTime.now(); // 21:54:01.875
LocalDateTime dateTime = LocalDateTime.now(); // 2015-11-23T21:54:01.875
ZonedDateTime dateTimeInKr = ZonedDateTime.now(); // 2015-11-23T21:54:01.875+09:00[Asia/Seoul]

LocalDate date = LocalDate.of(2015, 11, 23);
LocalTime time = LocalTime.of(23, 59, 59);
LocalDateTime dateTime = LocalDateTime.of(date, time); 
ZonedDateTime dateTimeInKr = ZonedDateTime.of(dateTime, ZoneId.of("Asia/Seoul")); 

Temporal과 TemporalAmount

LocalDate, LocalTime, LocalDateTime, ZonedDateTime등 날짜와 시간을 표현하기 위한 클래스들은 모두 Temporal, TemporalAccessor, TemporalAdjuster인터페이스를 구현했다.
DurationPeriodTemporalAmount 인터페이스를 구현하였다.

TemporalUnit과 TemporalField

TemporalUnit은 날짜와 시간의 단위를 정의해 놓은 인터페이스.
ChronoUnit은 이 인터페이스를 구현한 열거형.
TemporalFeild는 년, 원, 일 등 날짜와 시간의 필드를 정의해 놓은 것으로 ChronoFild가 해당 인터페이스를 구현했다.

날짜나 시간에서 특정 필드만 값을 얻을때는 get()이나 get으로 시작하는 메서드를 사용한다. 특정 단위의 값을 빼거나 더할때는 plus()또는 minus()를 사용한다.

LocalTime now = LocalTime.now();
int minute = now.getMinute();

LocalDate tomorrow = now.pulsDays(1);

Instant

Instant에포크 타임(1970-01-01 00:00:00 UTC)부터 경과된 시간을 나노초 단위로 표현한다. 사람에겐 불편하지만 단일 진법이라 계산이 쉽다.

주의할 점은 UTC(+00:00): Coordinated Universal Time 세계 협정시를 기준으로 하므로 한국은 +09:00를 해줘야한다. OffsetDateTime을 사용하면 이런차이를 좀 더 편하게 다룰 수 있다.

참고로 그리니치 천문대 기준시는 GMT(Greenwich Mean Time)이며 UTC와 거의 비슷하지만 UTC가 더 정확하다.

인스턴스 생성방법

Instant now = Instant.now();
Instant now2 = Instant.ofEpochSecond(now.getEpochSecond());
Instant now3 = Instant.ofEpochSecond(now.getEpochSecond(), now.getNano());
long epochSec = now.getEpochSecond();
int nano = now.getNano();

초 단위와 나노초 단위로 불러오기

Instant <-> Date

static Date from(Instant instant) // Instant -> Date
Instant toInstant()				  // Date -> Instant

LocalDateTime과 ZonedDateTime

LocalDate + LocalTime -> LocalDateTime
LocalDateTime + 시간대 -> ZonedDateTime

TemporalAdjusters

단순히 며칠 후, 몇 년 후(상대적인 계산)를 제외하고 다른 여러가지 검사가 가능하다. 예를 들면 다음해의 첫 날과 같은 검사를 메서드로 제공한다.

profile
CS/Software Engineer

0개의 댓글