Как я могу получить даты этой недели в Perl?

У меня есть следующий цикл, чтобы вычислить даты текущей недели и распечатать их. Это работает, но я плаваю в сумме возможностей даты/времени в Perl и хочу надеть Ваше мнение, существует ли лучший путь. Вот код, который я написал:

#!/usr/bin/env perl
use warnings;
use strict;

use DateTime;

# Calculate numeric value of today and the 
# target day (Monday = 1, Sunday = 7); the
# target, in this case, is Monday, since that's
# when I want the week to start
my $today_dt = DateTime->now;
my $today = $today_dt->day_of_week;
my $target = 1;

# Create DateTime copies to act as the "bookends"
# for the date range
my ($start, $end) = ($today_dt->clone(), $today_dt->clone());

if ($today == $target)
{
  # If today is the target, "start" is already set;
  # we simply need to set the end date
  $end->add( days => 6 );
}
else
{
  # Otherwise, we calculate the Monday preceeding today
  # and the Sunday following today
  my $delta = ($target - $today + 7) % 7;
  $start->add( days => $delta - 7 );
  $end->add( days => $delta - 1 );
}

# I clone the DateTime object again because, for some reason,
# I'm wary of using $start directly...
my $cur_date = $start->clone();

while ($cur_date <= $end)
{
  my $date_ymd = $cur_date->ymd;
  print "$date_ymd\n";
  $cur_date->add( days => 1 );
}

Как упомянуто, это работает, но действительно ли это является самым быстрым или самым эффективным? Я предполагаю, что быстрота и эффективность не могут обязательно сочетаться, но Ваша обратная связь очень ценится.

7
задан brian d foy 27 May 2010 в 03:29
поделиться

4 ответа

Немного улучшенная версия ответа friedo ...

my $start_of_week =
    DateTime->today()
            ->truncate( to => 'week' );

for ( 0..6 ) {
    print $start_of_week->clone()->add( days => $_ );
}

Однако здесь предполагается, что понедельник - первый день недели. В воскресенье начните с ...

my $start_of_week =
    DateTime->today()
            ->truncate( to => 'week' )
            ->subtract( days => 1 );

В любом случае лучше использовать метод truncate , чем реализовывать его заново, как это сделал Фридо;)

15
ответ дан 6 December 2019 в 08:14
поделиться

Будет ли это работать:

use strict;
use warnings;
use POSIX qw<strftime>;
my ( $day, $pmon, $pyear, $wday ) = ( localtime )[3..6];
$day -= $wday - 1; # Get monday
for my $d ( map { $day + $_ } 0..6 ) { 
    print strftime( '%A, %B %d, %Y', ( 0 ) x 3, $d, $pmon, $pyear ), "\n";
}

Я печатаю их только в качестве иллюстрации. Вы можете сохранить их как временные метки, например:

use POSIX qw<mktime>;
my @week = map { mktime(( 0 ) x 3, $day + $_, $pmon, $pyear ) } 0..6;
2
ответ дан 6 December 2019 в 08:14
поделиться

Вы можете использовать объект DateTime, чтобы получить текущий день недели в виде числа (1-7). Тогда просто используйте это, чтобы найти понедельник текущей недели. Например:

my $today = DateTime->now;
my $start = $today->clone;

# move $start to Monday
$start->subtract( days => ( $today->wday - 1 ) );   # Monday gives 1, so on monday we
                                                    # subtract zero. 

my $end = $start->clone->add( days => 7 );

Вышеупомянутое не проверено, но идея должна работать.

4
ответ дан 6 December 2019 в 08:14
поделиться

Это должно сработать:

use POSIX; # for strftime
my $time = time ();
my $seconds = 24*60*60;
my @time = gmtime ();
$time = $time - $time[6] * $seconds;
for my $wday (0..6) {
    $time += $seconds;
    my @wday = gmtime ($time);
    print strftime ("%A %d %B %Y\n", @wday);
}

Дает мне:

$ ./week.pl 
Monday 24 May 2010
Tuesday 25 May 2010
Wednesday 26 May 2010
Thursday 27 May 2010
Friday 28 May 2010
Saturday 29 May 2010
Sunday 30 May 2010

Если вы хотите, чтобы недели начинались с воскресенья, измените $ time [6] на ($ time [6] + 1) .

Предполагается, что вам нужны недели по Гринвичу. Измените gmtime на localtime , чтобы получить недели местного часового пояса.

1
ответ дан 6 December 2019 в 08:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: