생년월일 경계는 대부분의 입력에서 아무 문제가 되지 않다가 딱 하루 차이에서 갈라집니다. 이 글에서는 윤년과 2월 29일, 생일 당일의 나이 계산, 시간대에 따라 달라지는 오늘, 그리고 달력이 다른 나라의 표기까지 살펴봅니다. 나이 제한이 있는 화면을 시험하는 사람에게 필요한 경계 사례도 함께 정리합니다.
윤년은 어떻게 정해지나요?
널리 쓰이는 규칙은 세 단계로 되어 있습니다. 연도가 사로 나누어떨어지면 윤년이고, 백으로 나누어떨어지면 윤년이 아니며, 사백으로 나누어떨어지면 다시 윤년입니다. 이 규칙에 따르면 1900년은 윤년이 아니고 2000년은 윤년입니다.
사로 나누어떨어지는지만 보고 판단하면 백 년 단위에서 하루씩 어긋납니다. 시험 데이터에 1900년 2월 29일 같은 값이 들어 있으면, 그 값은 존재할 수 없는 날짜입니다. 형식 검사가 월과 일의 범위만 보는 경우에는 이런 값이 그대로 통과합니다.
날짜를 다루는 도구는 대개 이 규칙을 이미 알고 있으므로 직접 계산할 일은 많지 않습니다. 문제는 규칙을 직접 구현했거나, 문자열을 잘라 연월일을 꺼내는 처리가 남아 있을 때 생깁니다. 2000년과 1900년 값을 시험에 함께 넣어 두면 두 경우가 갈리는지 한 번에 확인됩니다.
2월 29일에 태어난 사람은 언제 생일인가요?
법과 관행이 나라마다 다릅니다. 어떤 곳은 2월 28일에 생일이 온 것으로 보고, 어떤 곳은 3월 1일로 봅니다. 어느 쪽을 고르든 서비스 안에서는 한 가지로 정하고 문서에 남기는 편이 좋습니다. 정하지 않으면 화면과 서버가 서로 다른 답을 낼 수 있습니다.
시험 관점에서 중요한 것은 두 날짜를 모두 경계 사례로 남겨 두는 것입니다. 2월 28일과 3월 1일에 그 사람의 나이가 어떻게 계산되는지 확인해 두면, 나중에 규칙을 바꿔도 무엇이 달라지는지 분명해집니다.
이 결정은 나이 제한과 함께 볼 때 더 중요해집니다. 기준에 딱 걸린 사람이 2월 29일생이라면 어느 날을 생일로 잡는지에 따라 통과와 거절이 뒤집힙니다. 규칙을 정했다면 그 날짜를 그대로 시험 데이터에 넣어 두고, 규칙을 바꿀 때 이 값이 어떻게 달라지는지도 함께 확인합니다.
생일 당일에 나이는 어떻게 되나요?
만 나이는 생일이 지났는지를 기준으로 셉니다. 생일 당일에는 이미 한 살이 올라간 것으로 보는 것이 일반적입니다. 그래서 하루 전과 생일 당일의 나이가 다르고, 나이 제한이 있는 화면에서는 이 하루가 통과와 거절을 가릅니다.
이 계산에서 흔히 하는 실수는 두 날짜의 차이를 연 단위로 나누는 것입니다. 그렇게 하면 생일이 지났는지 여부가 반영되지 않아 경계일에서 정확히 한 살만큼 어긋납니다. 월과 일을 따로 비교해 생일이 지났는지 먼저 판단한 뒤 연도 차이를 더하는 편이 안전합니다.
오늘이 언제인지는 어디에 달려 있나요?
나이 계산은 오늘 날짜에 의존하고, 오늘 날짜는 시간대에 따라 달라집니다. 한 지역이 자정을 넘긴 시각에도 다른 지역은 아직 전날일 수 있습니다. 그래서 서버가 어느 시간대를 기준으로 오늘을 정하는지가 경계일의 결과를 바꿉니다.
이 문제는 생일이 임박한 사용자에게만 나타나기 때문에 눈에 잘 띄지 않습니다. 시험에 경계 사례를 넣어 두면 어느 쪽 기준으로 동작하는지 분명해집니다. 화면에서 계산한 값과 서버에서 계산한 값이 다른 경우도 같은 원인에서 생깁니다.
비슷한 문제가 서버를 여러 지역에 두었을 때도 나타납니다. 요청을 처리하는 서버가 바뀌면 기준 날짜가 달라질 수 있으므로, 오늘을 구하는 일은 한 곳에서 하고 그 값을 넘겨받아 쓰는 편이 안전합니다.
달력이 다른 나라는 어떻게 표기하나요?
그레고리력만 쓰는 것이 아닙니다. 에티오피아와 네팔, 이란 같은 나라는 각자의 달력을 함께 사용하고, 같은 날짜라도 달력에 따라 연도와 월일 표기가 달라집니다. 사용자가 자기 달력으로 생년월일을 적으면, 서비스가 그것을 그대로 저장했을 때 나이 계산이 크게 어긋납니다.
국제 서비스를 만든다면 입력 시점에 어느 달력의 값인지 밝히게 하고, 저장은 하나의 기준으로 옮겨서 하는 편이 안전합니다. 날짜와 다른 항목이 서로 맞는지 확인하는 방법은 신원 데이터 일관성에서 이어서 다룹니다.
신원 생성기로 경계 날짜 만들어 보기
신원 생성기에서는 국가와 성별을 고른 뒤 생년월일과 나이가 함께 표시되는 기록을 만들 수 있습니다. 나이 제한을 시험한다면 생일이 임박한 값과 방금 지난 값을 각각 만들어 두고, 화면이 두 경우를 다르게 다루는지 확인해 보세요.
생성되는 값은 알고리즘이 합성한 것이며 실존 인물의 생일이 아닙니다. 시험용으로만 사용하고 실제 인물을 사칭하는 데 쓰지 마세요.
개발자를 위한 메모: 날짜와 시간대를 분리하라
- 생년월일은 시간대가 없는 날짜로 저장합니다. 시각을 함께 저장하면 시간대 변환 과정에서 하루가 밀릴 수 있습니다.
- 나이는 저장하지 말고 필요할 때 계산합니다. 저장해 두면 하루가 지날 때마다 값이 틀어집니다.
- 경계 사례를 표로 고정해 둡니다. 생일 하루 전, 생일 당일, 생일 다음 날, 윤년의 2월 29일, 세기가 바뀌는 해가 좋은 출발점입니다.
- 기준 시간대를 정하고 한 곳에서만 오늘을 구합니다. 화면과 서버가 각자 오늘을 계산하면 경계일의 결과가 갈립니다.
- 달력이 다른 지역의 입력을 받을 계획인지 먼저 정합니다. 계획이 없다면 그 사실을 검증 규칙에도 반영해, 조용히 잘못된 값이 저장되지 않게 합니다.
- 존재하지 않는 날짜를 거르는 검사를 형식 검사와 함께 둡니다. 월과 일의 범위만 보는 검사는 윤년 규칙을 놓칩니다.
- 화면과 서버가 같은 계산 함수를 씁니다. 두 곳에 따로 구현하면 경계일에서 답이 갈립니다.
- 경계 사례 시험에는 기대 결과를 함께 적어 둡니다. 계산이 맞는지 판단할 기준이 없으면 시험이 형식만 확인하게 됩니다.
다음 단계
나이 제한 화면을 시험하고 있다면 연령 확인 테스트를 이어서 읽어 보세요. 시험에 쓸 생년월일 값이 필요하다면 신원 생성기에서 국가를 고르고 몇 번 생성해, 나온 생일과 나이가 서로 맞는지 확인하는 것이 가장 빠릅니다.