콘텐츠로 이동

날짜에서 Day - 1을 하면 월초에 깨지는 로컬 푸시 버그

클라이언트의 잘못된 날짜 계산 때문에 로컬 푸시를 예약하는 시점에 다음 예외가 발생했다.

ArgumentOutOfRangeException: Year, Month, and Day parameters describe an un-representable DateTime.
System.DateTime.DateToTicks (System.Int32 year, System.Int32 month, System.Int32 day) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
System.DateTime..ctor (System.Int32 year, System.Int32 month, System.Int32 day, System.Int32 hour, System.Int32 minute, System.Int32 second) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
DataPool.PurchaseStampInfo.ReserveLocalPush () (at Assets/Scripts/DataPool/PurchaseStampInfo.cs:226)
SessionLobby+<>c__DisplayClass62_0.<JoinLobby>b__0 (System.Exception e, Network.AnswerLobby answer) (at Assets/Scripts/Session/SessionLobby.cs:585)
SessionLobby+<>c__DisplayClass49_0`1[T].<Request>b__1 (System.Exception e, T result) (at Assets/Scripts/Session/SessionLobby.cs:328)
...
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <028e4d71153d4ed5ac6bee0dfc08aa3b>:0)

아래 첫 번째 줄에서 expireTime.Day가 1(1일)이면 Day 인자가 0이 되어 예외가 난다.

12월 20일 오픈 이후의 스탬프 카드는 1월 18일에 마감되지만, 1월 3일에 구매해 카드를 완성한 유저는 마감일이 2월 1일이 되어 이 오류가 발생했다.

두 번째 줄처럼 AddDays를 쓰도록 고쳤다.

DateTime tempTime = new DateTime(expireTime.Year, expireTime.Month, expireTime.Day - 1, expireTime.Hour, expireTime.Minute, expireTime.Second);
DateTime tempTime = expireTime.AddDays(-1);

클라이언트는 수정했지만 메이저 배포까지 시간이 촉박해, 서버 API에서도 PST 기준 1일이면 하루를 더해 저장하도록 함께 수정했다.

날짜 연산은 년·월·일 필드를 직접 빼거나 더하지 말고 AddDays 같은 API를 쓴다. 필드 단위 계산은 월 경계에서 표현할 수 없는 날짜를 만든다.