使用DateTime模块将带小时的EDT时间戳转GMT遇异常
EDT时间戳转GMT时间失败,转换前后结果一致
我编写了如下Perl脚本,尝试借助DateTime模块将带小时的EDT时间戳转换为GMT时间:
use strict; use warnings; use DateTime; use DateTime::Format::Strptime; my $watermark = "2023081410"; my $parseesthour = DateTime::Format::Strptime->new(pattern => '%Y%m%d%H', time_zone => 'America/New_York'); my $parsegmthour = DateTime::Format::Strptime->new(pattern => '%Y%m%d%H', time_zone => 'GMT'); $watermark = $parseesthour->parse_datetime($watermark); $watermark->set_formatter($parseesthour); print "\nwatermark before - $watermark\n"; my $watermarkgmt = $parsegmthour->parse_datetime($watermark); $watermarkgmt->set_formatter($parsegmthour); print "\nwatermark after - $watermarkgmt\n";
但脚本输出的转换前后时间戳完全一致:
watermark before - 2023081410
watermark after - 2023081410
问题原因
错误出在重新解析DateTime对象的步骤:
当你把已经是DateTime对象的$watermark传给parse_datetime时,Perl会自动调用对象的字符串化方法(因为你之前通过set_formatter设置了EDT格式的输出),实际传入的是字符串2023081410。此时$parsegmthour会把这个字符串当作GMT时区的时间来解析,而非转换原EDT时间的时区,最终得到的自然是和原字符串一致的结果。
修正方案
不需要重新解析,直接调用DateTime对象的set_time_zone方法切换时区即可:
use strict; use warnings; use DateTime; use DateTime::Format::Strptime; my $watermark = "2023081410"; my $parse_edt = DateTime::Format::Strptime->new( pattern => '%Y%m%d%H', time_zone => 'America/New_York' ); my $parse_gmt = DateTime::Format::Strptime->new( pattern => '%Y%m%d%H', time_zone => 'GMT' ); # 解析EDT时间为DateTime对象 my $dt_edt = $parse_edt->parse_datetime($watermark); print "\nwatermark before - " . $parse_edt->format_datetime($dt_edt) . "\n"; # 直接切换时区到GMT $dt_edt->set_time_zone('GMT'); # 用GMT格式输出 print "\nwatermark after - " . $parse_gmt->format_datetime($dt_edt) . "\n";
输出结果
watermark before - 2023081410 watermark after - 2023081414
解释:2023年8月14日EDT的10点,对应GMT的14点(EDT夏令时比GMT晚4小时),转换结果符合预期。
内容的提问来源于stack exchange,提问作者James Finnegan
相关产品推荐
相关产品推荐

