DateTime64 데이터 타입

DateTime64 데이터 타입

정의된 서브초(sub-second) 정밀도로 캘린더 날짜와 하루 중 시각으로 표현되는 순간을 저장하는 데이터 타입이에요. 틱 크기(정밀도)는 10^-precision 초이고, 기본 정밀도는 3(밀리초)이에요.

출처: 문서

본문

정의된 서브초 정밀도와 함께 캘린더 날짜와 하루 중 시각으로 표현할 수 있는 순간을 저장할 수 있어요. 틱 크기(정밀도)는 10⁻ᵖʳᵉᶜⁱˢⁱᵒⁿ 초예요. 유효 범위는 [0 : 9]이고, 보통 3(밀리초), 6(마이크로초), 9(나노초)를 사용해요. 기본값은 3(밀리초)이에요.

문법 (Syntax):

DateTime64(precision, [timezone])

내부적으로 epoch 시작(1970-01-01 00:00:00 UTC) 이후의 ‘틱(tick)’ 수를 Int64로 저장해요. 틱 분해능은 precision 매개변수로 결정돼요. 또한 DateTime64 타입은 컬럼 전체에 동일한 시간대를 저장할 수 있는데, 이는 DateTime64 타입 값이 텍스트 형식으로 표시되는 방식과 문자열로 지정된 값('2020-01-01 05:00:01.000')이 파싱되는 방식에 영향을 줘요. 시간대는 테이블 행(또는 결과셋)에 저장되지 않고 컬럼 메타데이터에 저장돼요. 자세한 내용은 DateTime을 참고해요.

지원 범위는 [0000-01-01 00:00:00, 9999-12-31 23:59:59.999999999]이에요. 소수점 이하 자릿수는 precision 매개변수에 따라 달라져요.

참고: 위 전체 범위는 정밀도 7까지 사용할 수 있어요. 틱이 Int64에 저장되므로 더 높은 정밀도는 더 좁은 범위를 다뤄요. 정밀도 8에서는 최대 값이 대략 4892-10-07이고, 최대 정밀도 9자리(나노초)에서 지원 범위는 UTC 기준 1677-09-21 00:12:44부터 2262-04-11 23:47:16까지예요.

예시 (Examples)

  • DateTime64 타입 컬럼이 있는 테이블을 만들고 데이터를 넣는 예시에요.
CREATE TABLE dt64
(
    `timestamp` DateTime64(3, 'Asia/Istanbul'),
    `event_id` UInt8
)
ENGINE = MergeTree;
-- Parse DateTime64
-- - from an integer interpreted as the number of seconds since 1970-01-01 (like DateTime),
-- - from a decimal interpreted as the number of seconds, the fractional part giving sub-second precision,
-- - from a string.

INSERT INTO dt64
VALUES
(1546300800, 1),
(1546300800.123, 2),
('2019-01-01 00:00:00', 3);

SELECT * FROM dt64;
┌───────────────timestamp─┬─event_id─┐
│ 2019-01-01 03:00:00.000 │        1 │
│ 2019-01-01 03:00:00.123 │        2 │
│ 2019-01-01 00:00:00.000 │        3 │
└─────────────────────────┴──────────┘
  • datetime을 숫자로 넣으면 DateTime처럼 초 단위의 Unix Timestamp(UTC)로 취급돼요. 1546300800은 UTC 기준 '2019-01-01 00:00:00'을 나타내요. 그런데 timestamp 컬럼에 Asia/Istanbul(UTC+3) 시간대가 지정되어 있으므로 문자열로 출력할 때 값은 '2019-01-01 03:00:00'으로 보여져요. 소수부가 있는 숫자도 같은 방식으로 동작해요. 소수점 앞부분은 초 단위 Unix Timestamp이고, 뒷부분은 컬럼의 정밀도에 따른 서브초 정밀도를 제공해요. (26.8 버전 이전에는 JSONValues/Quoted 입력 경로 — 후자는 Quoted 이스케이프 규칙으로 필드를 파싱하는 모든 형식(Values, MySQLDump, Quoted 필드 이스케이프로 구성된 Template/CustomSeparated/Regexp)을 포함 — 에서 따옴표 없는 정수를 대신 컬럼 정밀도의 원시 하부 값으로 해석했어요. 그래서 정밀도 3에서 1546300800000'2019-01-01 00:00:00'을 뜻했어요. 이런 경로에서 이전 동작을 복원하려면 input_format_read_datetime_number_as_raw_value = 1(또는 SET compatibility = '26.7')로 설정해요. 이는 JSONExtract 함수와 JSON 데이터 타입에도 영향을 줘요. 호환 설정은 따옴표 없는 정수에만 적용돼요. Values 형식에서 레거시 스트리밍 파서가 거부하는 소수 숫자는 SQL 표현식 평가로 폴백되어 초 단위로 읽히는데, 이는 26.8 이전 버전과 같아요. JSONExtractJSON 데이터 타입에서는 소수 값이 Float64로 파싱되므로, Float64가 보존할 수 있는 것보다 더 많은 자릿수를 가진 타임스탬프는 정확히 원문 텍스트를 파싱하는 행 입력 형식들과 달리 인접한 값으로 반올림될 수 있어요. 탭으로 구분된 형식, CSV 및 기타 이스케이프 텍스트 입력 형식은 이 설정의 적용을 받지 않으며 따옴표 없는 숫자에 대한 기존 해석(큰 값은 틱으로 읽음)을 유지해요.)

  • datetime을 문자열 값으로 넣으면 컬럼 시간대 기준으로 취급돼요. '2019-01-01 00:00:00'Asia/Istanbul 시간대 기준으로 취급되어 1546290000000으로 저장돼요.

  • DateTime64 값 필터링

SELECT * FROM dt64 WHERE timestamp = toDateTime64('2019-01-01 00:00:00', 3, 'Asia/Istanbul');
┌───────────────timestamp─┬─event_id─┐
│ 2019-01-01 00:00:00.000 │        3 │
└─────────────────────────┴──────────┘

DateTime과 달리 DateTime64 값은 String에서 자동으로 변환되지 않아요.

SELECT * FROM dt64 WHERE timestamp = toDateTime64(1546300800.123, 3);
┌───────────────timestamp─┬─event_id─┐
│ 2019-01-01 03:00:00.123 │        1 │
│ 2019-01-01 03:00:00.123 │        2 │
└─────────────────────────┴──────────┘

숫자를 넣을 때와 마찬가지로 toDateTime64 함수도 숫자 인자를 초 단위로 취급하므로, 소수점 뒤에 서브초 정밀도를 주어야 해요.

  • DateTime64 타입 값의 시간대 얻기
SELECT toDateTime64(now(), 3, 'Asia/Istanbul') AS column, toTypeName(column) AS x;
┌──────────────────column─┬─x──────────────────────────────┐
│ 2023-06-05 00:09:52.000 │ DateTime64(3, 'Asia/Istanbul') │
└─────────────────────────┴────────────────────────────────┘
  • 시간대 변환
SELECT
toDateTime64(timestamp, 3, 'Europe/London') AS lon_time,
toDateTime64(timestamp, 3, 'Asia/Istanbul') AS istanbul_time
FROM dt64;
┌────────────────lon_time─┬───────────istanbul_time─┐
│ 2019-01-01 00:00:00.123 │ 2019-01-01 03:00:00.123 │
│ 2019-01-01 00:00:00.123 │ 2019-01-01 03:00:00.123 │
│ 2018-12-31 21:00:00.000 │ 2019-01-01 00:00:00.000 │
└─────────────────────────┴─────────────────────────┘

더 알아보기 (Learn more)