将本地时间转换为 UTC 时,如何使 Time::Piece 尊重 DST?

2024-01-08

我想将时间戳从当地时间转换为 GMT。我有遗留代码“手动”执行此操作Time::Local::timelocal() and gmtime。它有效,但我不喜欢它并想使用Time::Piece反而。我用了这个答案 https://stackoverflow.com/a/411795/5830574这样做(尽管他们正在以相反的方式转换,但我能够替换+ with - :-)).

这是我的代码:

#!/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 代码似乎无法在 DST 下正常工作。我住在德国,所以目前(春季/夏季,DST 生效)我们采用 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因为这需要将其部署在十几台生产机器上。


问题1

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

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

to

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

然而,这留下了$utc_tp标记为当地时间,所以你真的想要:

my $utc_tp = gmtime( $local_tp->epoch );

问题2

尽管它的名字,$local_tp不是当地时间,所以$local_tp->tzoffset()为零。改变

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

to

localtime->strptime( $local_ts, '%y-%m-%d %H:%M:%S' );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将本地时间转换为 UTC 时,如何使 Time::Piece 尊重 DST? 的相关文章

随机推荐

  • Angular HTML5 URL - 服务器配置

    我读过 AngularJS 使用 hashbang URL 作为默认值 但这不是一个优势 因此应该使用 HTML5 URL 为了在客户端配置此行为 必须完成以下操作 locationProvider html5Mode true 在服务器端
  • INSTALL_NON_MARKET_APPS 替代方案?

    我需要检查 安装来自未知来源的应用程序 选项是否启用或禁用 然而 INSTALL NON MARKET APPS在 API 17 中已弃用 是否有新的替代方法来检查这一点 这是旧的检查方法 boolean canInstallFromOth
  • Matplotlib 中极坐标图的插值差异

    我正在尝试在极坐标图上生成等值线图 并在 matlab 中编写一些快速脚本以获得一些结果 出于好奇 我也想使用 matplotlib 在 python 中尝试同样的事情 但不知何故 我看到相同输入数据的不同组等高线图 我试图弄清楚发生了什么
  • 如何仅聚合混合数据类型数据框中的数字列

    我有一个混合的pd DataFrame import pandas as pd import numpy as np df pd DataFrame A 1 B pd Timestamp 20130102 C pd Timestamp 20
  • 搜索/迭代 boost::spirit::qi::symbols

    如果我有一个符号表 struct MySymbols symbols
  • OCaml构造函数解包

    是否可以通过将数据绑定到单个值而不是元组来解包类型 type foo Foo of int string type foo Foo of int string Foo 3 bar Foo 3 bar Error The constructo
  • 如何为 geopandas 图制作表格图例

    我正在使用 geopandas 绘制分区统计图 并且需要绘制自定义的表格图例 这个问题 https stackoverflow com questions 44567107 how to make tabular legend using
  • 函数如何检查打字稿中的 null ?

    在 typescript 2 6 中 我想编写一个执行空检查的函数 当我启用严格的空检查时 typescript 2 6 会抱怨以下代码 注意 使用空检查时直接起作用 编辑 已更正notNullOrUndefined因为它没有检查 foo
  • 具有无限参数但具有相同(固定)类型的 C++ 函数

    我想要一个具有无限数量参数的函数 但我还想确保这些都是同一类型的指针 像这样的事情 void myFunc float value MyClass take all pointers of type MyClass and call fun
  • SQL Server 脚本生成器从十六进制转换日期时间值

    我需要从 SQL Server 生成插入脚本 当我使用 SQL Server 脚本生成器时 它会从十六进制转换日期时间值 例如 CAST xxxxxxxxxxxxx as dateTime 我怎样才能避免这种情况 我想要脚本中的实际值 不幸
  • Google Picker API 和选择 Google 云端硬盘项目的问题

    我正在尝试集成 Google Picker 以从 Google Drive 选择文件 如下这个例子 https developers google com drive integrate open 打开选择器时 我在 javascript
  • 使用 NSTask 和 NSPipe 导致 CPU 使用率 100%

    我正在尝试使用 NSTask 运行一个简单的 bash 脚本并将输出定向到文本视图 任务执行后 我的应用程序的 CPU 使用率为 100 即使它是一个简单的任务echo 目前 我创建了一个全新的项目来隔离该问题 interface AppD
  • 如何将 Byte[](解码为 PNG 或 JPG)转换为 Tensorflows 张量

    我正在尝试在 Unity 的项目中使用 Tensorflowsharp 我面临的问题是 对于转换 您通常使用第二个图将输入转换为张量 Android 不支持使用的函数 DecodeJpg 和 DecodePng 那么如何将该输入转换为张量
  • 如何使用 PHP 处理邮件发送错误

    我正在构建一个用于发送新闻通讯的 symfony 模块 这个想法是建立一个地址队列列表来接收邮件 然后使用 cron 作业 一次发送 50 个邮件 我现在不知道如何做是阅读当电子邮件地址不存在或邮件已满时服务器发回的邮件传送报告 这个想法是
  • 在 HTML 中查找值的快速方法 (Java)

    使用正则表达式 获取网站 HTML 并查找此标记内的值 或与此相关的任何属性值 的最简单方法是什么 snip snip 取决于您需要构建的 Http 请求的复杂程度 身份验证等 这是我过去见过的一种简单方法 StringBuilder ht
  • 检查丢失的软件包并安装它们的优雅方法?

    这些天我似乎与合著者分享了很多代码 他们中的许多人都是 R 新手 中级用户 并且没有意识到他们必须安装他们尚未安装的软件包 有没有一种优雅的调用方式installed packages 将其与我正在加载和安装的那些进行比较 如果丢失 是的
  • Windows 批处理文件中一行中的多个命令

    在 Unix 中 我们可以将多个命令放在一行中 如下所示 date ls l date 我在Windows中尝试过类似的事情 gt echo TIME dir echo TIME 但它打印了时间并且不执行命令dir 我怎样才能实现这个目标
  • 在mapview中绘制透明的圆

    我的地图视图和叠加有问题 每次改变 GPS 位置时 我都必须在地图上画一个圆圈 我在覆盖类中使用了扩展覆盖的方法绘制 问题是我必须以透明度绘制这些圆圈 但是当圆圈在交点处相互重叠时 颜色会有所不同 因为存在 alpha 之和 我该如何修复它
  • 多线程Hello World

    使用两个线程 您应该打印 Hello World Hello World Hello World Hello World Hello World Hello World 在两个线程中 一个应该打印 Hello 另一个线程应该打印 World
  • 将本地时间转换为 UTC 时,如何使 Time::Piece 尊重 DST?

    我想将时间戳从当地时间转换为 GMT 我有遗留代码 手动 执行此操作Time Local timelocal and gmtime 它有效 但我不喜欢它并想使用Time Piece反而 我用了这个答案 https stackoverflow