Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Spark SQL 날짜와 시간 함수

날짜 함수는 Date/Timestamp 또는 파싱할 수 있는 문자열을 받습니다. 문자열의 기본 예는 yyyy-MM-dd, yyyy-MM-dd HH:mm:ss이며 다른 형식은 지원되는 파서에 패턴을 명시합니다. 시각의 해석과 표시는 세션 시간대 및 파싱 설정에 영향을 받습니다.

날짜 이동과 달력 값

함수와 인자의미
ADD_MONTHS(start, months)날짜를 지정 월 수만큼 이동. 시각 부분은 무시
DATEDIFF(end, start)end에서 start를 뺀 일 수
DATE_ADD(start, days)날짜에 일 수 더하기
DATE_SUB(start, days)날짜에서 일 수 빼기
DAYOFMONTH(expr)월 안의 일, 정수
DAYOFYEAR(expr)연중 일 번호, 정수
HOUR(expr)시, 정수
LAST_DAY(date)해당 월의 마지막 날짜
MINUTE(expr)분, 정수
MONTH(expr)월, 정수
MONTHS_BETWEEN(date1, date2[, roundOff])date1에서 date2를 뺀 월 수
NEXT_DAY(date, weekday)date보다 뒤에 있는 다음 지정 요일
QUARTER(expr)달력 분기, 1~4
SECOND(expr)초, 정수
WEEKOFYEAR(expr)연중 주 번호
YEAR(expr)연도, 정수

ADD_MONTHS는 원래 일을 유지하되 대상 월에 그 일이 없으면 월말로 조정합니다. Spark 3.0 이후에는 원래 날짜가 월말이라는 이유만으로 새 월의 월말에 맞추지 않습니다. 예를 들어 2019-02-28에 한 달을 더하면 2019-03-28입니다. Spark 2.4 이하의 월말 유지 동작과 구분합니다.

MONTHS_BETWEEN은 첫 날짜가 더 늦으면 양수, 더 빠르면 음수입니다. 두 날짜의 일이 같거나 둘 다 월말이면 정수이며, 그 외에는 31일 기준 부분 월을 계산하고 기본적으로 소수 8자리로 반올림합니다. roundOff=False이면 그 반올림을 끕니다.

NEXT_DAY는 Mon, Tue, Wed, Thu, Fri, Sat, Sun 표기를 대소문자 구분 없이 받습니다. 입력이 이미 지정 요일이어도 같은 날이 아니라 뒤의 해당 요일을 선택합니다.

SELECT
    ADD_MONTHS(DATE '2019-02-28', 1) AS one_month_later,
    LAST_DAY(DATE '2019-03-15') AS end_of_month,
    DATEDIFF(DATE '2019-03-03', DATE '2019-03-01') AS days_between,
    NEXT_DAY(DATE '2019-03-01', 'Mon') AS next_monday

표현식의 자료형과 형식화

함수와 인자결과와 조건
DATE_FORMAT(expr, format)지정한 패턴의 문자열
FROM_UNIXTIME(seconds[, format])epoch 초를 세션 시간대의 문자열로 표현. 기본 yyyy-MM-dd HH:mm:ss
FROM_UTC_TIMESTAMP(timestamp, timezone)입력을 UTC 시각으로 보고 지정 시간대의 시계 값으로 이동한 Timestamp
TO_DATE(expr[, format])Date로 변환
TO_UTC_TIMESTAMP(timestamp, timezone)지정 시간대의 시계 값을 UTC 기준으로 이동한 Timestamp
TRUNC(date, format)지정 단위 아래 날짜 부분 제거
UNIX_TIMESTAMP(text[, format])문자열을 epoch 초로 변환. 기본 yyyy-MM-dd HH:mm:ss와 기본 시간대/locale 사용

epoch 기준은 1970-01-01 00:00:00 UTC이며 밀리초와 초를 혼동하지 않습니다. FROM_UNIXTIME은 Timestamp 객체가 아니라 문자열입니다. FROM_UTC_TIMESTAMP와 TO_UTC_TIMESTAMP는 시간대 이름을 붙이는 문자열 포맷 함수가 아닙니다.

TRUNC의 연도 표기는 year/yyyy/yy, 월 표기는 month/mon/mm을 사용할 수 있습니다. FORMAT 패턴은 실행하는 Spark 버전의 datetime pattern 규칙을 따릅니다. Spark 3 계열에서는 예전 Java SimpleDateFormat의 모든 패턴이 그대로 호환되지 않습니다.

잘못된 날짜 문자열이나 패턴은 항상 같은 방식으로 NULL이 되지 않습니다. ANSI 설정에 따른 파싱 오류와, Spark 3.1 이후 잘못된 패턴 자체의 오류를 구분합니다.

SELECT
    TO_DATE('07302016', 'MMddyyyy') AS parsed_date,
    DATE_FORMAT(TIMESTAMP '2016-07-30 11:29:27', 'yyyy-MM-dd') AS date_text,
    TRUNC(DATE '2016-07-30', 'month') AS month_start,
    FROM_UNIXTIME(0, 'yyyy-MM-dd HH:mm:ss') AS epoch_text

WINDOW로 시간 구간 만들기

WINDOW(timeColumn, windowDuration)
WINDOW(timeColumn, windowDuration, slideDuration)
WINDOW(timeColumn, windowDuration, slideDuration, startTime)
인자의미
timeColumnTimestamp 열
windowDuration구간 폭. 예: 10 minutes, 1 second
slideDuration구간을 시작하는 간격. 생략하면 폭과 같은 tumbling 구간. 폭 이하여야 함
startTimeepoch UTC 기준 시작 offset. 예: 15 minutes

기간은 달력에 따라 늘거나 줄지 않는 고정 길이입니다. 월 단위는 지원하지 않으며 마이크로초 정밀도까지 지원합니다. 시작 경계는 포함하고 끝 경계는 제외합니다. 12:05는 [12:05,12:10)에는 속하고 [12:00,12:05)에는 속하지 않습니다.

SELECT
    WINDOW(event_time, '10 minutes', '5 minutes') AS time_window,
    COUNT(*) AS events
FROM VALUES
    (TIMESTAMP '2025-01-01 12:01:00'),
    (TIMESTAMP '2025-01-01 12:06:00') AS samples(event_time)
GROUP BY WINDOW(event_time, '10 minutes', '5 minutes')

결과 구간에는 start/end Timestamp가 있습니다. 매시 15분에 시작하는 한 시간 구간은 폭과 간격을 1 hour, 시작 offset을 15 minutes로 지정합니다. 이 함수는 분석 window의 LAG/LEAD와 다른 시간 구간 생성 연산입니다.