사전 그레고리력
표준

그레고리력

gabury1고친 사람 github-actions[bot]

그레고리력은 날짜를 계절에 맞춰 셉니다. 오늘 세계 대부분이 이 달력으로 날짜를 적습니다. 한 해를 365일로 둡니다. 몇 해에 한 번은 2월에 하루를 더합니다. 한국에서 양력이라고 부르는 달력이 이것입니다.

쉽고 빠른 이해

그레고리력은 날짜에 번호를 매기는 규칙입니다. 내년 2월에 29일이 있는지 없는지도 이 규칙이 정합니다.

지구가 해를 한 바퀴 도는 데는 365일하고 6시간 가까이 더 걸립니다. 해마다 365일로만 세면 달력 날짜와 계절이 조금씩 벌어집니다. 그래서 남는 시간을 모아 몇 해에 한 번 하루를 끼웁니다.

  1. 4로 나눠떨어지는 해에는 2월에 하루를 더합니다
  2. 100으로 나눠떨어지는 해는 더하지 않습니다
  3. 400으로 나눠떨어지는 해는 다시 더합니다

대가는 계산이 고르지 않다는 것입니다. 해마다 날수가 다르고 2월 29일은 몇 해에 한 번만 옵니다. 날짜를 더하고 빼는 코드는 이 예외를 전부 따라가야 합니다.

상세

그레고리력은 한 해를 열두 달로 나눕니다. 달마다 날수도 정합니다. 그리고 몇 해에 한 번 하루를 더합니다. 2026-09-24 라는 문자열이 어느 날을 가리키는지도 이 규칙으로 정해집니다.

한국에서는 음력과 맞세워 양력이라고 부릅니다. 음력은 달이 차고 기우는 주기로 날짜를 셉니다. 그레고리력은 달이 아니라 해를 따릅니다.

해에 맞춘 한 해의 길이

달력이 맞추려는 대상은 계절입니다. 봄이 해마다 같은 날짜 언저리에 와야 농사와 행사 날짜를 미리 잡을 수 있습니다.

계절은 지구가 해를 한 바퀴 도는 주기를 따릅니다. 이 주기가 태양년입니다. 회귀년이라고도 합니다.

태양년은 낮과 밤의 길이가 같아지는 봄날인 춘분에서 다음 춘분까지를 잰 길이입니다. 365일하고 6시간이 조금 안 됩니다. 소수로 적으면 약 365.2422일입니다.

날짜는 하루 단위로만 셉니다. 0.2422일 같은 조각을 날짜에 붙일 수는 없습니다. 그래서 평소에는 한 해를 365일로 둡니다. 모인 조각은 몇 해에 한 번 하루로 바꿔 끼웁니다.

하루를 끼운 해를 윤년이라고 합니다. 끼우지 않은 해는 평년입니다. 끼우는 날은 2월 29일입니다. 이 날이 윤일입니다.

윤년을 가르는 세 규칙

이 소절은 어느 해가 윤년인지 가르는 규칙을 봅니다. 규칙은 셋입니다. 아래 규칙이 위 규칙을 뒤집는 예외입니다.

  • 4로 나눠떨어지는 해는 윤년입니다
  • 그중 100으로 나눠떨어지는 해는 평년입니다
  • 그중 400으로 나눠떨어지는 해는 다시 윤년입니다

그래서 2024년은 윤년이고 1900년은 평년입니다. 2000년은 100으로 나눠떨어집니다. 400으로도 나눠떨어집니다. 그래서 윤년이었습니다.

flowchart TD
    Y["연도 · 400년에 400해"] --> A{"4로 나눠떨어지나"}
    A -->|아니다| N1["평년 · 365일 · 300해"]
    A -->|그렇다| B{"100으로 나눠떨어지나"}
    B -->|아니다| L1["윤년 · 366일 · 96해"]
    B -->|그렇다| C{"400으로 나눠떨어지나"}
    C -->|아니다| N2["평년 · 365일 · 3해"]
    C -->|그렇다| L2["윤년 · 366일 · 1해"]

그림의 해 수는 400년 동안의 연도를 이 물음에 차례로 넣어 센 것입니다. 네 해 중 세 해는 첫 물음에서 평년으로 끝납니다. 둘째와 셋째 물음은 100년에 한 번 오는 해에만 결과를 바꿉니다.

코드로 옮기면 한 줄입니다. 아래는 파이썬으로 적은 판정 함수와 그 결과입니다.

