NaiveDateTime — 시간대가 없는 날짜·시간
NaiveDateTime — 시간대가 없는 날짜·시간
NaiveDateTime은 시간대(time zone) 없이 날짜와 시간을 담는 구조체(struct) 예요. 이름의 "naive"(순진한)라는 말이 이 구조의 성격을 그대로 드러내요. 시간대 개념이 빠져 있다 보니 실제로 존재하지 않을 수도 있는 시각까지 그냥 표현해 버리죠.
출처: NaiveDateTime
본문
NaiveDateTime 구조체는 year, month, day, hour, minute, second, microsecond, calendar 필드를 가져요. 새 naive datetime은 new/2, new/8 함수나 ~N 시길(sigil_N/2)로 만들 수 있어요:
iex> ~N[2000-01-01 23:00:07]
~N[2000-01-01 23:00:07]
구조체 안의 날짜·시간 필드는 직접 접근할 수 있어요:
iex> naive = ~N[2000-01-01 23:00:07]
iex> naive.year
2000
iex> naive.second
7
왜 "naive"라고 부르는 걸까요. 이 datetime 표현에는 시간대가 없어서, 어떤 지역에서는 전혀 존재하지 않는 시각이라도 형식상으로는 유효한 값으로 남아 있어요. 예를 들어 어떤 지역이 서머타임(daylight saving)을 적용하면 시계는 보통 한 시간 앞으로 또는 뒤로 움직여요. 그 결과 어떤 시각은 아예 발생하지 않거나, 반대로 두 번 이상 발생하기도 해요. NaiveDateTime은 시간대 기준으로 검증되지 않으니까 이런 오류가 그대로 눈에 띄지 않고 지나갈 수 있어요.
그래서 개발자는 NaiveDateTime 구조체를 직접 만들기보다는, 이 모듈이 제공하는 함수나 서드파티 달력 라이브러리의 함수를 사용하는 게 안전해요.
naive datetime 비교하기
Elixir에서 ==/2, >/2, </2 같은 비교는 구조적(structural)이에요. 즉 NaiveDateTime 구조체의 필드 값을 기준으로 비교해요. naive datetime끼리 제대로 된 비교를 하려면 compare/2, after?/2, before?/2 함수를 쓰세요. 이 모듈에 compare/2가 있다는 것 덕분에 Enum.min/2, Enum.max/2로 Enum 안에서 최소·최대 naive datetime을 구할 수도 있어요:
iex> Enum.min([~N[2020-01-01 23:00:07], ~N[2000-01-01 23:00:07]], NaiveDateTime)
~N[2000-01-01 23:00:07]
에포크(epoch) 다루기
add/3와 diff/3는 시각을 계산하거나, 두 순간 사이의 초 수를 구할 때 써요. 예를 들어 Unix 에포크(1970-01-01 00:00:00)로부터 몇 초가 지났는지 계산해 볼게요:
iex> NaiveDateTime.diff(~N[2010-04-17 14:00:00], ~N[1970-01-01 00:00:00])
1271512800
iex> NaiveDateTime.add(~N[1970-01-01 00:00:00], 1_271_512_800)
~N[2010-04-17 14:00:00]
이 함수들은 위의 Unix 에포크나 그레고리오 에포크(0000-01-01 00:00:00) 같은 흔한 에포크를 처리할 때 최적화되어 있어요.