IT/php

[PHP] Carbon 사용시 주의점

_이준호_ 2023. 2. 2. 01:24

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 로 했으면 좋겠다. 왜냐하면 나뿐만이 아니라 다른 개발자들도 이를 버그로 인식하고 스택오버플로우나 깃헙 이슈에 이와 관련된 많은 글들이 있다. 결론적으로 버그는 아니고 원래 저렇게 동작하는 기능이다.

 

참고