Date — 달력 날짜
Date — 달력 날짜
프로그램이 달력의 하루를 다뤄야 할 때가 있어요. 그럴 때 쓰는 타입이 Date예요. 그레고리력(양력)의 하루를 식별하는 변경 불가능한(immutable) 객체예요.
본문
class Date { }
Date는 그레고리력에서 하루를 식별하는 변경 불가능한 객체예요.
Date 객체는 정수와의 덧셈·뺄셈을 지원하는데, 이때 정수는 "일(day) 수"로 해석돼요. 또 ==, <, <=, >, >=, != 같은 숫자 비교 연산자로 Date 객체를 비교할 수 있어요. Date가 YYYY-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)의 문자열로, 또는 Instant나 DateTime 객체로도 만들 수 있어요. 선택적으로 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»