Carbon 과 DateTime
PHP 에선 시간 관련 작업시 Carbon 라이브러리를 주로 사용한다. 예전 javascript 의 moment 같은 존재이다 (참고로 현재 moment 는 deprecated 됨.) 그리고 Carbon 은 PHP 에서 제공해주는 시간 라이브러리 DateTime 을 활용하여 구현되어 있다. 이러한 이유로 DateTime 라이브러리 작동 메커니즘을 자연스럽게 따라갈수 밖에 없다. 그래서 이번 글에선 DateTime 작동 메커니즘중 하나를 소개 하려고 하고 이를 잘 알고 있어야 Carbon 사용중 뜻밖의 버그를 방지 할수 있을것이다.
https://carbon.nesbot.com/docs/
echo $dt->addMonths(60); // 2017-01-31 00:00:00
echo $dt->addMonth(); // 2017-03-03 00:00:00 equivalent of $dt->month($dt->month + 1); so it wraps
echo $dt->subMonth(); // 2017-02-03 00:00:00
echo $dt->subMonths(60); // 2012-02-03 00:00:00
달을 이전달, 다음달로 증감 시키고 싶은 경우 위 메소드를 자주 사용했을 것이다. 메소드 명만 보면 간단한 기능인데 한가지 주의해야 할 점이 있다. 코드로 한번 살펴보자.
$lastDayInJan = Carbon::create(2023, 1, 31, 0, 0, 0);
$lastDayInJan->addMonth() // 2023-03-03
2023-01-31 에서 1달을 증감 시켰는데 결과 값이 2023-03-03 으로 나왔다. Carbon 라이브러리에서 오버플로우 되는 일자들을 알아서 절삭 해줄거라고 생각했었는데 결과는 정반대였다. 오버플로우된 일자 만큼 더하여 정정하기 때문에 이것을 명심해야 하고 이건 DateTime 의 작동 메커니즘이다.
위와 같은 상황을 방지하기 위해선 아래와 같이 사용해야 한다.
echo $lastDayInJan->copy()->addMonthNoOverflow(); // 2017-02-28 00:00:00
// plural addMonthsNoOverflow() method is also available
echo $lastDayInJan->copy()->subMonthsNoOverflow(2); // 2016-11-30 00:00:00
// singular subMonthNoOverflow() method is also available
개인적으로 NoOverflow 를 default 로 했으면 좋겠다. 왜냐하면 나뿐만이 아니라 다른 개발자들도 이를 버그로 인식하고 스택오버플로우나 깃헙 이슈에 이와 관련된 많은 글들이 있다. 결론적으로 버그는 아니고 원래 저렇게 동작하는 기능이다.
참고
'IT > php' 카테고리의 다른 글
[PHP] ?: 와 ?? 연산자의 차이점 (0) | 2024.09.12 |
---|---|
[PHP] 자식 클래스에서 상속 받은 const 값 선언 강제 하는법 (0) | 2024.02.07 |