Python
def is_leap(y):
    return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)

is_leap(2024)  # True
is_leap(1900)  # False
is_leap(2000)  # True

400년 동안 4로 나눠떨어지는 해는 100번 옵니다. 그중 100으로 나눠떨어지는 해가 넷입니다. 이 넷 중 400으로는 안 나눠떨어지는 셋이 평년으로 빠집니다. 그래서 윤년은 100번에서 셋을 뺀 97번입니다.

그러면 한 해의 평균 길이는 365.2425일이 됩니다. 태양년보다 한 해에 30초가 안 되게 깁니다.

율리우스력과 다른 한 가지

그레고리력 바로 앞에 유럽이 쓰던 달력은 율리우스력입니다. 달 이름과 달마다의 날수는 두 달력이 같습니다. 다른 것은 윤년 규칙 하나입니다.

율리우스력은 4로 나눠떨어지는 해를 모두 윤년으로 둡니다. 100과 400의 예외가 없습니다. 그래서 평균 한 해가 365.25일입니다. 태양년보다 해마다 11분쯤 깁니다.

율리우스력 그레고리력
윤년 규칙 4로 나눠떨어지면 윤년 4로 나눠떨어지면 윤년, 100이면 평년, 400이면 다시 윤년
400년 동안 윤년 100번 97번
평균 한 해 365.25일 365.2425일
태양년과 하루 어긋나기까지 걸리는 햇수 128년쯤 3천 년 넘게

두 열은 400년에 윤년 세 번을 빼느냐 마느냐로 갈립니다. 그 셋을 빼는 것만으로 계절과 벌어지는 속도가 스무 배 넘게 느려집니다.

율리우스력의 11분은 작아 보여도 쌓입니다. 천 년 넘게 쌓이자 달력이 계절보다 열흘 가까이 늦어졌습니다. 춘분은 제때 오는데 달력은 아직 열흘 앞의 날짜에 머물러 있는 셈입니다. 그래서 3월 21일 언저리에 찍히던 춘분이 3월 11일 언저리에 찍혔습니다.

1582년에 건너뛴 열흘

이 소절은 율리우스력에서 그레고리력으로 넘어간 방법을 봅니다. 윤년 규칙을 바꾸면 앞으로 벌어질 어긋남은 훨씬 느려집니다. 그동안 쌓인 열흘은 그래도 남습니다.

그래서 달력을 바꾼 해에 날짜 열흘을 한 번에 건너뛰었습니다. 1582년 교황 그레고리우스 13세가 새 규칙을 공포했습니다. 달력 이름도 이 교황에게서 왔습니다. 처음 따른 나라들에서는 날짜가 이렇게 이어졌습니다.

1582-10-04  // 율리우스력 마지막 날 · 목요일
1582-10-15  // 그레고리력 첫날 · 금요일

10월 5일부터 14일까지는 그 나라들의 달력에 없습니다. 요일은 끊기지 않고 목요일 다음 금요일로 이어졌습니다. 건너뛴 것은 날짜 번호이지 날 자체가 아닙니다.

모든 나라가 한꺼번에 바꾸지는 않았습니다. 가톨릭 나라들이 먼저 바꿨습니다. 영국은 170년쯤 뒤에 따랐습니다. 그래서 같은 날짜 번호가 나라마다 다른 날을 가리키던 시기가 있었습니다.

한국은 사정이 다릅니다. 율리우스력이 아니라 음력에서 넘어왔습니다. 양력으로 바꾼 것은 19세기 말입니다.

컴퓨터가 쓰는 역산 그레고리력

이 소절은 컴퓨터가 날짜를 적을 때 그레고리력을 어떻게 쓰는지 봅니다. 날짜 문자열 대부분이 그레고리력 날짜입니다.

날짜와 시각을 글자로 적는 법을 정한 국제 표준이 ISO 8601입니다. ISO(International Organization for Standardization, 국제표준화기구)가 낸 이 표준은 날짜를 그레고리력으로 적습니다.

RFC(Request for Comments)는 인터넷 기술 표준을 싣는 문서 묶음입니다. 인터넷 프로토콜이 주고받는 시각 문자열 형식인 RFC 3339는 ISO 8601 을 좁혀 쓴 것입니다. RFC 3339 도 그레고리력을 따릅니다.

그런데 컴퓨터가 다루는 날짜는 1582년 이전에도 있습니다. 그 날짜에도 지금의 윤년 규칙을 거꾸로 늘려 적용하는 방식을 역산 그레고리력(proleptic Gregorian calendar)이라고 부릅니다.

