将历史时间戳从 UTC 转换为本地
Converting Historical Timestamps from UTC to Local
我有一个文件,其中包含过去的时间戳,并且都是 UTC 时间。我需要将这些转换为东部时间。我已经接近了,但它在夏令时转换期间搞砸了。
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
#DST not in effect
my $utc = '2015-03-08 01:59:00.000';
my $local = utc_to_local($utc);
print "DST not in effect: utc($utc) = local($local)\n";
#DST not in effect
$utc = '2015-03-08 02:00:00.000';
$local = utc_to_local($utc);
print "DST not in effect: utc($utc) = local($local)\n";
sub utc_to_local
{
my $utc_ts = $_[0]; #this has ms on right side, we want left 19 characters
$utc_ts = substr $utc_ts, 0, 19;
my $local_tp = localtime->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
$local_tp = $local_tp + $local_tp->tzoffset();
return $local_tp->strftime('%Y-%m-%d %H:%M:%S');
}
如您所见,如果我在 3 月 8 日尝试 1:59 AM UTC 并在 3 月 8 日尝试 2 AM UTC,它认为更改已经发生,但 2 AM UTC 只有 3/7晚上 9 点。远离夏令时转换,它会正确执行 -5 和 -4 偏移。
DST not in effect: utc(2015-03-08 01:59:00.000) = local(2015-03-07 20:59:00)
DST not in effect: utc(2015-03-08 02:00:00.000) = local(2015-03-07 22:00:00)
$utc_ts
不是当地时间。
my $local_tp = localtime->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
应该是
my $utc_tp = Time::Piece->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
然后是转换为本地时间的问题。
$local_tp = $local_tp + $local_tp->tzoffset();
应该是
my $local_tp = localtime($utc_tp->epoch);
总计:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw( );
use Time::Piece;
sub utc_to_local {
my ($utc_ts) = @_;
my $utc_tp = Time::Piece->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
my $local_tp = localtime($utc_tp->epoch);
return $local_tp->strftime('%Y-%m-%d %H:%M:%S');
}
sub local_to_utc {
my ($local_ts) = @_;
my $local_tp = Time::Piece->strptime( $local_ts, '%Y-%m-%d %H:%M:%S' );
my $utc_tp = gmtime($local_tp->epoch);
return $utc_tp->strftime('%Y-%m-%d %H:%M:%S');
}
{
$ENV{TZ} = 'America/Toronto';
POSIX::tzset();
# DST not in effect
my $utc = '2015-03-08 06:59:00.000';
my $local = utc_to_local(substr($utc, 0, -4));
print "DST not in effect: utc($utc) = local($local)\n";
# DST not in effect
$utc = '2015-03-08 07:00:00.000';
$local = utc_to_local(substr($utc, 0, -4));
print "DST not in effect: utc($utc) = local($local)\n";
}
输出:
DST not in effect: utc(2015-03-08 06:59:00.000) = local(2015-03-08 01:59:00)
DST not in effect: utc(2015-03-08 07:00:00.000) = local(2015-03-08 03:00:00)
我有一个文件,其中包含过去的时间戳,并且都是 UTC 时间。我需要将这些转换为东部时间。我已经接近了,但它在夏令时转换期间搞砸了。
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
#DST not in effect
my $utc = '2015-03-08 01:59:00.000';
my $local = utc_to_local($utc);
print "DST not in effect: utc($utc) = local($local)\n";
#DST not in effect
$utc = '2015-03-08 02:00:00.000';
$local = utc_to_local($utc);
print "DST not in effect: utc($utc) = local($local)\n";
sub utc_to_local
{
my $utc_ts = $_[0]; #this has ms on right side, we want left 19 characters
$utc_ts = substr $utc_ts, 0, 19;
my $local_tp = localtime->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
$local_tp = $local_tp + $local_tp->tzoffset();
return $local_tp->strftime('%Y-%m-%d %H:%M:%S');
}
如您所见,如果我在 3 月 8 日尝试 1:59 AM UTC 并在 3 月 8 日尝试 2 AM UTC,它认为更改已经发生,但 2 AM UTC 只有 3/7晚上 9 点。远离夏令时转换,它会正确执行 -5 和 -4 偏移。
DST not in effect: utc(2015-03-08 01:59:00.000) = local(2015-03-07 20:59:00)
DST not in effect: utc(2015-03-08 02:00:00.000) = local(2015-03-07 22:00:00)
$utc_ts
不是当地时间。
my $local_tp = localtime->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
应该是
my $utc_tp = Time::Piece->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
然后是转换为本地时间的问题。
$local_tp = $local_tp + $local_tp->tzoffset();
应该是
my $local_tp = localtime($utc_tp->epoch);
总计:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw( );
use Time::Piece;
sub utc_to_local {
my ($utc_ts) = @_;
my $utc_tp = Time::Piece->strptime( $utc_ts, '%Y-%m-%d %H:%M:%S' );
my $local_tp = localtime($utc_tp->epoch);
return $local_tp->strftime('%Y-%m-%d %H:%M:%S');
}
sub local_to_utc {
my ($local_ts) = @_;
my $local_tp = Time::Piece->strptime( $local_ts, '%Y-%m-%d %H:%M:%S' );
my $utc_tp = gmtime($local_tp->epoch);
return $utc_tp->strftime('%Y-%m-%d %H:%M:%S');
}
{
$ENV{TZ} = 'America/Toronto';
POSIX::tzset();
# DST not in effect
my $utc = '2015-03-08 06:59:00.000';
my $local = utc_to_local(substr($utc, 0, -4));
print "DST not in effect: utc($utc) = local($local)\n";
# DST not in effect
$utc = '2015-03-08 07:00:00.000';
$local = utc_to_local(substr($utc, 0, -4));
print "DST not in effect: utc($utc) = local($local)\n";
}
输出:
DST not in effect: utc(2015-03-08 06:59:00.000) = local(2015-03-08 01:59:00)
DST not in effect: utc(2015-03-08 07:00:00.000) = local(2015-03-08 03:00:00)