【问题标题】:Converting timestamp to GMT with POSIX使用 POSIX 将时间戳转换为 GMT
【发布时间】:2018-03-07 21:54:37
【问题描述】:

是否可以使用 POSIX 模块在 Perl 中将给定的时间戳转换为 GMT?以下是我尝试过的,但不知道为什么时间如此遥远......

use POSIX;
my $shipts = "2017-09-23 20:53:00";
my $shiptsgmt = strftime("%Y-%m-%d %R", localtime(str2time($shipts, 'GMT')));
print "$shiptsgmt\n";

服务器的本地时间是太平洋时间,猜猜我正在尝试做的事情是不正确的。以上产生 2017-09-23 13:53 我需要 2017-09-24 03:53 时间。

【问题讨论】:

  • 使用 POSIX 允许 str2time。
  • 我在 POSIX 文档(v5.16 和 v5.27)中没有看到...
  • @rwfitzy ?我得到了Undefined subroutine &main::str2time called at ...
  • POSIX.pm 没有任何日期解析实用程序;它不是最适合这项工作的模块。
  • 对不起,我现在看到它实际上来自使用了 Date::Parse 。鉴于这应该是关于该模块而不是现在的 POSIX,解决方案非常简单,可以使用 gmtime 而不是 localtime,如 gmtime(str2time($shipts))。有效!

标签: perl timestamp posix gmt


【解决方案1】:

单独的POSIX 无法做到这一点,这离不开内置函数的帮助和一些处理。

另一种选择:Time::Piece 是核心,根据我的经验,它比 POSIX 快得多

perl -MTime::Piece -wE'
    $d = "2017-09-23 20:53:00"; 
    $t = localtime->strptime($d, "%Y-%m-%d %H:%M:%S");
    $t = gmtime($t->epoch);
    say $t->strftime("%Y-%m-%d %H:%M:%S");
'

这将创建一个对象,然后使用模块的(兼容)替换 gmtime 将其转换为 GMT,返回一个也被适当标记为 GMT 的对象。

strftime 与 POSIX 扩展相同但轻得多,strptimefrom FreeBSD。 该模块还有许多方法可以将日期时间对象的各个部分或表示形式作为字符串获取,以及一些其他实用程序。另见Time::Seconds

DateTime 很好地完成了这一切,通过其 formatters 进行解析和字符串化。但是很重。


注意 最终很容易错误地使用这个模块,而这个答案在ikegami 修复它之前就是这样做的。因此,请非常小心除基本以外的任何用途。查看链接的答案

请注意,上面的答案在 v5.10 中不起作用,显然是由于模块中的 then-bug。

【讨论】:

  • @ikegami 谢谢。我已经编辑了我现在发现的您帖子中的信息,这些信息直接处理了该错误(以及另一篇显然是欺骗的旧帖子)。如果我找到它们,我会添加更合适的链接。 (我清除了一些 cmets 以使您的警告更加明显。)
  • @ikegami 如果我问你一个问题。我已经为这里的特殊用途编写了一个子类化Time::Piece(小心!)的实用程序,它就像一个魅力。但我永远无法找到与此相关的部分:这个模块是否有任何故障,有边缘情况、DST、没有午夜的日子等等? (不包括技巧和用户错误。)我正在考虑相当基本的用途,用于上个世纪左右的全球日期时间。我已经搜索和搜索,发现没什么好担心的,但这是一项棘手的工作。虽然在这里不能问这样的问题:(
  • 它使用localtime 表示时区的东西,所以那里没有感兴趣的问题。 T::P 的问题在于它很容易做错事。这是 API 设计失败,而不是代码中的错误。子类化可能会继承这些问题。封装可能不会。
  • @ikegami 非常感谢您终于清除了这个问题!提示一下——我被便利所吸引,但后来我也以这种方式暴露了棘手的部分(虽然我不需要所有这些)。是时候为事情计时了..
猜你喜欢
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
相关资源
最近更新 更多