在Perl中如何查找给定日期的上一个星期一的日期?

ani*_*mwr 8 perl date

我正在寻找一个Perl脚本,可以在任何指定的日期给我最后一个星期一.

例如,对于2011-06-11日期,脚本应返回2011-06-06

cjm*_*cjm 24

我假设如果给定的日期是星期一,你想要相同的日期(而不是前一个星期一).这是使用DateTime执行此操作的一种方法:

use DateTime;

my $date = DateTime->new(year => 2011, month => 6, day => 11);
my $desired_dow = 1;            # Monday
$date->subtract(days => ($date->day_of_week - $desired_dow) % 7);
print "$date\n";
Run Code Online (Sandbox Code Playgroud)

(实际上,对于星期一的特殊情况,% 7没有必要,因为$date->day_of_week - 1将永远是0-6,并且mod 7是无操作.但是对于% 7,它适用于任何所需的星期几,而不是就在星期一.)

如果你确实想要上一个星期一,你可以改变减法:

$date->subtract(days => ($date->day_of_week - $desired_dow) % 7 || 7);
Run Code Online (Sandbox Code Playgroud)

如果需要解析在命令行中输入的日期,您可能需要查看DateTime :: Format :: Natural.

  • 在CPAN上有很多方法可以做到这一点以及很多日期/时间模块,但是DateTime是迄今为止用日期和时间做任何事情的最佳模块. (2认同)

mir*_*rod 12

你也可以使用Time :: ParseDate,它理解"上周一".

保持Perl声誉的单线程:

perl -MTime::ParseDate -M'POSIX qw(strftime)' -l -e'foreach (@ARGV) { my $now= parsedate( $_); my $e= parsedate( "last Monday", NOW => $now) ; print "$_ : ", strftime "%F", localtime( $e)}' 2011-06-11 2011-06-12 2011-06-13 2011-06-14
Run Code Online (Sandbox Code Playgroud)

一个理智的脚本:

#!/usr/bin/perl

use strict;
use warnings;

use Time::ParseDate;    # to parse dates
use POSIX qw(strftime); # to format dates

foreach my $date (@ARGV) 
  { my $date_epoch= parsedate( $date) || die"'cannot parse date '$date'\n";
    my $monday= parsedate( "last Monday", NOW => $date_epoch);                  # last Monday before NOW
    print "Monday before $date: ", strftime( "%F", localtime( $monday)), "\n";  # %F is YYYY-MM-DD
  }
Run Code Online (Sandbox Code Playgroud)

几个笔记:如果日期是星期一,那么你得到上一个星期一,这可能是你想要的,也可能不是你想要的,改变那个刚刚设置到第二天(加上60*60*24,一天,到$ date_epoch).那么Time :: ParseDate相当自由,它会愉快地解析2011-23-38(例如2012-12-09).