class DateTime does Dateish {}

为了处理民用时间中的点,DateTime 对象存储年、月、日、时、分(全部为 Int)、秒(可能是分数)和时区。

它提供用于计算日期(针对公历)和时间的方法。

DateTime 方法是不可变的;如果您想修改一个方法,请创建一个修改后的副本。

时区以 Int 形式处理,单位为相对于 UTC 的偏移量,而不是时区名称。

my $dt = DateTime.new(
    year    => 2015,
    month   => 11,
    day     => 21,
    hour    => 16,
    minute  => 1,
);
 
say $dt;                            # OUTPUT: «2015-11-21T16:01:00Z␤» 
say $dt.later(days => 20);          # OUTPUT: «2015-12-11T16:01:00Z␤» 
say $dt.truncated-to('hour');       # OUTPUT: «2015-11-21T16:00:00Z␤» 
say $dt.in-timezone(-8 * 3600);     # OUTPUT: «2015-11-21T08:01:00-0800␤» 
 
my $now = DateTime.now(formatter => { sprintf "%02d:%02d".hour.minute });
say $now;                           # 12:45 (or something like that) 

自 6.d 版本起,使用合成码点(例如 7̈)将导致错误。

方法§

方法 new§

multi method new(Int :$year!Int :$month = 1Int :$day = 1,
                 Int :$hour = 0Int :$minute = 0:$second = 0,
                 Int :$timezone = 0:&formatter)
multi method new(Date :$date!,
                 Int :$hour = 0Int :$minute = 0:$second = 0,
                 Int :$timezone = 0:&formatter)
multi method new(Int() $yearInt() $monthInt() $day,
                 Int() $hourInt $minute$second,
                 Int() :$timezone = 0:&formatter)
multi method new(Instant:D $i,  :$timezone=0:&formatter)
multi method new(Numeric:D $posix,  :$timezone=0:&formatter)
multi method new(Str:D $format:$timezone=0:&formatter)

创建一个新的 DateTime 对象。创建新 DateTime 对象的一种选择是分别使用组件(年、月、日、时等)。另一种方法是传递 Date 对象作为日期组件,并逐个指定时间组件。再另一种方法是从 Instant 获取时间,只提供时区和格式化程序。或者,您可以使用 Numeric 作为 UNIX 时间戳,而不是 Instant。

您还可以提供一个 Str,其格式为 ISO 8601 时间戳记号或完整的 RFC 3339 日期和时间。字符串应格式化为 yyyy-mm-ddThh:mm:ssZyyyy-mm-ddThh:mm:ss+0100。我们比 ISO 8601 标准的限制要少一些,因为我们允许 Unicode 数字并混合使用简化和扩展时间格式。

无效的输入字符串会引发 X::Temporal::InvalidFormat 类型的异常。如果您提供一个包含时区并提供 timezone 命名参数的字符串,则会引发 X::DateTime::TimezoneClash 类型的异常。

my $datetime = DateTime.new(year => 2015,
                            month => 1,
                            day => 1,
                            hour => 1,
                            minute => 1,
                            second => 1,
                            timezone => 1);
$datetime = DateTime.new(date => Date.new('2015-12-24'),
                         hour => 1,
                         minute => 1,
                         second => 1,
                         timezone => 1);
$datetime = DateTime.new(201511# First January of 2015 
                         111);   # Hour, minute, second with default time zone 
