Конвертировать время файла в GMT в Perl - PullRequest
1 голос
/ 25 января 2020

Я работаю над некоторыми учебными материалами для новых программистов, где я говорю о HTTP-заголовке, поэтому я пытаюсь установить Last-Modified вручную. У меня все получилось, кроме времени доставки файла в GMT. Вот что у меня есть:

Вопрос в том, чтобы дать stat($fh)->mtime, который может работать в любом часовом поясе, какой код необходимо добавить для преобразования в GMT?

my $scriptFilename = $ENV{'SCRIPT_FILENAME'};
my $timestamp;

my $fh = FileHandle->new;
if ($fh->open("< ${scriptFilename}")) {
    $timestamp = time2str("%a, %e %b %Y %X %Z", stat($fh)->mtime);
    $fh->close;
}

#Last-Modified: Tue, 15 Oct 2019 12:45:26 GMT

print <<"END";
Content-type: text/html; charset=iso-8859-1
Last-Modified: $timestamp

<html>
...
</html>

Ответы [ 3 ]

5 голосов
/ 25 января 2020

time2str из пакета Date::Format (я предполагаю, что отсюда time2str) принимает необязательный третий аргумент для указания часового пояса.

$timestamp = time2str("%a, %e %b %Y %X %Z", stat($fh)->mtime, 'UTC');
3 голосов
/ 25 января 2020

Кажется, здесь есть некоторая путаница: результат mtime не находится ни в каком часовом поясе, он находится в секундах, начиная с эпохи, которая является фиксированным моментом времени (за исключением високосных секунд, которые игнорируются). Таким образом, все, что вам нужно сделать, это представить его в нужном часовом поясе, который является UT C. В другом ответе упоминалось, как сделать это с помощью функции, которую вы использовали, но обычной функцией для форматирования времени в строку является strftime, который предоставляется парой основных модулей.

use strict;
use warnings;

use POSIX 'strftime';
# gmtime interprets the mtime seconds in UTC
my $timestamp = strftime "%a, %e %b %Y %X %Z", gmtime $mtime;

use Time::Piece 'gmtime';
my $timestamp = gmtime($mtime)->strftime("%a, %e %b %Y %X %Z");

Но ваше использование case на самом деле является указанным c форматом даты, который используется протоколом HTTP, и который всегда будет в GMT / UT C. Для этого есть модуль: HTTP :: Date

use strict;
use warnings;
use HTTP::Date 'time2str';
my $timestamp = time2str $mtime;
2 голосов
/ 25 января 2020

В основном

  my $dt = DateTime->new(
      year      => 2000,
      month     => 5,
      day       => 10,
      hour      => 15,
      minute    => 15,
      time_zone => 'America/Los_Angeles',
  );

  print $dt->hour; # prints 15

  $dt->set_time_zone( 'America/Chicago' );

  print $dt->hour; # prints 17

См. здесь , чтобы отформатировать вывод.

...