Date — 달력 날짜

Date — 달력 날짜

프로그램이 달력의 하루를 다뤄야 할 때가 있어요. 그럴 때 쓰는 타입이 Date예요. 그레고리력(양력)의 하루를 식별하는 변경 불가능한(immutable) 객체예요.

출처: Raku Documentation — Date

본문

class Date { }

Date는 그레고리력에서 하루를 식별하는 변경 불가능한 객체예요.

Date 객체는 정수와의 덧셈·뺄셈을 지원하는데, 이때 정수는 "일(day) 수"로 해석돼요. 또 ==, <, <=, >, >=, != 같은 숫자 비교 연산자로 Date 객체를 비교할 수 있어요. DateYYYY-MM-DD 형식으로 문자열화되기 때문에, eq, lt, le 같은 문자열 연산자로 비교해도 올바른 결과가 나와요.

Date.today는 시스템 시계 기준 오늘 날짜의 객체를 만들어요.

my $d = Date.new(2015, 12, 24); # Christmas Eve!
say $d;                         # OUTPUT: «2015-12-24␤»
say $d.year;                    # OUTPUT: «2015␤»
say $d.month;                   # OUTPUT: «12␤»
say $d.day;                     # OUTPUT: «24␤»
say $d.day-of-week;             # OUTPUT: «4␤» (Thursday)
say $d.later(days => 20);       # OUTPUT: «2016-01-13␤»
my $n = Date.new('2015-12-31'); # New Year's Eve
say $n - $d;                    # OUTPUT: «7␤», 7 days between New Years/Christmas Eve
say $n + 1;                     # OUTPUT: «2016-01-01␤»

버전 6.d부터는 Date.raku를 호출할 수 있어요.

method new

multi method new($year, $month, $day, :&formatter --> Date:D)
multi method new(:$year!, :$month = 1, :$day = 1  --> Date:D)
multi method new(Str $date                        --> Date:D)
multi method new(Instant:D $dt                    --> Date:D)
multi method new(DateTime:D $dt                   --> Date:D)

Date 객체를 만들어요. 만들 수 있는 방법이 여러 가지예요. 정수로 강제 변환 가능한 (year, month, day) 셋으로 만들 수도 있고, YYYY-MM-DD 형식(ISO 8601)의 문자열로, 또는 InstantDateTime 객체로도 만들 수 있어요. 선택적으로 formatter를 이름 있는 인자로 받을 수 있어요.

my $date = Date.new(2042, 1, 1);
$date = Date.new(year => 2042, month => 1, day => 1);
$date = Date.new("2042-01-01");
$date = Date.new(Instant.from-posix: 1482155532);
$date = Date.new(DateTime.now);

Rakudo 2022.03부터는 "day" 인자로 호출 가능한(callable) 것을 줄 수도 있어요. *는 그 달의 마지막 날을 뜻하고, 마지막 날부터 거꾸로 세는 방식(e.g. *-1)도 가능해요.

say Date.new(2042, 2, *); # OUTPUT: «2042-02-28␤»
say Date.new(2044, 2, *); # OUTPUT: «2044-02-29␤»

method new-from-daycount

method new-from-daycount($daycount,:&formatter --> Date:D)

$daycount로 새 Date 객체를 만들어요. $daycount는 수정 줄리안 일(Modified Julian Day), 즉 epoch 1858년 11월 17일로부터의 일 수예요. 선택적으로 formatter를 이름 있는 인자로 받아요.

say Date.new-from-daycount(49987);          # OUTPUT: «1995-09-27␤»

method daycount

method daycount(Date:D: --> Int:D)

수정 줄리안 일, 즉 epoch 1858년 11월 17일로부터의 일 수를 반환해요.

method last-date-in-month

method last-date-in-month(Date:D: --> Date:D)

해당 Date 객체가 속한 달의 마지막 날짜를 반환해요. 이미 그 달의 마지막 날이라면 invocant 자신을 반환해요.

say Date.new('2015-11-24').last-date-in-month; # OUTPUT: «2015-11-30␤»

이렇게 하면 그 달의 남은 모든 날짜를 범위로 훨씬 쉽게 표현할 수 있어요.

$date .. $date.last-date-in-month

method first-date-in-month

method first-date-in-month(Date:D: --> Date:D)

해당 Date 객체가 속한 달의 첫 날짜를 반환해요. 이미 그 달의 첫 날이라면 invocant 자신을 반환해요.

say Date.new('2015-11-24').first-date-in-month; # OUTPUT: «2015-11-01␤»

method clone

method clone(Date:D: :$year, :$month, :$day, :&formatter)

