1

我正在循环一系列连续的日期。我需要找出哪些是周末,以便将它们丢弃。一种方法是通过 perl(我的脚本是用什么编写的)来确定星期几,或者在每次通过循环时进行查询。要检查的日期永远不会超过 30 个,通常是 5 个或更少。加载 Date::Time 并使用 perl 或在不需要模块的情况下运行 Query 会更有效吗?如果 perl 是最好的方法,我可以帮助从 YYYY-MM-DD 格式中提取星期几。我可以使用 1-7 号或短名称 mon-sun。

2012-05-01
2012-05-02
2012-05-03
2012-05-04
2012-05-05
2012-05-06

不确定这是否可能,但也许更合适的解决方案是编写一个查询(因为我知道开始和结束并且它们是连续的)来计算 x 和 y 之间的天数,其中 dayofweek NOT IN(6,7)

4

5 回答 5

3

请参阅DateTime::Format::StrptimeDateTime

use 5.010;
use strictures;
use DateTime::Format::Strptime qw();
my $parser = DateTime::Format::Strptime->new(pattern => '%F');
for my $date (qw(
    2012-05-01
    2012-05-02
    2012-05-03
    2012-05-04
    2012-05-05
    2012-05-06
)) {
    my $dow = $parser->parse_datetime($date)->day_of_week;
    say "$date is a weekend day" if 6 == $dow or 7 == $dow;
}
于 2012-06-06T18:15:21.710 回答
2

MySQL 有一个星期函数,你可以直接使用。

于 2012-06-06T18:15:38.760 回答
2

最明显的解决方案是使用该Time::Piece模块,它自 v5.9 以来一直是 Perl 的核心模块,因此可能不需要在您的系统上安装。

wday方法返回一周中的数字日期,其中 1 == 星期日,因此对于周末,您正在寻找 7(星期六)或 1 的值。这可以进行调整,以便星期六由零(而星期日由 1)表示写作

my $dow = $tp->wday % 7;

之后就是一个周末的测试$dow < 2

这里有一些代码来演示。

use strict;
use warnings;

use Time::Piece;

while (<DATA>) {
  chomp;
  my $tp = Time::Piece->strptime($_, '%Y-%m-%d');
  my $dow = $tp->wday % 7;
  print $_;
  print " (weekend)" if $dow < 2;
  print "\n";
}

__DATA__
2012-05-01
2012-05-02
2012-05-03
2012-05-04
2012-05-05
2012-05-06

输出

2012-05-01
2012-05-02
2012-05-03
2012-05-04
2012-05-05 (weekend)
2012-05-06 (weekend)
于 2012-06-06T18:25:13.470 回答
2

您可以使用核心Time::Local模块,然后使用localtime. 工作日 0 对应于星期日,6 对应于星期六。

#! /usr/bin/env perl

use strict;
use warnings;

use Time::Local;

my @dates = qw(
  2012-05-01
  2012-05-02
  2012-05-03
  2012-05-04
  2012-05-05
  2012-05-06
);

my @days = qw/ Sun Mon Tue Wed Thu Fri Sat /;

foreach my $date (@dates) {
  my($yyyy,$mm,$dd) = split /-/, $date;
  my $time_t = timelocal 0, 0, 0, $dd, $mm-1, $yyyy-1900;
  my $wday = (localtime $time_t)[6];
  my $weekend = ($wday == 0 || $wday == 6) ? " *" : "";

  print "$date: $days[$wday] ($wday)$weekend\n";
}

输出:

2012-05-01:周二(2)
2012-05-02: 星期三 (3)
2012-05-03:周四(4)
2012-05-04:周五(5)
2012-05-05: 星期六 (6) *
2012-05-06: 太阳 (0) *

为了好玩,您可以使用 Swiss Army Chainsaw 并抓取cal实用程序的输出。

#! /usr/bin/env perl

use strict;
use warnings;

use 5.10.0;  # for smart matching

sub weekday_type {
  my($date) = @_;
  die "$0: unexpected date '$date'"
    unless my($yyyy,$mm,$dd) =
             $date =~ /^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})$/;

  my $calendar = `cal -m $mm $yyyy`;
  die "$0: cal -m $mm $yyyy failed" if $?;

  for (split /\n/, $calendar) {
    if (/^ \s* [0-9]{1,2} (?: \s+ [0-9]{1,2})* \s*$/x) {
      my @dates = split;
      my @weekend = splice @dates, @dates > 1 ? -2 : -1;
      return "weekend" if ($dd+0) ~~ @weekend;
    }
  }

  "weekday";
}

像这样使用它

my @dates = qw(
  2012-05-01
  2012-05-02
  2012-05-03
  2012-05-04
  2012-05-05
  2012-05-06
);

my @days = qw/ Sun Mon Tue Wed Thu Fri Sat /;

foreach my $date (@dates) {
  my $type = weekday_type $date;
  print "$date: $type\n";
}

输出:

2012-05-01:平日
2012-05-02:工作日
2012-05-03:平日
2012-05-04:平日
2012-05-05:周末
2012-05-06:周末

我不建议在生产中这样做。

于 2012-06-06T19:42:36.477 回答
0
use Date::Simple qw/date/;
use Date::Range;

my ( $start, $end ) = ( date('2012-05-02'), date('2012-05-16') );
my $range = Date::Range->new( $start, $end );
my @all_dates = $range->dates;

foreach my $d (@all_dates) {
  my $date  = Date::Simple->new($d);
  print $date->day_of_week." ".$d."<br />";
  }

#--OUTPUT--#

3 2012-05-02
4 2012-05-03
5 2012-05-04
6 2012-05-05
0 2012-05-06
1 2012-05-07
2 2012-05-08
3 2012-05-09
4 2012-05-10
5 2012-05-11
6 2012-05-12
0 2012-05-13
1 2012-05-14
2 2012-05-15
3 2012-05-16
于 2012-06-06T19:51:28.607 回答