목표
- 기계 관점에서의 시간이 무엇인지, 왜 필요한지 이해한다.
- Instant를 만들기 위해서 필요한 구성 요소를 이해한다.
개요
기계에서 사람이 사용하는 날짜와 시간을 사용하기 위해서는 많은 기준과 그에 대한 연산이 필요하기 때문에 사람이 사용하는 날짜와 시간을 사용하여 시간을 표현하지 않는다. 기계의 관점에서는 날짜와 시간 단위를 끊어서 기록하기 보다는 연속된 시간에서 기준 시간을 두고 특정 지점을 하나의 수로 표현하는 것이 자연스럽다. 또한 특정 시간을 하나의 수로 표현하는 방식으로 데이터를 저장해야 시간 데이터를 수월하게 관리할 수 있다.
예를 들어 1970년 1월 1일 0시 0분 0초 UTC+0 이라는 시간 단위는 년, 월, 일, 시, 분, 초, 시간대 라는 7개 단위로 이루어져 있다. 이 시간은 기준점인 1970년 1월 1일 0시 0분 0초 UTC+0 을 절대값을 준다음 그로부터 지난 시간만 저장한다면 0초라는 1개의 단위로 저장 가능하다.
Java의 Time 패키지에서는 기계 관점에서 시간을 관리하는 Instant 클래스를 제공한다. 자 그러면 이제 Instant 클래스가 어떻게 이루어져 있는지 알아보도록 하자.
Instant 클래스 구성요소
위에서 말했듯이 기준 시간을 두고 특정 시점을 하나의 수로 표현하기 위한 객체를 만들기 위한 클래스가 바로 Instant 클래스이다. Instant 클래스의 기준 시간은 1970년 1월 1일 0시 0분 0초 UTC+0 이다. 따라서 Instant 클래스의 구성요소는 아래 하나이다.
- 1970년 1월 1일 0시 0분 0초 UTC+0 부터 지난 시간(초)
하지만, 우리가 쓰는 시간 구성요소로부터 위의 1970년 1월 1일 0시 0분 0초 UTC+0 부터 지난 시간(초)를 구하려면 다음 값들이 필요하다.
- 날짜(연, 월, 일)
- 시간(시, 분, 초)
- 시간대(TimeZone)
이 중 하나의 값이라도 빠진다면 Instant 클래스는 생성이 불가능하다. 예를 들어 시간대가 빠진 날짜와 시간 데이터만 있다고 하면 시간대(UTC)에 따라 기준시간으로부터 지난 시간이 달라질 수 있기 때문에 생성이 불가능하다.
Instant 만들기
따라서 Instant를 만드는 방법은 두가지이다.
- 1970년 1월 1일 0시 0분 0초 UTC+0 부터 지난 시간을 이용해 만드는 방법
- 날짜(연, 월, 일), 시간(시, 분, 초), 시간대(TimeZone)을 조합해 만드는 방법
1970년 1월 1일 0시 0분 0초 UTC+0 부터 지난 시간을 이용해 만드는 방법
1. 지난 시간을 초로 표현해 만드는 방법
val instantTime: Instant = Instant.ofEpochSecond(10L)
println(instantTime) // 1970-01-01T00:00:10Z
2. 지난 시간을 밀리초로 표현해 만드는 방법
val instantTime: Instant = Instant.ofEpochMilli(10L)
println(instantTime) // 1970-01-01T00:00:00.010Z
3. 지난 시간을 초와 나노초로 표현해 만드는 방법
val instantTime: Instant = Instant.ofEpochSecond(10L, 1L) // 1번째 변수 : 초, 2번째 변수 : 나노초
println(instantTime) // 1970-01-01T00:00:10.000000001Z
위와 같이 1970년 1월 1일 UTC+0로부터 지난 시간에 대한 값 만으로 Instant 객체를 만들어 낼 수 있다.
날짜(연, 월, 일), 시간(시, 분, 초), 시간대(TimeZone)을 조합해 만드는 방법
Instant를 만들기 위해서는 세가지 구성요소가 필요하다.
- 날짜(연, 월, 일)
- 시간(시, 분, 초)
- 시간대(TimeZone)
이 구성요소들은 다음과 같이 만들어질 수 있다. 너무 다양하게 만들 수 있어서 모두 다루지는 못하고 일부만 다루도록 하겠다.
1. LocalDateTime과 ZoneId를 이용해 Instant 만들기
val dateTime: LocalDateTime = LocalDateTime.of(2021, 1, 26, 19, 30, 20);
val zoneIdKorea: ZoneId = ZoneId.of("Asia/Seoul");
val instant: Instant = dateTime.atZone(zoneIdKorea).toInstant()
println(instant) // 2021-01-26T10:30:20Z
instant의 Z는 UTC+0를 뜻한다. 한국은 UTC+9이므로 9시간을 뺀 값이 Instant의 시간이 된다.
2. ZonedDateTime과 Instant.from() 메서드를 이용해 Instant 만들기
val dateTime: LocalDateTime = LocalDateTime.of(2021, 1, 26, 19, 30, 20);
val zoneIdKorea: ZoneId = ZoneId.of("Asia/Seoul");
val zonedDateTime: ZonedDateTime = dateTime.atZone(zoneIdKorea)
val instant: Instant = Instant.from(zonedDateTime)
println(instant) // 2021-01-26T10:30:20Z
정리
Instant를 만들 수 있는 방법은 다양하다. 위에서는 그 중 일부만을 보았다. 중요한 점은 Instant를 만들기 위해서 필요한 요소들을 아는 것이다. 필요한 요소들에 대한 구분만 완벽히 된다면 어떠한 방식으로든 Instant를 만들어낼 수 있다.