$datetime = DateTime.new(now);                       # Instant. 
# from a Unix timestamp 
say $datetime = DateTime.new(1470853583.3);          # OUTPUT: «2016-08-10T18:26:23.300000Z␤» 
$datetime = DateTime.new("2015-01-01T03:17:30+0500"# Formatted string

自 Rakudo 2022.03 版本起,day 参数可以是 Callable,其中 * 返回该月中的最后一天,而 *-n 返回最后一天减去 n

自 Rakudo 2022.07 版本起,还可以指定一个“YYYY-MM-DD”字符串来表示给定日期的午夜。

say DateTime.new("2023-03-04");  # OUTPUT: «2023-03-04T00:00:00Z␤»

now 方法§

method now(:$timezone = $*TZ:&formatter --> DateTime:D)

根据当前系统时间创建一个新的 DateTime 对象。可以提供自定义 格式化程序时区:$timezone格林威治标准时间 的偏移量(以秒为单位),默认为 $*TZ 变量 的值。

say DateTime.now# OUTPUT: «2018-01-08T13:05:32.703292-06:00␤»

请注意,可以将下面显示的方法链接到 .now,以便轻松表示当前值,例如:

say DateTime.now.year# OUTPUT: «2018␤»

clone 方法§

method clone(DateTime:D: :$year:$month:$day:$hour:$minute:$second:$timezone:&formatter)

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

say DateTime.new('2015-12-24T12:23:00Z').clone(hour => 0);
# OUTPUT: «2015-12-24T00:23:00Z␤»

请注意,在某些情况下,这可能导致无效的日期

say DateTime.new("2012-02-29T12:34:56Z").clone(year => 2015);
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::OutOfRange: Day out of range. Is: 29, should be in 1..28␤»

hh-mm-ss 方法§

method hh-mm-ss(DateTime:D: --> Str:D)

以 24 小时制 HH:MM:SS 格式将对象表示的时间作为字符串返回

say DateTime.new("2052-02-29T22:34:56Z").hh-mm-ss;
# OUTPUT: «22:34:56␤»

hour 方法§

method hour(DateTime:D: --> Int:D)

返回小时部分。

say DateTime.new('2012-02-29T12:34:56Z').hour;      # OUTPUT: «12␤»

minute 方法§

method minute(DateTime:D: --> Int:D)

返回分钟部分。

say DateTime.new('2012-02-29T12:34:56Z').minute;     # OUTPUT: «34␤»

second 方法§

method second(DateTime:D:)

返回秒部分,包括可能的分数秒。

say DateTime.new('2012-02-29T12:34:56Z').second;     # OUTPUT: «56␤» 
say DateTime.new('2012-02-29T12:34:56.789Z').second# OUTPUT: «56.789␤» 
say DateTime.new('2012-02-29T12:34:56,789Z').second# comma also ok

whole-second 方法§

method whole-second(DateTime:D:)

返回秒部分,向下舍入到 Int

say DateTime.new('2012-02-29T12:34:56.789Z').whole-second;      # OUTPUT: «56␤»

timezone 方法§

method timezone(DateTime:D: --> Int:D)

返回时区(以秒为单位),作为与 UTC 的偏移量。

say DateTime.new('2015-12-24T12:23:00+0200').timezone;          # OUTPUT: «7200␤»

offset 方法§

method offset(DateTime:D: --> Int:D)

返回时区(以秒为单位),作为与 UTC 的偏移量。这是 timezone 方法 的别名。

say DateTime.new('2015-12-24T12:23:00+0200').offset;            # OUTPUT: «7200␤»

offset-in-minutes 方法§

method offset-in-minutes(DateTime:D: --> Real:D)

返回时区(以分钟为单位),作为与 UTC 的偏移量。

say DateTime.new('2015-12-24T12:23:00+0200').offset-in-minutes# OUTPUT: «120␤»

offset-in-hours 方法§

method offset-in-hours(DateTime:D: --> Real:D)

返回时区(以小时为单位),作为与 UTC 的偏移量。

say DateTime.new('2015-12-24T12:23:00+0200').offset-in-hours;   # OUTPUT: «2␤» 

Str 方法§

method Str(DateTime:D: --> Str:D)

返回调用者的字符串表示形式,由 格式化程序 完成。如果没有指定格式化程序,则会返回 ISO 8601 时间戳。

say DateTime.new('2015-12-24T12:23:00+0200').Str;
# OUTPUT: «2015-12-24T12:23:00+02:00␤» 

Instant 方法§

method Instant(DateTime:D: --> Instant:D)

根据调用者返回一个 Instant 对象。

say DateTime.new('2015-12-24T12:23:00+0200').Instant# OUTPUT: «Instant:1450952616␤»

Real 方法§

multi method Real(DateTime:D: --> Instant:D)

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

自 Rakudo 编译器 2023.02 版本起可用。

方法 Numeric§

multi method Numeric(DateTime:D: --> Instant:D)

自 Rakudo 编译器 2021.09 版本起可用。

将调用者转换为 Instant。可以使用 Instant 方法获取相同的值。这允许在算术运算中直接使用 DateTime 对象。

方法 day-fraction§

method day-fraction(DateTime:D: --> Real:D)

返回瞬时的时刻作为 24 小时一天的分数。

say DateTime.new('2021-12-24T12:23:00.43Z').day-fraction# OUTPUT: «0.5159772␤»

请注意,day-fraction 值与同一瞬时的 modified-julian-date 的小数部分相同。

自 Rakudo 编译器 2021.04 版本起可用。

方法 julian-date§

method julian-date(DateTime:D: --> Real:D)

返回 UTC 日期和时间的 儒略日 (JD)。

say DateTime.new('2021-12-24T12:23:00.43Z').julian-date# OUTPUT: «2459573.0159772␤»

julian-date公元前 4714 年 11 月 24 日 UTC 正午的纪元开始为零,采用 前溯 格里高利历(世界大部分地区和国际商业和旅行中使用的历法)。JD 用于天文学中定义天体经过地球本初子午线的时间。对于任何时刻,它都是从该纪元到该时刻的整数天数和小数天数之和。

自 Rakudo 编译器 2021.04 版本起可用。

方法 modified-julian-date§

method modified-julian-date(DateTime:D: --> Real:D)

返回 UTC 日期和时间的 修正儒略日 (MJD)。

say DateTime.new('2021-12-24T12:23:00.43Z').modified-julian-date# OUTPUT: «59572.5159772␤»

请注意,modified-julian-date 的小数部分与同一瞬时的 day-fraction 值相同。同样,MJD 的整数部分与同一瞬时的 daycount 值相同,因为它们引用相同的纪元(1858 年 11 月 17 日)。MJD 是通过从儒略日中减去常数 2_400_000.5 获得的,用于简化民用和天文时间系统之间的转换。

自 Rakudo 编译器 2021.04 版本起可用。

方法 posix§

method posix(Bool:D: $ignore-timezone = False --> Int:D)

返回日期和时间作为 POSIX/UNIX 时间戳(自 POSIX 纪元(1970-01-01T00:00:00Z)以来的整数秒数)。

如果 $ignore-timezoneTrue,则 DateTime 对象将被视为时区偏移为零。

method posix(Bool:D: $ignore-timezone = False:$real --> Num:D)

自 Rakudo 编译器 2022.06 版本起,还可以指定 :real 命名参数。如果指定为真值,则将返回 Num,从而可以精确到自 POSIX 纪元以来的秒数的亚秒级。

say DateTime.new('2015-12-24T12:23:00Z').posix;           # OUTPUT: «1450959780␤» 
say DateTime.new('2022-06-21T12:23:00.5Z').posix;         # OUTPUT: «1655814180␤» 
say DateTime.new('2022-06-21T12:23:00.5Z').posix(:real);  # OUTPUT: «1655814180.5␤» 

方法 truncated-to§

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

返回调用者的副本,其中小于指定单位的所有内容都截断为最小可能值。

my $d = DateTime.new("2012-02-29T12:34:56.946314Z");
say $d.truncated-to('second');      # OUTPUT: «2012-02-29T12:34:56Z␤» 
say $d.truncated-to('minute');      # OUTPUT: «2012-02-29T12:34:00Z␤» 
say $d.truncated-to('hour');        # OUTPUT: «2012-02-29T12:00:00Z␤» 
say $d.truncated-to('day');         # OUTPUT: «2012-02-29T00:00:00Z␤» 
say $d.truncated-to('month');       # OUTPUT: «2012-02-01T00:00:00Z␤» 
say $d.truncated-to('year');        # OUTPUT: «2012-01-01T00:00:00Z␤»

带有小数秒的 DateTime 可以使用 .truncated-to('second') 截断为整数秒。

方法 Date§

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

将调用者转换为 Date

say DateTime.new("2012-02-29T12:34:56.946314Z").Date# OUTPUT: «2012-02-29␤» 
say DateTime.Date;                                    # OUTPUT: «(Date)␤» 

方法 DateTime§

method DateTime(--> DateTime)

返回调用者。

say DateTime.new("2012-02-29T12:34:56.946314Z").DateTime;
# OUTPUT: «2012-02-29T12:34:56.946314Z␤» 
say DateTime.DateTime;
# OUTPUT: «(DateTime)␤»

方法 utc§

method utc(DateTime:D: --> DateTime:D)

返回同一时间但位于 UTC 时区的 DateTime 对象。

say DateTime.new('2015-12-24T12:23:00+0200').utc;
# OUTPUT: «2015-12-24T10:23:00Z␤»

方法 in-timezone§

method in-timezone(DateTime:D: Int(Cool$timezone = 0 --> DateTime:D)

返回同一时间但位于指定 $timezone 的 DateTime 对象,该时区是与 GMT 的偏移量(以秒为单位)。

say DateTime.new('2015-12-24T12:23:00Z').in-timezone(3600 + 1800); # OUTPUT: «2015-12-24T13:53:00+0130␤»

根据 RFC 7164,闰秒不遵守当地时间,并且始终发生在 UTC 日的末尾

say DateTime.new: '2017-01-01T00:59:60+01:00'
# OUTPUT: «2017-01-01T00:59:60+01:00␤»

方法 local§

method local(DateTime:D: --> DateTime:D)

返回同一时间但位于本地时区 ($*TZ) 的 DateTime 对象。

my $*TZ = -3600;
say DateTime.new('2015-12-24T12:23:00+0200').local# OUTPUT: «2015-12-24T09:23:00-0100␤»

子程序 infix:<->§

multi infix:<-> (DateTime:DDuration:D --> DateTime:D)
multi infix:<-> (DateTime:DDateTime:D --> Duration:D)

获取一个要减去的 DateTime 和一个 Duration 或另一个 DateTime 对象。分别返回一个新的 DateTime 对象或两个日期之间的 Duration。在减去 Duration 时,原始 DateTime 的时区保留在返回的 DateTime 对象中。

say raku DateTime.new(:2016year) - DateTime.new(:2015year):;
# OUTPUT: «Duration.new(31536001.0)␤» 
say DateTime.new(:2016year, :3600timezone) - Duration.new(31536001.0);
# OUTPUT: «2015-01-01T00:00:00+01:00␤»

子程序 infix:<+>§

multi infix:<+> (DateTime:DDuration:D --> DateTime:D)
multi infix:<+> (Duration:DDateTime:D --> DateTime:D)

获取一个 DateTime 并将其增加给定的 Duration,同时保留时区。

say DateTime.new(:2015year) + Duration.new(31536001.0);
# OUTPUT: «2016-01-01T00:00:00Z␤» 
say Duration.new(42+ DateTime.new(:2015year, :3600timezone);
# OUTPUT: «2015-01-01T00:00:42+01:00␤»

子程序 infix:<cmp>§

multi infix:<cmp>(DateTime:D \aDateTime:D \b --> Order:D)

比较等效的瞬间,返回顺序。

类型图§

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

展开上方的图表