(1) 날짜, 시간 관련 API
(LocalTime, LocalDate, LocalDateTime)
기존에 사용했던 Date
, Calendar
클래스들은 결과가 직관적이지 않고, 달(Month)의 인덱스가 0부터 시작한다는 점과 스레드에 안전하지 않는 등 많은 문제점들이 있었습니다. 이를 보완하기 위해 자바 8 버전에서 추가된 날짜, 시간 관련 클래스인 LocalTime
, LocalDate
, LocalDateTime
API를 지원합니다.
1. 날짜, 시간 관련 정적 팩토리 메서드
1-1. LocalTime
now()
현재 시스템 시계에서 현재 시간을 LocalTime 객체를 생성합니다.
LocalTime localTime1 = LocalTime.now(); // 01:53:44.770
of(int hour, int minute, int second, int nanoOfSecond)
시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)를 받아 LocalTime
객체를 생성합니다.
LocalTime localTimeOf1 = LocalTime.of(13, 30); // 13:30
LocalTime localTimeOf2 = LocalTime.of(13, 30, 12); // 13:30:12
LocalTime localTimeOf3 = LocalTime.of(13, 30, 12, 100); // 13:30:12.000000100
parse(CharSequence text, DateTimeFormatter formatter)
시간 문자열과 파싱 할 시간 포맷을 받아 LocalTime
객체를 생성합니다. 시간 문자열 포맷이 기본 형태인 'HH:mm:ss'의 형태라면 DateTimeFormatter
이 필요 없지만 기본 형태가 아니라면 시간 포맷을 인자로 넘겨줘야 합니다.
// ✨ 기본 시간 포맷인 'HH:mm:ss'이므로 DateTimeFormatter가 필요없다.
// 출력 : 13:30
LocalTime localTime = LocalTime.parse("13:30:00"); // 출력 : 13:30
// ✨ 기본 시간 포맷이 아니므로 시간 문자열에 맞는 DateTimeFormatter가 필요하다.
// 출력 : 13:30
LocalTime localTime = LocalTime.parse("13 30 00", DateTimeFormatter.ofPattern("HH mm ss"));
from(TemporalAccessor temporal)
TemporalAccessor
인터페이스를 구현한 객체의 시간 정보를 이용하여 LocalTime
객체를 생성합니다. 일반적으로 사용하는 시간, 날짜 관련 객체들은 TemporalAccessor
인터페이스를 구현한 객체이므로 시간 정보가 포함된 객체를 인자로 사용하시면 됩니다.
LocalDateTime localDateTime = LocalDateTime.now();
LocalTime localTime3 = LocalTime.from(localDateTime); // 17:31:14.104456
ZonedDateTime zonedDateTime = ZonedDateTime.of(
2023, 8, 15,
15, 20, 30, 0,
ZoneId.systemDefault());
LocalTime localTime4 = LocalTime.from(zonedDateTime); // 15:20:30
ofInstant(Instant instant, ZoneId zone)
협정 세계시(UTC)를 기준으로 하는 클래스인 Instant
와 시간대(time zone)를 나타내는 ZoneId
클래스를 이용하여 LocalTime
객체를 생성합니다. ofInstant
메서드를 이용하면 각 나라의 시간을 구할 수 있습니다.
참고로 서울의 시간은 UTC+9 입니다.
Instant now = Instant.now(); // 현재 시간 기준 -9 시간을 뺀 시간이 생성된다.
ZoneId zoneId = ZoneId.systemDefault(); // "Asiz/Seoul" 서울 시간대
LocalTime localTime5 = LocalTime.ofInstant(now, zoneId); // 현재 서울의 시간
ZoneId seoulZone = ZoneId.of("Asia/Seoul"); // 서울 시간대
ZoneId newYorkZone = ZoneId.of("America/New_York"); // 뉴욕 시간대
LocalTime localTime6 = LocalTime.ofInstant(now, newYorkZone); // 특정 시간대의 시각
ofNanoOfDay(long nanoOfDay)
나노초(nanoOfDay) 단위를 인자로 받아 LocalDate
객체를 생성합니다.
long nanoOfDay = 5_000_000_000L; // 5초에 해당하는 나노초
LocalTime timeFromNanoOfDay = LocalTime.ofNanoOfDay(nanoOfDay);
System.out.println(timeFromNanoOfDay); // 출력: 00:00:05
ofSecondOfDay(long secondOfDay)
초(secondOfDay) 단위를 인자로 받아 LocalDate
객체를 생성합니다.
long secondOfDay = 36_500L; // 10시 8분 20초에 해당하는 초
LocalTime localTime8 = LocalTime.ofSecondOfDay(secondOfDay);
System.out.println(localTime8); // 출력: 10:08:20
그 외 클래스 변수
LocalTime
클래스는 네 가지 클래스 변수들을 제공합니다. 최소 시간, 최대 시간, 자정, 정오를 구할 수 있도록 클래스 변수로 선언되어 있습니다. 참고로 LocalTime.MIN
과 LocalTime.MIDNIGHT
은 같은 값을 갖지만 2개의 클래스 변수로 선언된 이유는 의미론적 이유 때문이라고 java.time.* 저자가 말했습니다. 2개의 클래스 변수를 선언하는 것이 코드 내부에서 시간의 최솟값을 구하는 것인지, 하루의 시작을 구하는 것인지에 대한 의미를 전달하는 비용이 1개의 클래스 변수로 관리하는 것보단 비용이 절감되기 때문이라고 합니다.(음.. 저는 그렇게 공감이 되는 말이 아니었네요)
java - LocalTime.MIDNIGHT 대 LocalTime.MIN - 차이점이 있습니까? - 스택 오버플로 (stackoverflow.com)
// 출력 : 00:00
LocalTime min = LocalTime.MIN;
// 출력 : 23:59:59.999999999
LocalTime max = LocalTime.MAX;
// 출력 : 00:00
LocalTime midnight = LocalTime.MIDNIGHT;
// 출력 : 12:00
LocalTime noon = LocalTime.NOON;
1-2. LocalDate
now()
현재 시스템 기계에서 현재 날짜로 LocalDate
객체를 생성합니다
LocalDate localDate1 = LocalDate.now(); // 출력 : 2023-08-15
of(int year, int month, int dayOfMonth)
of(int year, Month month, int dayOfMonth)
연도(year), 달(month), 일(dayOfMonth)를 받아 LocalDate 객체를 생성합니다
// of 사용 1
LocalDate localDate2 = LocalDate.of(2023, 8, 15);
log.info("localDate2 = {}", localDate2); // 출력 : 2023-08-15
// of 사용 2
LocalDate localDate3 = LocalDate.of(2023, Month.AUGUST, 15);
log.info("localDate3 = {}", localDate3); // 출력 : 2023-08-15
parse(CharSequence text)
parse(CharSequence text, DateTimeFormatter formatter)
날짜 문자열과 파싱 할 날짜 포맷을 받아 LocalDate
객체를 생성합니다. 날짜 문자열 포맷이 기본 형태인 'yyy-MM-dd'의 형태라면 DateTimeFormatter
이 필요 없지만 기본 형태가 아니라면 날짜 포맷을 인자로 넘겨줘야 합니다.
// ✨ 기본 시간 포맷인 yyyy-MM-dd'이므로 DateTimeFormatter가 필요없다.
// 출력 : 2023-08-15
LocalDate localDate4 = LocalDate.parse("2023-08-15");
// ✨ 기본 시간 포맷이 아니므로 날짜 문자열에 맞는 DateTimeFormatter가 필요하다.
// 출력 : 2023-08-15
LocalDate localDate5 = LocalDate.parse("2023.08.15", DateTimeFormatter.ofPattern("yyyy.MM.dd"));
from(TemporalAccessor temporal)
TemporalAccessor
인터페이스를 구현한 객체의 날짜 정보를 이용하여 LocalDate
객체를 생성합니다. 일반적으로 사용하는 시간, 날짜 관련 객체들은 TemporalAccessor
인터페이스를 구현한 객체이므로 날짜 정보가 포함된 객체를 인자로 사용하시면 됩니다.
// from 사용 1
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate6 = LocalDate.from(localDateTime);
log.info("localDate6 = {}", localDate6); // 출력 : 2023-08-15
// from 사용 2
ZonedDateTime zonedDateTime = ZonedDateTime.of(
2023, 8, 15,
8, 20, 30, 0,
ZoneId.systemDefault());
LocalDate localDate7 = LocalDate.from(zonedDateTime);
log.info("localDate7 = {}", localDate7); // 출력 : 2023-08-15
ofInstant(Instant instant, ZoneId zone)
협정 세계시(UTC)를 기준으로 하는 클래스인 Instant
와 시간대(time zone)를 나타내는 ZoneId
클래스를 이용하여 LocalDate
객체를 생성합니다. ofInstant
메서드를 이용하면 시간 오프셋에 맞는 각 나라의 날짜(UTC 기준 ±1일)를 구할 수 있습니다.
참고로 서울의 시간은 UTC+9 입니다.
// ofInstant 사용 1
Instant now = Instant.now(); // 현재 시간 기준 -9 시간을 뺀 LocalDate 생성
ZoneId zoneId = ZoneId.systemDefault(); // "Asia/Seoul" 서울 시간대
LocalDate localDate8 = LocalDate.ofInstant(now, zoneId); // 현재 서울의 날짜
log.info("localDate8 = {}", localDate8); // 출력 : 2023-08-15
// ofInstant 사용 2
ZoneId seoulZone = ZoneId.of("Asia/Seoul"); // 서울 시간대
ZoneId newYorkZone = ZoneId.of("America/New_York"); // 뉴욕 시간대
LocalDate localDate9 = LocalDate.ofInstant(now, newYorkZone); // 특정 시간대의 날짜
log.info("localDate9 = {}", localDate9); // 출력 : 2023-08-15
ofEpochDay(long epochDay)
Epoch는 1970-01-01인 날짜를 말하며 Epoch를 기준으로 날(epochDay)을 더한 LocalDate
객체를 생성합니다.
LocalDate localDate10 = LocalDate.ofEpochDay(18628);
log.info("localDate10 = {}", localDate10); // 출력 : 2023-08-15
ofYearDay(int year, int dayOfYear)
연도(year)를 기준으로 날(dayOfYear)을 더한 LocalDate
객체를 생성합니다.
LocalDate localDate11 = LocalDate.ofYearDay(2023, 227);
log.info("localDate11 = {}", localDate11); // 출력 : 2023-08-15
그 외 클래스 변수
LocalDate
는 3가지 클래스 변수를 제공합니다. 지원되는 최소 날짜, 최대 날짜, 그리고 Epoch 날짜를 구할 수 있도록 클래스 변수가 선언되어 있습니다.
// 출력 : -999999999-01-01
public static final LocalDate MIN = LocalDate.of(Year.MIN_VALUE, 1, 1);
// 출력 : +999999999-12-31
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
// 출력 : 1970-01-01
public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
1-3. LocalDateTime
now()
현재 시스템 기계에서 현재 날짜와 시간으로 LocalDateTime
객체를 생성합니다
// 출력 : 2023-08-19T15:28:09.066320400
LocalDateTime localDateTime1 = LocalDateTime.now();
of(int year, int month, int dayOfMonth, int hour, int minute)
of(int year, int month, int dayOfMonth, int hour, int minute, int second)
of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)
of(int year, Month month, int dayOfMonth, int hour, int minute)
of(int year, Month month, int dayOfMonth, int hour, int minute, int second)
of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)
연도(year), 달(month), 일(dayOfMonth), 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)를 받아 LocalDateTime
객체를 생성합니다
// 출력 : 2023-08-19T13:30
LocalDateTime localDateTime2 = LocalDateTime.of(2023, 8, 19, 13, 30);
// 출력 : 2023-08-19T13:30:11
LocalDateTime localDateTime3 = LocalDateTime.of(2023, 8, 19, 13, 30, 11);
// 출력 : 2023-08-19T13:30:11.000001
LocalDateTime localDateTime4 = LocalDateTime.of(2023, 8, 19, 13, 30, 11, 1000);
// 출력 : 2023-08-19T13:30
LocalDateTime localDateTime5 = LocalDateTime.of(2023, Month.AUGUST, 19, 13, 30);
// 출력 : 2023-08-19T13:30:12
LocalDateTime localDateTime6 = LocalDateTime.of(2023, Month.AUGUST, 19, 13, 30, 12);
// 출력 : 2023-08-19T13:30:12.000002
LocalDateTime localDateTime7 = LocalDateTime.of(2023, Month.AUGUST, 19, 13, 30, 12, 2000);
of(LocalDate date, LocalTime, time)
LocalDate와 LocalTime를 받아 LocalDateTime
객체를 생성합니다.
// 출력 : 2023-08-19T00:00
LocalDateTime localDateTime10 = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
parse(CharSequence text)
parse(CharSequence text, DateTimeFormatter formatter)
날짜와 시간 문자열과 파싱 할 날짜 포맷을 받아 LocalDateTime
객체를 생성합니다. 날짜와 시간 문자열 포맷이 기본 형태인 'yyy-MM-ddTHH:mm:ss'의 형태라면 DateTimeFormatter
이 필요 없지만 기본 형태가 아니라면 날짜 포맷을 인자로 넘겨줘야 합니다.
// ✨ 기본 시간 포맷인 yyyy-MM-dd'이므로 DateTimeFormatter가 필요없다.
// 출력 : 2023-08-19T14:03:30
LocalDateTime localDateTime11 = LocalDateTime.parse("2023-08-19T14:03:30");
// ✨ 기본 시간 포맷이 아니므로 날짜, 시간 문자열에 맞는 DateTimeFormatter가 필요하다.
// 출력 : 2023-08-19T14:03:30
LocalDateTime localDateTime12 = LocalDateTime.parse("2023.08.19 14:03:30", DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"));
from(TemporalAccessor temporal)
TemporalAccessor
인터페이스를 구현한 객체의 날짜 정보를 이용하여 LocalDateTime
객체를 생성합니다. 날짜와 시간 값이 모두 있어야 하기 때문에 LocalDateTime
, ZonedDateTime
, OffsetDateTime
을 사용할 수 있습니다.
ZonedDateTime zonedDateTime = ZonedDateTime.of(
2023, 8, 15,
8, 20, 30, 0,
ZoneId.systemDefault());
LocalDateTime localDateTime13 = LocalDateTime.from(zonedDateTime);
ofInstant(Instant instant, ZoneId zone)
협정 세계시(UTC)를 기준으로 하는 클래스인 Instant
와 시간대(time zone)를 나타내는 ZoneId
클래스를 이용하여 LocalDateTime
객체를 생성합니다. ofInstant
메서드를 이용하면 시간 오프셋에 맞는 각 나라의 날짜(UTC 기준 ±1일)와 시간을 구할 수 있습니다.
Instant now = Instant.now(); // 현재 시간 기준 -9 시간을 뺀 LocalDate 생성
ZoneId zoneId = ZoneId.systemDefault(); // "Asia/Seoul" 서울 시간대
LocalDateTime localDateTime14 = LocalDateTime.ofInstant(now, zoneId); // 현재 서울의 날짜와 시간
ZoneId seoulZone = ZoneId.of("Asia/Seoul"); // 서울 시간대
ZoneId newYorkZone = ZoneId.of("America/New_York"); // 뉴욕 시간대
LocalDateTime localDateTime15 = LocalDateTime.ofInstant(now, newYorkZone); // 뉴옥 날짜와 시간
그 외 클래스 변수
LocalDateTIme
는 두 가지 클래스 변수를 제공합니다. 지원되는 최소 날짜와 시간, 최대 날짜와 시간을 구할 수 있도록 클래스 변수가 선언되어 있습니다.
// 출력 : -999999999-01-01T00:00
LocalDateTime min = LocalDateTime.MIN;
// 출력 : +999999999-12-31T23:59:59.999999999
LocalDateTime max = LocalDateTime.MAX;
관련 포스팅
'Backend > Java' 카테고리의 다른 글
[Java] 🧵 Thread 기본 개념 (0) | 2025.04.06 |
---|---|
[Java] (2) 시간, 날짜 관련 API(LocalTime, LocalDate, LocalDateTime) (0) | 2023.08.20 |
[Java] 자바 8 - 올바른 Optional 사용법 (0) | 2023.08.13 |
[Java] 자바 8 - Optional 사용법 (1) | 2023.07.31 |
[Java] 자바 8, 9 - 컬렉션 API 개선 (0) | 2023.07.30 |