class Date { }

Date 是一个不可变对象,用于标识公历中的某一天。

Date 对象支持整数的加减运算,其中整数被解释为天数。您可以使用数值比较运算符 ==, <, <=, >, >=, != 来比较 Date 对象。它们在 YYYY-MM-DD 格式中的字符串化意味着使用字符串运算符 eq, lt, le 等进行比较也会得到正确的结果。

Date.today 根据系统时钟创建一个表示当前日期的对象。

my $d = Date.new(20151224); # 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。它也会拒绝合成数字,例如 7̈ 。

方法§

方法 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 对象,可以从一个 (年,月,日) 三元组(可以强制转换为整数)创建,也可以从 YYYY-MM-DD 格式的字符串 (ISO 8601) 创建,或者从 Instant 或 DateTime 对象创建。可以选择接受格式器作为命名参数。

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

从 Rakudo 2022.03 开始,"日" 参数也可以是一个可调用对象,其中 * 代表一个月的最后一天,并且可以从最后一天开始计算日期。

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

方法 new-from-daycount§

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

创建一个新的 Date 对象,给定 $daycount,它是从纪元 1858 年 11 月 17 日开始的天数,即 修正儒略日。可以选择接受格式器作为命名参数。

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

方法 daycount§

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

返回从纪元 1858 年 11 月 17 日开始的天数,即 修正儒略日

方法 last-date-in-month§

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

返回 Date 对象所在月份的最后一天。否则,如果日期值已经是该月的最后一天,则返回调用者。

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

这应该允许更简单的范围,例如

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

对于该月剩下的所有日期。

方法 first-date-in-month§

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

返回 Date 对象所在月份的第一天。否则,如果日期值已经是该月的第一天,则返回调用者。

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

方法 clone§

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

基于调用者创建一个新的 Date 对象,但使用给定的参数覆盖调用者的值。

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

方法 today§

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

返回表示当前日期的 Date 对象。可以选择接受格式器作为命名参数。

say Date.today;

方法 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

方法 succ§

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

返回下一天的 Date。"succ" 是 "successor"(后继者)的缩写。

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

方法 pred§

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

返回前一天的 Date。"pred" 是 "predecessor"(前驱者)的缩写。

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

方法 Str§

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

返回调用者的字符串表示形式,如 格式器 所指定。如果没有指定格式器,则将返回一个 (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␤»

方法 gist§

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

YYYY-MM-DD 格式 (ISO 8601) 返回日期。

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

方法 Date§

method Date(--> Date)

返回调用者。

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

方法 DateTime§

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

将调用者转换为 DateTime

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

方法 Int§

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

将调用者转换为 Int。可以使用 daycount 方法获得相同的值。

从 Rakudo 编译器 2023.02 版本开始可用。

方法 Real§

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

将调用者转换为 Int。可以使用 daycount 方法获得相同的值。

从 Rakudo 编译器 2023.02 版本开始可用。

方法 Numeric§

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

将调用者转换为 Int。可以使用 daycount 方法获得相同的值。这允许 Date 对象直接用于算术运算。

从 Rakudo 编译器 2023.02 版本开始可用。

函数§

sub sleep§

sub sleep($seconds = Inf --> Nil)

尝试休眠给定的$seconds秒。完成后返回Nil。接受IntNumRatDuration类型作为参数,因为它们都属于Real类型。

sleep 5;                # Int 
sleep 5.2;              # Num 
sleep (5/2);            # Rat 
sleep (now - now + 5);  # Duration 

因此,可以休眠非整数秒数。例如,以下代码显示sleep (5/2)休眠2.5秒,而sleep 5.2休眠5.2秒。

my $before = now;
sleep (5/2);
my $after = now;
say $after-$before;  # OUTPUT: «2.502411561␤» 
 
$before = now;
sleep 5.2;
$after = now;
say $after-$before;  # OUTPUT: «5.20156987␤»

sub sleep-timer§

sub sleep-timer(Real() $seconds = Inf --> Duration:D)

此函数的实现类似于sleep,但与前者不同的是,它返回一个Duration实例,其中包含系统未休眠的秒数。

特别是,返回的Duration将处理进程被某些外部事件(例如,虚拟机或操作系统事件)唤醒时剩余的秒数。在正常情况下,当休眠未被中断时,返回的Duration的值为0,表示没有剩余的秒数需要休眠。因此,在正常情况下

say sleep-timer 3.14;  # OUTPUT: «0␤»

相同的结果适用于边缘情况,当传递负数或零休眠时间作为参数时。

say sleep-timer -2# OUTPUT: 0 
say sleep-timer 0;  # OUTPUT: 0 

另请参阅sleep-until

sub sleep-until§

sub sleep-until(Instant $until --> Bool)

工作方式类似于sleep,但会检查当前时间,并持续休眠,直到达到未来所需的时刻。它在内部使用sleep-timer方法循环,以确保如果意外过早唤醒,它将再次等待指定的时间,直到达到指定的时刻。返回休眠状态。

如果已达到未来的Instant(通过休眠或当前时间),则返回True;如果指定了过去的Instant,则返回False

要休眠到未来10秒,可以编写类似以下代码:

say sleep-until now+10;   # OUTPUT: «True␤»

尝试休眠到过去的时间不起作用。

my $instant = now - 5;
say sleep-until $instant# OUTPUT: «False␤»

但是,如果将时刻设置得足够远,休眠应该会运行。

my $instant = now + 30;
# assuming the two commands are run within 30 seconds of one another... 
say sleep-until $instant# OUTPUT: «True␤» 

要指定未来的确切时刻,首先创建一个在适当时间点的DateTime,然后将其转换为Instant

my $instant = DateTime.new(
    year => 2023,
    month => 9,
    day => 1,
    hour => 22,
    minute => 5);
say sleep-until $instant.Instant# OUTPUT: «True␤» (eventually...) 

这可以用作一种原始的闹钟。例如,假设您需要在2015年9月4日早上7点起床,但由于某种原因,您常用的闹钟坏了,您只有笔记本电脑。您可以将起床时间(注意时区,因为DateTime.new默认使用UTC)指定为Instant,并将其传递给sleep-until,然后您可以播放MP3文件来唤醒您,而不是使用您常用的闹钟。这个场景大致如下所示:

# DateTime.new uses UTC by default, so get time zone from current time 
my $timezone = DateTime.now.timezone;
my $instant = DateTime.new(
    year => 2015,
    month => 9,
    day => 4,
    hour => 7,
    minute => 0,
    timezone => $timezone
).Instant;
sleep-until $instant;
qqx{mplayer wake-me-up.mp3};

sub infix:<->§

multi infix:<-> (Date:DInt:D --> Date:D)
multi infix:<-> (Date:DDate: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:DInt:D --> Date:D)
multi infix:<+> (Int:DDate: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␤»

类型图§

Date的类型关系
raku-type-graph Date Date Any Any Date->Any Dateish Dateish Date->Dateish Mu Mu Any->Mu

展开上面的图表