查找Perl 6上周五的日期?

che*_*nyf 5 date sequence perl6 raku

我想生成一个序列,从上周五到周四结束,如果序列在周六和周日开始,则在前一周的周五结束.也就是说,假设今天是2018-05-09,那么上周五是2018-05-04,如果今天是2018-05-12,那么上周五也是 2018-05-04.所以我写道:

(Date.today, *.earlier(:1day) ... ( *.day-of-week==5 && *.week[1]+1==Date.today.week[1] )).tail # Output: 2018-05-06
Run Code Online (Sandbox Code Playgroud)

但结果2018-05-06却不是2018-05-04.

然后我用了一个Junction:

(Date.today, *.earlier(:1day) ... all( *.day-of-week==5,  *.week[1]+1==Date.today.week[1] )).tail # Output: 2018-05-04
Run Code Online (Sandbox Code Playgroud)

为什么&&在第一种情况下是错的?该...经营者说:

右侧将有一个端点,可以是Inf或*表示"无限"列表(其元素仅按需生成),一个表达式将在True时结束序列,或其他元素如Junctions.

&&操作员出了什么问题?

Bra*_*ert 5

问题是你的结局条件

*.day-of-week==5 && *.week[1]+1==Date.today.week[1]
Run Code Online (Sandbox Code Playgroud)

这是两个WhateverCode lambdas,每个lambdas都有1个参数.

*.day-of-week==5
Run Code Online (Sandbox Code Playgroud)
*.week[1]+1==Date.today.week[1]
Run Code Online (Sandbox Code Playgroud)

由于代码对象是真值,&&操作符移动到第二个.因此序列在到达前一周的星期日时停止.

即使代码是单个lambda,它也不会像你期望的那样工作,因为它将是一个带有两个参数的lambda.

执行此检查的正确方法是使用某种块.

{.day-of-week==5 && .week-number+1 == Date.today.week-number}
Run Code Online (Sandbox Code Playgroud)

将它包装在子程序中以便您可以测试它可能是个好主意.

sub last-friday ( Date:D $date ) {
  # cache it so that it doesn't have to be looked up on each iteration
  my $week-number = $date.week-number - 1;

  (
    $date,
    *.earlier( :1day )

    ...

    {
          .day-of-week == 5
      &&
          .week-number == $week-number
    }
  ).tail
}

say last-friday Date.new: :year(2018), :month( 5), :day( 9); # 2018-05-04
say last-friday Date.new: :year(2018), :month( 5), :day(12); # 2018-05-04

say Date.today.&last-friday; # 2018-05-04
Run Code Online (Sandbox Code Playgroud)

您也可以只计算正确的日期.

sub last-friday ( Date:D $date ) {
  $date.earlier:
    days => (
      $date.day-of-week # reset to previous sunday
      + 2               # go two days earlier to get friday
    )
}

say last-friday Date.new: :year(2018), :month( 5), :day( 9); # 2018-05-04
say last-friday Date.new: :year(2018), :month( 5), :day(12); # 2018-05-04

say Date.today.&last-friday; # 2018-05-04
Run Code Online (Sandbox Code Playgroud)