简体   繁体   中英

Convert filetime to GMT in Perl

I am working on some training material for new programmers where I am talking about the HTTP Header, so I am trying to set the Last-Modified manually. I have everything worked out except for getting the file time to GMT. Below is what I have so far:

The question is: giving stat($fh)->mtime which could be running in any timezone, what code needs to be added to convert to 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>

time2strDate::Format封装(我假定这就是time2str来自)有一个可选的第三个参数指定的时区。

$timestamp = time2str("%a, %e %b %Y %X %Z", stat($fh)->mtime, 'UTC');

There seems to be some confusion here: the result of mtime is not in any time zone, it is in seconds since the epoch which is a fixed point in time (barring leap seconds which are ignored). Thus all you need to do is represent it in the time zone you want, which is UTC. Another answer mentioned how to do this with the function you had been using, but the usual function to format a time into a string is strftime, which is provided by a couple core modules.

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");

But your use case is actually a specific date format, the one the HTTP protocol uses, and which will always be in GMT/UTC. There is a module for that: HTTP::Date

use strict;
use warnings;
use HTTP::Date 'time2str';
my $timestamp = time2str $mtime;

Basically

  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

See here for how to format the output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM