gpt4 book ai didi

perl - 将本地时间转换为 UTC 时,如何使 Time::Piece 遵守 DST?

转载 作者:行者123 更新时间:2023-12-04 11:35:21 26 4
gpt4 key购买 nike

我想将时间戳从本地时间转换为 GMT。我有使用 Time::Local::timelocal()“手动”执行此操作的遗留代码和 gmtime .它有效,但我不喜欢它并想使用 Time::Piece反而。我用过 this answer这样做(尽管他们正在以相反的方式转换,但我能够用 + 替换 - :-))。

这是我的代码:

#!/usr/bin/env perl

use strict;
use warnings;
use Time::Local;
use Time::Piece;
use POSIX qw(strftime);

sub local_to_utc_timelocal
{
my $local_ts = shift;
my ( $year, $mon, $mday, $hour, $min, $sec )
= ( $local_ts =~ /(\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/ );
my $local_secs = Time::Local::timelocal( $sec, $min, $hour, $mday, $mon - 1, $year );
return POSIX::strftime( '%y-%m-%d %H:%M:%S', gmtime($local_secs) );
}

sub local_to_utc_timepiece
{
my $local_ts = shift;
my $local_tp = Time::Piece->strptime( $local_ts, '%y-%m-%d %H:%M:%S' );
my $utc_tp = $local_tp - localtime->tzoffset(); # ***
return $utc_tp->strftime('%y-%m-%d %H:%M:%S');
}

my $local;

# DST in effect (April 19 2016):
$local = '16-04-19 14:30:00';
print "DST in effect:\n";
printf("utc(%s) = %s (using timelocal)\n", $local, local_to_utc_timelocal($local));
printf("utc(%s) = %s (using timepiece)\n\n", $local, local_to_utc_timepiece($local));

# DST NOT in effect (Feb 19 2016):
$local = '16-02-19 14:30:00';
print "DST NOT in effect:\n";
printf("utc(%s) = %s (using timelocal)\n", $local, local_to_utc_timelocal($local));
printf("utc(%s) = %s (using timepiece)\n", $local, local_to_utc_timepiece($local));

不幸的是,Time::Piece 代码似乎在夏令时无法正常工作。我住在德国,所以目前( Spring /夏季,有效的夏令时)我们是 UTC+2。对于“2016 年 4 月 19 日”,上面的代码给出:
DST in effect:
utc(16-04-19 14:30:00) = 16-04-19 12:30:00 (using timelocal)
utc(16-04-19 14:30:00) = 16-04-19 12:30:00 (using timepiece)

哪个是正确的。但是对于“2016 年 2 月 19 日”(当我们是 UTC+1 时),相同的代码给出:
DST NOT in effect:
utc(16-02-19 14:30:00) = 16-02-19 13:30:00 (using timelocal)
utc(16-02-19 14:30:00) = 16-02-19 12:30:00 (using timepiece)

即: gmtime(Time::Local::timelocal($timestamp))给出正确的 1 小时偏移,而 Time::Piece仍然提供 2 小时的补偿。

这是 Time::Piece 中的错误吗?还是我用错了?

我知道有很多方法可以将本地时间转换为 UTC,但我想使用 Time::Piece因为它的简单。另外我不能使用 DateTime因为这将涉及将其部署在十多台生产机器上。

最佳答案

问题一
localtime现在返回,所以 localtime->tzoffset()暂时返回偏移量。改变

my $utc_tp = $local_tp - localtime->tzoffset();


my $utc_tp = $local_tp - $local_tp->tzoffset();

然而,这留下了 $utc_tp标记为本地时间,所以你真的想要:
my $utc_tp = gmtime( $local_tp->epoch );

问题二

尽管它的名字, $local_tp不是本地时间,所以 $local_tp->tzoffset()为零。改变
Time::Piece->strptime( $local_ts, '%y-%m-%d %H:%M:%S' )


localtime->strptime( $local_ts, '%y-%m-%d %H:%M:%S' );

关于perl - 将本地时间转换为 UTC 时,如何使 Time::Piece 遵守 DST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36728581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com