PHP Carbon 라이브러리로 날짜/시간 처리하기

소스 코드 포맷팅 서비스인 carbon-app 소개는 여기를 참고하세요.



카본PHP 의 DateTime 클래스를 확장하여 날자와 시간을 쉽게 다룰수 있는 라이브러리로 laravel 에는 기본적으로 포함되어 있습니다.

Carbon Instance 생성

Carbon 객체는 아래처럼 여러 방법을 통해 생성할 수 있습니다.

현재 시간 객체 생성

now() static 메서드를 사용하여 현재 시간을 갖는 Carbon 객체를 생성할수 있습니다.

현재 시간 얻기
<?php

// $dt 는 현재 시간이 저장됨
$dt = \Carbon\Carbon::now();


문자열에서 생성

날짜/시간 문자열에서 Carbon 객체를 생성합니다. 첫 번째 파라미터는 PHP의 date time 문자열 format 을, 두 번째는 Carbon 으로 변환할 문자열을 전달합니다.

$val = '2015-10-11 11:22:33';
$dt = \Carbon\Carbon::createFromFormat('Y-m-d h:i:s', $val);


24시간 형식을 사용하려면 포맷에 'h' 대신 'H' 지정합니다.

$val = '2015-10-11 14:22:33';
$dt = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $val);


연월일만 사용할 경우 아래처럼 format 에 'Y-m-d' 를 지정하면 됩니다.

$val = '2015-10-11';
$dt = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $val);

DateTime 에서 생성

PHP의 DateTime 객체로부터 생성하려면 instance() 메소드 사용합니다.

$dt = new DateTime('2011-01-01T15:03:01.012345Z');

$this_update = \Carbon\Carbon::instance($dt );


Unix Time Stamp에서 생성

Unix Time Stamp 로 부터 Carbon 객체를 생성하려면 createFromTimestamp() static 메서드에 time stamp 값(long type)을 넘겨 주면 됩니다.

존재하는 Carbon 객체를 Unix Time Stamp 로 표시하려면 timestamp property 값에 접근하면 됩니다.

$dt = \Carbon\Carbon::createFromTimestamp(1587967874);

// "2020-04-27 06:11:14.000000"
var_dump($dt);

// 1587967874
var_dump($dt->timestamp);


라라벨 엘로퀀트 연동

laravel 은 Model 클래스의 $dates 변수에 날자/시간 컬럼을 명시하면 자동으로 Carbon 객체로 생성됩니다.

class Task extends Model {
	protected $dates = ['deleted_at', 'requested_at'];
}


$dates 에 안 넣고 view 에 전달하면 mutator/accessor 가 안 되므로 다음 에러 발생하니 주의하세요. 


날자 계산

addXXX

시간 및 날자 더하기는 addXXX 메서드 사용하며 XXX 는 Hour 나 Day, Week 같은 시간 단위를 사용합니다.

XXX 는 단수와 복수가 있는데 단수일 경우 파라미터가 없이 자동으로 1을 더하고 복수일 경우 파라미터에 (plus)할 숫자를 전달해 주면 됩니다. ( (minus) 도 가능)

  • 3일을 더할 경우 addDays()
  • 1시간을 더할 경우 addHour()
  • 1시간을 더하는 addHour()addHours(1) 와 동일
use Carbon\Carbon;

// 현재 시간 
$dt = Carbon::now();

// 1분 더하기
$dt->addMinute();


// 현재 시간보다 5시간 37분 이후
$dt->addHours(5)->addMinutes(37);

// 하루 더하기
$dt->addDay();

// 현재 일보다 3주 5일 뒤
$dt->addWeeks(3)->addDays(5);


// 현재 일보다 2달 5일 뒤
$dt->addMonths(2)->addDays(5);

subXXX

뺄 경우 subXXX 를 사용하며 또는 addXXX 에서 파라미터를 - 로 줘도 됩니다.

use Carbon\Carbon;

// 현재 시간 
$dt = Carbon::now();
  
// 3시간 28분전
$dt->subHours(3)->subMinutes(28);

// 아래와 동일
$dt->addHours(-3)->addMinutes(-28);  

// 60 개월 4일 전
$dt->subMonths(60)->subDays(4);

날자 계산 함수를 쓰면 현재 인스턴스를 변경하므로 원하지 않을 경우 $dt->copy()->subDays() 처럼 객체를 복사하는 copy() 메서드를 호출해서 인스턴스를 복제후 사용합니다..

오버플로우 방지

PHP Carbon 달을 더하거나 뺄때 오버플로우(overflow)되지 않게 하기 참고


차이 계산

use \Carbon\Carbon;


$dt = Carbon::now();
 
$dt->diffInDays($dt->copy()->addMonth());     // 1달 후이므로 차이는 30
        
 
echo Carbon::now()->subDays(5)->diffForHumans();              // 5 days ago


출력

기본 출력

toXXXString() 메서드를 사용하면 되며 XXX 는 출력할 데이타 명을 사용

  • 날자와 시간을 출력할 때: toDateTimeString() 
  • 날자 출력: toDateString()
  • 시간 출력: toTimeString()
$dt = Carbon::create(1975, 12, 25, 14, 15, 16);

var_dump($dt->toDateTimeString() == $dt);          // bool(true) => uses __toString()
echo $dt->toDateString();                          // 1975-12-25
echo $dt->toFormattedDateString();                 // Dec 25, 1975
echo $dt->toTimeString();                          // 14:15:16
echo $dt->toDateTimeString();                      // 1975-12-25 14:15:16
echo $dt->toDayDateTimeString();                   // Thu, Dec 25, 1975 2:15 PM
$dt = \Carbon\Carbon::now();
 
echo $dt;  // 2016-04-26 14:28:39
echo $dt->toDateTimeString();  // 상동
 
echo $dt->toDateString();  // 2016-04-26
echo $dt->toTimeString();  // 14:28:39


출력 포맷팅

Carbon 2 부터는 setToStringFormat 가 deprecated 되었습니다. 대신 DateTimeInterface 클래스의 format() 메서드를 사용하세요

연월일 표시
$dt = \Carbon\Carbon::now();
echo $dt->format('Y-m-d');
연월일 시간/분/초 표시
$dt = \Carbon\Carbon::now();
echo $dt->format('Y-m-d H:i:s');
 Carbon 1 일 경우....

setToStringFormat($format) 메소드 사용하며 파라미터로 출력할 포맷을 지정. 기본 포맷팅으로 돌릴 경우 resetToStringFormat() 메서드 사용

$dt = \Carbon\Carbon::now();
 
$dt->setToStringFormat('jS \o\f F, Y g:i:s a');
echo $dt;                                          // 26th of April, 2016 02:28:39 pm
 
$dt->setToStringFormat('Y-m-d H:i:s');
echo $dt;										  //  2016-04-26 14:28:39
$dt->resetToStringFormat();
echo $dt;                                          //  2016-04-26 14:28:39



Modifiers

시간을 변경할 수 있는  startOfXXX(), next() and previous()  등의 메서드

startOfXXX

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfDay();                            // 2012-01-31 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfDay();                              // 2012-01-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfMonth();                          // 2012-01-01 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfMonth();                            // 2012-01-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfYear();                           // 2012-01-01 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfYear();                             // 2012-12-31 23:59:59


next, previous

$dt = Carbon::create(2012, 1, 1, 12, 0, 0);
echo $dt->previous();                              // 2011-12-25 00:00:00


$dt = Carbon::create(2012, 1, 1, 12, 0, 0);
echo $dt->next();                                  // 2012-01-08 00:00:00


average

$start = Carbon::create(2014, 1, 1, 0, 0, 0);
$end = Carbon::create(2014, 1, 30, 0, 0, 0);
echo $start->average($end);                        // 2014-01-15 12:00:00


Constant

dayOfWeek

현재 Carbon 객체의 요일을 확인하려면 dayOfWeek 변수를 아래의 constant 와 비교하면 됨,.

var_dump(Carbon::SUNDAY);                          // int(0)
var_dump(Carbon::MONDAY);                          // int(1)
var_dump(Carbon::TUESDAY);                         // int(2)
var_dump(Carbon::WEDNESDAY);                       // int(3)
var_dump(Carbon::THURSDAY);                        // int(4)
var_dump(Carbon::FRIDAY);                          // int(5)
var_dump(Carbon::SATURDAY);                        // int(6)
$dt = \Carbon\Carbon::create(2017, 12, 25, 0, 0, 0);


echo $dt->dayOfWeek;	// 1 이므로 17년 크리스마스는 월요일


주말인지 확인

위 constant 를 응용해서 토/일요일인지 확인 가능

<?php

$dates = ["2017-08-18" => false, "2017-08-19" => true, "2017-08-20" => true, "2017-08-21" => false, ];

foreach($dates as $d => $v) {
    $dt = \Carbon\Carbon::createFromFormat('Y-m-d', $d);

    if ($dt->dayOfWeek == \Carbon\Carbon::SUNDAY || $dt->dayOfWeek == \Carbon\Carbon::SATURDAY)
	    echo "$d 는 주말입니다.\n";
    else 
	    echo "$d 는 평일이니 열심히 일하세요.!\n";    
}


기타 Constant

var_dump(Carbon::YEARS_PER_CENTURY);               // int(100)
var_dump(Carbon::YEARS_PER_DECADE);                // int(10)
var_dump(Carbon::MONTHS_PER_YEAR);                 // int(12)
var_dump(Carbon::WEEKS_PER_YEAR);                  // int(52)
var_dump(Carbon::DAYS_PER_WEEK);                   // int(7)
var_dump(Carbon::HOURS_PER_DAY);                   // int(24)
var_dump(Carbon::MINUTES_PER_HOUR);                // int(60)
var_dump(Carbon::SECONDS_PER_MINUTE);              // int(60)


CarbonInterval

PHP 의 dateinterval 을 상속한 유틸리티 클래스


make() 메서드로 문자열로부터 Instance 생성 가능

echo CarbonInterval::make('1h 15m')->forHumans();            // 1 hour 15 minutes

같이 보기

Ref