In Date§

请参阅上下文中的主要文档 in context 以了解 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};