Java에서 전통적으로 시간을 표현하는 기본 클래스는 Date 클래스다. Date 클래스는 unix epoch time의 milliseconds 단위로 시간을 다룬다.
Epoch Time 이란?
1970년 1월 1일(UTC/GMT 자정기준) 부터 얼마나 지났는지 초, 밀리초, 나노초 단위로 센 카운트값이다. 프로그래밍을 하면서 어떤 시점을 지역과 상관 없이 숫자로 표현하고 싶을 때 사용한다.
public class DateExample {
public static void main(String[] args) {
System.out.println(new Date());
System.out.println(new Date(1));
System.out.println(new Date().after(new Date(1)));
System.out.println(new Date().compareTo(new Date(1)));
System.out.println(new Date().compareTo(new Date()));
long future = 2228562001000L;
System.out.println(new Date(future));
System.out.println(new Date().compareTo(new Date(future)));
}
}
위에 단점들 때문에 자바8부터는 아래의 LocalDate, LocalTime, LocalDateTime라는 클래스가 도입됐다.
시간 없이 연-월-일 단위를 다루기 위한 클래스
LocalDate localDate = LocalDate.now();
LocalDate.of(2015, 02, 20);
LocalDate.parse("2022-02-20");
LocalDate tomorrow = LocalDate.now().plusDays(1);
LocalDate previousMonthSameDay = LocalDate.now().minus(1, ChronoUnit.MONTHS);
DayOfWeek sunday = LocalDate.parse("2022-06-12").getDayOfWeek();
int twelve = LocalDate.parse("2022-06-12").getDayOfMonth();
boolean leapYear = LocalDate.now().isLeapYear();
boolean notBefore = LocalDate.parse("2022-06-12").isBefore(LocalDate.parse("2022-06-11"));
boolean isAfter = LocalDate.parse("2022-06-12").isAfter(LocalDate.parse("2022-06-11"));
LocalDateTime beginningOfDay = LocalDate.parse("2022-06-12").atStartOfDay();
LocalDate firstDayOfMonth = LocalDate.parse("2022-06-12").with(TemporalAdjusters.firstDayOfMonth());
💡 factory 패턴
위 예제에서 사용한 now(), of(), parse() 는 객체를 생성할 때 사용되는 팩토리 함수다. 주어진 인자에 따라 객체를 생성 해야할 때 사용한다
날짜 없이 시간만 다루고 싶을 때 쓰는 클래스
LocalTime now = LocalTime.now();
LocalTime sevenThirty = LocalTime.parse("07:30");
LocalTime sevenThirty2 = LocalTime.of(7, 30);
LocalTime nineThirty = LocalTime.parse("07:30").plus(2, ChronoUnit.HOURS);
int seven = LocalTime.parse("07:30").getHour();
boolean isbefore = LocalTime.parse("06:30").isBefore(LocalTime.parse("07:30"));
LocalTime maxTime = LocalTime.MAX
날짜와 시간을 모두사용하고 싶을 때 사용하는 클래스
LocalDateTime.now();
LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30);
LocalDateTime.parse("2015-02-20T06:30:00");
localDateTime.plusDays(1);
localDateTime.minusHours(2);
localDateTime.getMonth();
타임존을 적용한 날짜와 시간을 다룰 때 사용한다.
ZoneId zoneId = ZoneId.of("Asia/Seoul");
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
ZonedDateTime.parse("2022-05-03T10:15:30+09:00[Asia/Seoul]");
LocalDateTime localDateTime = LocalDateTime.of(2022, Month.FEBRUARY, 20, 06, 30);
ZoneOffset offset = ZoneOffset.of("+02:00");
OffsetDateTime offSetByTwo = OffsetDateTime.of(localDateTime, offset);
시간이나 날짜 사이의 기간을 쉽고 type-safe하게 표현하기 위해서 Period, Duration 클래스를 사용한다.
두 날짜 사이의 기간을 표현할 때 Period를 사용한다.
LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));
int five = Period.between(initialDate, finalDate).getDays();
long five = ChronoUnit.DAYS.between(initialDate, finalDate);
두 시간 사이의 비교나 계산을 하기 위해 사용한다.
LocalTime initialTime = LocalTime.of(6, 30, 0);
LocalTime finalTime = initialTime.plus(Duration.ofSeconds(30));
long thirty = Duration.between(initialTime, finalTime).getSeconds();
long thirty = ChronoUnit.SECONDS.between(initialTime, finalTime);
Instant 클래스를 통해서 LocaDate, LocalTime, LocalDateTime 과 변환이 가능하다.
LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
LocalDateTime.ofInstant(Calendar.getInstance().toInstant(), ZoneId.systemDefault());
Date.fromInstant(LocalDateTime.now().toInstant(ZoneOffset.UTC))
LocalDateTime localDateTime = LocalDateTime.of(2022, Month.JANUARY, 25, 6, 30);
String localDateString = localDateTime.format(DateTimeFormatter.ISO_DATE);
localDateTime
.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.KOREA));
형식을 변환하는데 사용한 FormatStyle 내에 정적 변수로 다양한 종류의 형식이 있다.
FormatStyle의 사용법은 Javadoc에 자세한 설명이 있으니 참고.
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
사용하고자 하는 형식이 없거나 생각하는 형식이 있을 수 있다. ISO8601
에서 정의한 심볼을 통해서 원하는 형식으로 결과를 만들 수 있다.
LocalDateTime localDateTime = LocalDateTime.of(2022, Month.JANUARY, 25, 6, 30);
String localDateString = localDateTime.format(DateTimeFormatter.ISO_DATE);
localDateTime.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));