역산 그레고리력은 날짜를 건너뛰지 않습니다. 1582년 10월 5일부터 14일까지도 날짜로 있습니다. 규칙이 하나뿐입니다. 어느 해든 같은 식으로 날짜를 셉니다.

이 방식은 역사 기록과 어긋납니다. 1582년 이전 유럽의 기록은 율리우스력 날짜입니다. 그 날짜 숫자를 그대로 두고 역산 그레고리력으로 읽으면 다른 날을 가리킵니다.

두 달력이 벌어진 폭은 시대마다 다릅니다. 1500년처럼 100으로 나눠떨어지고 400으로는 안 나눠떨어지는 해는 율리우스력에서만 윤년입니다. 그런 해를 지날 때마다 차이가 하루씩 벌어집니다. 그래서 옛 날짜일수록 차이가 작습니다. 1582년 무렵에는 열흘입니다.

날짜 라이브러리도 한 가지로 통일돼 있지 않습니다. 자바 java.time.LocalDate 와 파이썬 datetime.date 는 모든 날짜를 역산 그레고리력으로 셉니다. 자바 java.util.GregorianCalendar 는 기본값으로 1582년 10월 15일 앞을 율리우스력으로 셉니다. 두 쪽이 같은 옛 날짜 문자열을 받으면 서로 다른 날을 가리킵니다.

백엔드 코드가 걸리는 윤년

이 소절은 그레고리력의 고르지 않은 계산이 백엔드 코드에서 드러나는 곳을 봅니다. 탈은 대개 한 해의 날수가 늘 같다고 믿는 데서 납니다.

평년은 365일입니다. 윤년은 366일입니다. 그래서 「1년」을 365일이나 31,536,000초로 고정해 더하면 윤년을 지날 때 하루가 어긋납니다. 1년 뒤 날짜는 날수를 더하지 말고 연도를 하나 올려 구해야 합니다.

2월 29일은 따로 탈이 납니다. 2024-02-29 에 1년을 더하면 2025-02-29 가 됩니다. 그런 날짜는 없습니다. 구독 갱신일이나 해마다 돌아오는 기념일을 계산하는 코드가 이 날짜에서 걸립니다.

라이브러리마다 이 날짜를 다르게 다룹니다. 자바 LocalDate 의 plusYears(1) 은 그달의 마지막 날인 2월 28일로 당깁니다. 파이썬 date 의 replace(year=2025) 는 ValueError 를 냅니다. 3월 1일로 넘기는 라이브러리도 있습니다.

날짜를 검증할 때도 이 규칙이 필요합니다. 1900-02-29 는 형식이 맞아 보여도 없는 날짜입니다. 1900년은 100으로 나눠떨어지는 평년이기 때문입니다.

윤년과 윤초

윤년과 이름이 닮은 것으로 윤초가 있습니다. 둘 다 무언가를 끼워 넣습니다. 맞추는 대상은 다릅니다.

UTC(Coordinated Universal Time, 협정 세계시)는 세계가 시각을 맞추는 기준 시각입니다. 나라마다 다른 시간대의 시각도 이 시각에 몇 시간을 더하거나 빼서 정합니다.

윤초는 이 UTC 에 1초를 더해 시계를 지구 자전에 맞춥니다. 윤년은 달력에 하루를 더해 날짜를 계절에 맞춥니다. 윤년은 규칙으로 미리 정해져 있습니다. 윤초는 그때그때 발표됩니다.

관련 항목

그레고리력이 계절에 맞추는 해의 길이와 윤일

태양년 · 회귀년 · 춘분 · 윤년 · 평년 · 윤일

그레고리력과 맞세워지는 다른 달력

율리우스력 · 음력 · 태음태양력 · 이슬람력 · 히브리력 · ISO 주 날짜

그레고리력으로 날짜를 적는 표준과 형식

ISO 8601 · RFC 3339 · 역산 그레고리력 · 천문학적 연도 표기 · 날짜 형식

그레고리력 날짜와 맞바꾸는 시각 값

유닉스 시간 · 에포크 · 타임스탬프 · time_t · 율리우스일

그레고리력 날짜에 시각을 붙이는 기준

UTC · 윤초 · 시간대 · UTC 오프셋 · 서머타임 · 시간과 시계

다른 이름: Gregorian calendar · 그레고리오력 · 그레고리우스력