invocant를 바탕으로 새 Date 객체를 만들되, 주어진 인자가 invocant의 값을 덮어써요.

say Date.new('2015-11-24').clone(month => 12);    # OUTPUT: «2015-12-24␤»

method today

method today(:&formatter --> Date:D)

오늘 날짜의 Date 객체를 반환해요. 선택적으로 formatter 이름 있는 인자를 받아요.

say Date.today;

method truncated-to

method truncated-to(Date:D: Cool $unit)

Date를 그 해/달/주의 첫 날로 잘라낸 값을 반환해요. 예를 들어

my $c = Date.new('2012-12-24');
say $c.truncated-to('year');     # OUTPUT: «2012-01-01␤»
say $c.truncated-to('month');    # OUTPUT: «2012-12-01␤»
say $c.truncated-to('week');     # OUTPUT: «2012-12-24␤», because it's Monday already

method succ

method succ(Date:D: --> Date:D)

다음 날의 Date를 반환해요. "succ"는 "successor(후계자)"의 줄임말이에요.

say Date.new("2016-02-28").succ;   # OUTPUT: «2016-02-29␤»

method pred

method pred(Date:D: --> Date:D)

이전 날의 Date를 반환해요. "pred"는 "predecessor(선임자)"의 줄임말이에요.

say Date.new("2016-01-01").pred;   # OUTPUT: «2015-12-31␤»

method Str

multi method Str(Date:D: --> Str:D)

invocant를 formatter가 지정한 대로 문자열로 표현해 반환해요. formatter를 지정하지 않았다면 ISO 8601 형식의 날짜가 반환돼요.

say Date.new('2015-12-24').Str;                     # OUTPUT: «2015-12-24␤»

my $fmt = { sprintf "%02d/%02d/%04d", .month, .day, .year };
say Date.new('2015-12-24', formatter => $fmt).Str;  # OUTPUT: «12/24/2015␤»

method gist

multi method gist(Date:D: --> Str:D)

날짜를 YYYY-MM-DD 형식(ISO 8601)으로 반환해요.

say Date.new('2015-12-24').gist;                    # OUTPUT: «2015-12-24␤»

method Date

method Date(--> Date)

invocant 자신을 반환해요.

say Date.new('2015-12-24').Date;  # OUTPUT: «2015-12-24␤»
say Date.Date;                    # OUTPUT: «(Date)␤»

method DateTime

multi method DateTime(Date:U: --> DateTime:U)
multi method DateTime(Date:D: --> DateTime:D)

invocant를 DateTime으로 변환해요.

say Date.new('2015-12-24').DateTime; # OUTPUT: «2015-12-24T00:00:00Z␤»
say Date.DateTime;                   # OUTPUT: «(DateTime)␤»

method Int

multi method Int(Date:D: --> Int:D)

invocant를 Int로 변환해요. daycount 메서드로도 같은 값을 얻을 수 있어요.

Rakudo 컴파일러 2023.02 릴리스부터 사용할 수 있어요.

method Real

multi method Real(Date:D: --> Int:D)

invocant를 Int로 변환해요. daycount 메서드로도 같은 값을 얻을 수 있어요.

Rakudo 컴파일러 2023.02 릴리스부터 사용할 수 있어요.

method Numeric

multi method Numeric(Date:D: --> Int:D)

invocant를 Int로 변환해요. daycount 메서드로도 같은 값을 얻을 수 있어요. 이 덕분에 Date 객체를 산술 연산에 바로 쓸 수 있어요.

Rakudo 컴파일러 2023.02 릴리스부터 사용할 수 있어요.

sub infix:<->

multi infix:<-> (Date:D, Int:D --> Date:D)
multi infix:<-> (Date:D, Date:D --> Int:D)

뺄 대상 날짜와, 뺄 일 수를 나타내는 Int 또는 다른 Date 객체를 받아요. 각각 새 Date 객체 또는 두 날짜 사이의 일 수를 반환해요.

say Date.new('2016-12-25') - Date.new('2016-12-24'); # OUTPUT: «1␤»
say Date.new('2015-12-25') - Date.new('2016-11-21'); # OUTPUT: «-332␤»
say Date.new('2016-11-21') - 332;                    # OUTPUT: «2015-12-25␤»

sub infix:<+>

multi infix:<+> (Date:D, Int:D --> Date:D)
multi infix:<+> (Int:D, Date:D --> Date:D)

Int를 받아 그 Date 객체에 그만큼의 일 수를 더해요.

say Date.new('2015-12-25') + 332; # OUTPUT: «2016-11-21␤»
say 1 + Date.new('2015-12-25');   # OUTPUT: «2015-12-26␤»

출처: Raku Documentation — Date