Как мне получить вчерашнюю дату в Perl? - PullRequest
4 голосов
/ 14 мая 2019

В настоящее время я беру сегодняшнюю дату, используя ниже. Мне нужно получить вчерашнюю дату, используя это .. как я могу получить это?

my $today = `date "+%Y-%m-%d"`;

Ответы [ 6 ]

9 голосов
/ 14 мая 2019

Если вы хотите, чтобы вчерашняя дата:

use DateTime qw( );

my $yday_date =
   DateTime
      ->now( time_zone => 'local' )
      ->set_time_zone('floating')
      ->truncate( to => 'days' )
      ->subtract( days => 1 )
      ->strftime('%Y-%m-%d');

Например, в Нью-Йорке, в 2019-05-14 01:00:00, он даст 2019-05-13.

Например, в Нью-Йорке в 2019-11-04 00:00:00 он выдаст 2019-11-03.

Обратите внимание, что ->now( time_zone => 'local' )->set_time_zone('floating')->truncate( to => 'days' ) используется вместо ->today( time_zone => 'local' ) для решения эта проблема .


Если вы хотите время на день раньше:

use DateTime qw( );

my $yday_datetime =
   DateTime
      ->now( time_zone => 'local' )
      ->subtract( days => 1 )
      ->strftime('%Y-%m-%d %H:%M:%S');

Например, в Нью-Йорке, в 2019-05-14 01: 00: 00 - 2019-05-13, 01: 00: 00.

Например, в Нью-Йорке в 2019-03-10, 12:00:00 - 2019-03.-09 12: 00: 00.

Например, в Нью-Йорке в 2019-03-11 02:30:00 будет выдано сообщение об ошибке.(2019-03-10 02:30:00 не существует из-за перехода на летнее время.)


Если вы хотите установить время на 24 часа раньше:

use DateTime qw( );

my $yday_datetime =
   DateTime
      ->now( time_zone => 'local' )
      ->subtract( hours => 24 )
      ->strftime('%Y-%m-%d %H:%M:%S');

Например, в Нью-Йорке, в 2019-05-14 01:00:00, он даст 2019-05-13 01: 00: 00.

Например, в Нью-Йорке, в 2019-03-10 12:00:00, это будет 2019-03-09 11: 00: 00.

Например, в Нью-Йорке, в 2019-03-11 02:30:00, этодаст 2019-03-10 01: 30: 00.

7 голосов
/ 14 мая 2019

Использование DateTime module

use strict;
use warnings;
use feature 'say';

use DateTime;

my $today = DateTime->today(time_zone => 'local');

my $yesterday = $today->clone->add(days => -1);

say $yesterday->ymd;  #--> 2019-05-13

или напрямую

my $yesterday = DateTime->today(time_zone => 'local')->add(days => -1);

Теперь это объекты, с которыми вы можете делать практически все, что связано с датой и временем.

Чтобы извлечь строку в формате вопроса, используйте $yesterday->ymd, поскольку ymd по умолчанию имеет формат %Y-%m-%d.Практически произвольные форматы могут быть получены с использованием метода strftime .


Нет никаких причин использовать системные средства для такой работы.Более того, модуль является несравненно более сложным и округлым для всех видов любопытных случаев и потребностей.

Пример: в некоторые даты, когда наступает летнее время, в определенные периоды времени просто не существует .Документы предлагают пример от 2003-04-06, когда 01:59:59 «прыгает» на 03:00:00 и этот час истек.Модуль обрабатывает попытки использовать такое (несуществующее время) правильно, выдавая ошибки.

И если вам нужно выполнить какую-либо работу с датами, то использование системного date даже не вариант, так как вы получаетеназад просто строка, которую вам придется анализировать вручную для любого дальнейшего использования.


Было добавлено, что на самом деле также требуется время, а не только дата.Затем, например,

my $today = DateTime->now(time_zone => 'local');

say $today->strftime("%Y%m%d_%H.%M.%S");         #--> 20190522_22.44.23

my $yesterday = $today->clone->add(days => -1);

say $yesterday->strftime("%Y%m%d_%H.%M.%S");     #--> 20190521_22.44.23

, где метод now"сохраняет" (местное) время вместе с датой (today равно truncate -ed now).

3 голосов
/ 14 мая 2019

Я рекомендую использовать DateTime (как описано в ответе Ikegami).Но если вы не хотите устанавливать модуль CPAN, этот метод использует только функции, доступные в стандартной установке Perl.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Time::Local;
use POSIX 'strftime';

# Get the current date/time
my ($sec, $min, $hr, $day, $mon, $yr) = localtime;

# Get the epoch seconds for midday today
# (we use midday to eliminate potential problems
# when entering or leaving daylight savings time)
my $midday = timelocal(0, 0, 12, $day, $mon, $yr);

# Subtract a day's worth of seconds from the epoch
my $midday_yesterday = $midday - (24 * 60 * 60);

# Convert that epoch value to a string date using
# localtime() and POSIX::strftime().
my $yesterday = strftime('%Y%m%d', localtime($midday_yesterday));

say $yesterday;
2 голосов
/ 14 мая 2019

С Время :: Момент , для только вчерашней даты:

use strict;
use warnings;
use Time::Moment;
my $yesterday = Time::Moment->now->minus_days(1)->strftime('%Y-%m-%d');

Время :: Момент работает в моменты и смещения, а не часовые пояса, поэтому, если вы хотите точную датуи время «один день назад» в вашем местном часовом поясе, как в примерах DateTime, вы можете использовать Time :: Moment :: Role :: TimeZone .

use strict;
use warnings;
use Time::Moment;
use Role::Tiny ();
my $class = Role::Tiny->create_class_with_roles('Time::Moment', 'Time::Moment::Role::TimeZone');
my $yesterday = $class->now->minus_days(1)->with_system_offset_same_local; # 1 day ago
my $yesterday = $class->now->minus_days(1)->with_system_offset_same_instant; # 24 hours ago

ИТе же предостережения применяются, если текущее время не существует в предыдущий день в местном часовом поясе.

0 голосов
/ 14 мая 2019

Использование строки backtick имеет некоторые причуды .... Мне обычно нравится этот оператор на диске.

Позвольте мне рекомендовать использовать функцию localtime(), предоставляемую модулем Time::Piece (есть bulitin localtime()функция, но тот из Time::Piece является удивительным:)


use Time::Piece;

my ($t, $today, $yesterday);

$t = localtime();
$today = sprintf('%04d/%02d/%02d', $t->year, $t->mon, $t->mday);

$t = localtime(time() - 86400);
$yesterday = sprintf('%04d/%02d/%02d', $t->year, $t->mon, $t->mday);

0 голосов
/ 14 мая 2019
my $yesterday = `date -d yesterday +%Y%m%d-%H%M%S`;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...