Perl/DateTime 페이지의 소스 보기
마지막으로 [b]
-- Loading page list... --
내용출력
로그인[l]
Diary
[f]
최근변경내역
[r]
페이지목록[i]
횡설수설[2]
게시판[3]
링크
수정할 수 없습니다: Perl/DateTime 는 읽기 전용 페이지입니다.
Cpan:DateTime == # 날짜를 더하거나 빼기 == 애초에 달력이란 게 달마다 날 수가 다르고 윤년에 서머타임에 여러 요소들이 섞여 있어서, 이게 뜻밖의 경우를 당하기 쉽다. 문서에 있는 [https://metacpan.org/pod/DateTime#How-DateTime-Math-Works How DateTime Math Works 절]에서 눈에 들어오는 부분 위주로 옮겨보면: DateTime은 덧셈이나 뺄셈을 할 때 일, 월, 분, 초, 나노초 순서로 연산한다. 오버플로우가 날 경우는 각 단계에서 조정한다. 따라서 2월 28일에 "1개월 1일"를 더하면 3월 29일이 되는 게 아니라 4월 1일이 된다. 반면에 1개월을 먼저 더한 후에 1일을 더하면 3월 29일이 된다. {{{#!vim perl my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); $dt->add( months => 1, days => 1 ); # 2003-04-01 - the result # 반면에, ($dt가 2월 28일인 상태에서) $dt->add( months => 1 )->add( days => 1 ); # 2003-03-29 }}} 서머 타임의 경우도 유사한 문제가 발생한다. {{{#!vim perl my $dt = DateTime->new( year => 2003, month => 4, day => 5, hour => 1, minute => 58, time_zone => "America/Chicago", ); $dt->add( days => 1, minutes => 3 ); # 2003-04-06 02:01:00 $dt->add( minutes => 3 )->add( days => 1 ); # 2003-04-06 03:01:00 }}} 이런 경우는 datetime 객체를 UTC 타임존으로 변환한 후 연산하면 결과를 미리 예상하기 쉽다. Cpan:DateTime::Duration 모듈에는, 개월 단위로 더할 때 "달의 마지막 날"을 계산하는 세 가지 알고리즘을 제공한다. 이 알고리즘은 덧셈의 결과가 그 달의 마지막 날을 넘어갈 때(1월 30일에 1개월을 더하는 경우처럼) 영향을 미친다. {{{#!vim perl # 2010-08-31 + 1 month = 2010-10-01 $dt->add( months => 1, end_of_month => 'wrap' ); # 2010-01-30 + 1 month = 2010-02-28 $dt->add( months => 1, end_of_month => 'limit' ); # 2010-04-30 + 1 month = 2010-05-31 $dt->add( months => 1, end_of_month => 'preserve' ); }}} * 월초, 월말의 여러 날짜에 대해 각각 테스트한 결과 : [https://gist.github.com/gypark/d0c9f5e2b7d908513105 gist] 디폴트 동작은 양의 duration 값에 대해서는 "wrap"을, 음의 duration 값에 대해서는 "preserve"를 적용한다고 한다. 저 gist에 있는 "다음 달 10일"을 찾는 코드는 [[주인장]]이 실제로 업무용 코드를 작성하며 문제가 되었던 코드이다. 1월 31일을 기준으로 다음 달 10일을 찾기 위해 "다음 달(1개월 더하기)"를 먼저 했더니 3월 3일이 되고 그 다음 "10일"로 설정하면 결과적으로 3월 10일이 되어 버린다. 이런 경우는 "10일"로 설정하는 걸 먼저 해주어야 한다. == # Comments ==
---- [[컴퓨터분류]]
Perl/DateTime
페이지로 돌아가기 |
다른 수정본 보기