개발 이야기3분 읽기

존재하지 않는 시각과 두 번 오는 시각

시간대 변환에서 하루가 23시간이거나 25시간이 되는 날이 있습니다. 오프셋을 저장하면 왜 깨지는지 실행 결과로 정리했습니다.

회의를 서울 오후 6시로 잡고 뉴욕 참석자에게 시각을 알려 줘야 합니다. 시차는 13시간이니 오전 5시입니다.

그 계산은 날짜에 따라 틀립니다.

오프셋은 지역의 속성이 아니다

같은 순간을 여러 지역에서 본 결과입니다.

UTC                    2026-08-28 03:00:00   GMT+00:00
Asia/Seoul             2026-08-28 12:00:00   GMT+09:00
Asia/Kolkata           2026-08-28 08:30:00   GMT+05:30
Asia/Kathmandu         2026-08-28 08:45:00   GMT+05:45
Australia/Lord_Howe    2026-08-28 13:30:00   GMT+10:30
Pacific/Chatham        2026-08-28 15:45:00   GMT+12:45
America/New_York       2026-08-27 23:00:00   GMT-04:00
Europe/London          2026-08-28 04:00:00   GMT+01:00

30분과 45분 단위 오프셋이 있습니다. 카트만두는 +5:45, 채텀 제도는 +12:45입니다. 시간 단위로만 처리하는 코드는 이 지역들에서 틀립니다.

날짜가 넘어가는 것도 봅니다 — 뉴욕은 아직 전날입니다.

같은 지역이 계절마다 다르다

2026-01-15  Europe/London  GMT+00:00
2026-07-15  Europe/London  GMT+01:00

런던은 겨울에 +00:00, 여름에 +01:00입니다. Europe/London은 오프셋이 아니라 규칙의 이름입니다 — 언제 오프셋을 바꾸는지에 대한 이력을 담고 있습니다.

그래서 미래 일정을 오프셋으로 저장하면 안 됩니다. 2026-11-15T09:00+01:00으로 저장한 런던 회의는 11월에 실제로 +00:00이라 한 시간 어긋납니다. 지역 이름과 현지 시각을 저장해야 합니다.

하루가 24시간이 아닌 날

미국의 서머타임 시작일입니다.

2026-03-08 01:30:00 EST
2026-03-08 03:30:00 EDT

두 시각 사이는 한 시간입니다. 02:30은 그날 존재하지 않습니다. 시계가 2시에서 3시로 건너뜁니다.

종료일에는 반대입니다.

2026-11-01 01:30:00 EDT
2026-11-01 01:30:00 EST

같은 벽시계 시각이 두 번 옵니다. 문자열 2026-11-01 01:30만으로는 어느 쪽인지 정할 수 없습니다.

이 이틀의 길이를 재 보면 이렇습니다.

2026-03-08 New York  23시간
2026-11-01 New York  25시간

어긋나는 자리들

매일 실행되는 작업. 새벽 2시 30분에 도는 배치는 3월 8일에 실행되지 않거나, 11월 1일에 두 번 실행됩니다. UTC 기준으로 도는 스케줄러라면 이 문제가 없는 대신 현지 시각이 매년 두 번 바뀝니다.

기간 계산. 날짜 + 24시간다음 날 같은 시각이 다른 날이 있습니다. 하루를 86,400초로 두고 더하면 3월 8일에 한 시간 밀립니다.

중복 시각의 로그 정렬. 11월 1일 01:30 로그 두 벌은 현지 시각으로 정렬하면 섞입니다. 저장은 UTC로 해야 순서가 유지됩니다.

약어는 유일하지 않다. CST는 미국 중부(-06:00), 중국(+08:00), 쿠바(-05:00)에 모두 쓰입니다. 약어로 시간대를 지정하면 해석이 갈립니다.

무엇을 저장하는가

저장 대상 형식
이미 일어난 일 (로그·생성 시각) UTC 타임스탬프
앞으로 할 일 (회의·알림) 지역 이름 + 현지 시각
날짜만 있는 것 (생일·기념일) 날짜 문자열, 시간대 없이

이미 일어난 일은 순간이 확정돼 있으므로 UTC 하나면 충분합니다. 앞으로 할 일은 규칙이 바뀔 수 있어서 지역 이름이 필요합니다 — 실제로 각국이 서머타임 규칙을 바꾸면 tz 데이터베이스가 갱신되고, 저장된 오프셋은 갱신되지 않습니다.

확인 순서

  1. 미래 일정을 오프셋이 붙은 타임스탬프로 저장하고 있다면 지역 이름을 함께 저장합니다
  2. 시차를 상수로 계산하는 코드를 찾습니다. +9, * 3600 같은 형태입니다
  3. 하루를 더할 때 86,400초를 더하는지, 날짜 연산을 쓰는지 봅니다
  4. 새벽 시간대에 도는 배치가 있으면 서머타임 전환일에 어떻게 되는지 확인합니다. 안전한 자리는 서머타임 전환이 없는 시각입니다
  5. 30분·45분 오프셋 지역을 테스트에 넣습니다. 인도·네팔·호주 일부가 그렇습니다

tools.onuel.dev시간대 변환기는 한 순간을 주요 지역에서 각각 몇 시로 보는지 함께 보여 줍니다. 그 날짜에 실제로 적용된 오프셋을 쓰므로, 서머타임 전환일 앞뒤로 날짜를 바꿔 넣으면 위의 23시간·25시간이 그대로 나옵니다. 타임스탬프 자체를 다룰 때는 Epoch 변환현재 Epoch을, 기간 표기는 기간 변환기를 씁니다.

  • #시간대
  • #날짜
  • #DST