이번에 출석으로 페어프로그래밍하다가 처음 안 사실이있다.
바로 `yyyy-MM-dd`와 `YYYY-MM-dd`가 다르다는 사실!
나는 처음 알았다.
과연 둘은 뭐가 그렇게 다를까?
둘의 가장 큰 차이점은 y와 Y가 각각 다른 개념의 연도를 의미한다는 것이다.

특히 `YYYY`는 ISO-8601의 Week-based year를 따르기 때문에 연초와 연말에 의외의 값이 나올 수 있다.
ISO 8601은 날짜와 시간의 표준 형식을 정의하는 국제 표준입니다. 이 표준에서는 연도를 나타내는 다양한 형식을 다루며, 특히 주 기반 연도(week-based year)에 대한 내용을 포함하고 있습니다.
이게 무슨 말이냐?
1️⃣ yyyy-MM-dd
yyyy는 달력을 기준으로 한 연도를 의미한다. 즉, 우리가 보통 사용하는 그냥 연도를 뜻한다.
예를들어 2024년이면 언제든지 2024로 표시된다.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2023, 12, 31);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(date.format(formatter)); // 2023-12-31
}
}
2️⃣ YYYY-MM-dd (IOS 주차 기준 연도)
YYYY는 ISO-8601의 주차를 기준으로 한 연도를 의미한다.
따라서 한 해의 첫 주가 언제 시작하느냐에 따라 연도가 달라질 수 있다.
1월 1일이 속한 주가 이전 해의 마지막주라면 이전 해의 연도가 출력될 수 있고 12월 31일이 속한 주가 다음 해의 첫 주라면 다음 해의 연도가 출력될 수 있다.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2023, 12, 31);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd");
System.out.println(date.format(formatter)); // 2024-12-31
}
}
2023-12-31이지만 출력 결과는 2024년 12월 31일이다.
왜그럴까?
2023-12-31이지만, ISO 주차 기준으로 보면 2024년의 첫 번째 주에 속하기 때문이다.
즉, 2023-12-31이지만, 주 기준으로 2024년의 첫 주로 간주되어 2024-12-31이 나와버린다.
이런 문제 때문에 대부분의 경우 `YYYY`를 사용하지 않는 것이 좋다.
3️⃣ 언제 YYYY를 써야할까?
1. 주차(week-based year) 기준으로 데이터를 관리할 때
2. ISO-8601 주차 기반으로 연도를 계산할 때
- ex) 회계 연도나 주간 리포트 기준으로 연도를 계산해야 할 때는 `YYYY`를 사용할 수도 있다.
📚 정리
날짜를 포맷팅할 때는 `yyyy-MM-dd`를 쓰는게 좋다.
`YYYY-MM-dd`는 ISO 주차 기준의 연도(Week year)를 사용하기 때문에 연초와 연말에 예상치 못한 버그가 생길 수 있다. !
📌 Referece
https://www.iso.org/iso-8601-date-and-time-format.html?utm_source=chatgpt.com
'JAVA > 개념' 카테고리의 다른 글
Java 방어적 복사(Defensive Copy) 가이드 (feat. ArrayList, unmodifiableList, List.copyOf()) (0) | 2025.02.16 |
---|---|
private 생성자를 왜 만드시나요? (0) | 2025.02.15 |
언제 equals를 재정의 해야할까? (0) | 2024.11.22 |
Collection.forEach vs Stream.forEach (1) | 2024.11.20 |
stream.forEach (feat. 종단 연산) (1) | 2024.11.18 |