【问题标题】:perl strftime localtime minus 12 hoursperl strftime localtime 减去 12 小时
【发布时间】:2020-05-23 05:11:09
【问题描述】:

我正在使用 perl strftime for (datetime now)

perl -MPOSIX -e 'print POSIX::strftime("%m/%d/%Y %H:%M", localtime());'

我想现在将日期时间减去 12 小时

示例输出: 2/7/2020 1:002/6/2020 13:00

请使用上述代码帮助解决此问题

【问题讨论】:

    标签: perl datetime strftime localtime


    【解决方案1】:

    POSIXstrftime

    返回字符串。

    而且您不能方便地从字符串中减去小时数。

    改为使用库进行日期时间处理以进行操作,然后使用strftime进行格式化

    Time::Piece 的示例

    perl -MTime::Piece -MTime::Seconds -wE'
        $t = (localtime) - 12*ONE_HOUR;
        say $t->strftime("%m/%d/%Y %H:%M")'
    

    Time::SecondsTime::Piece 一起提供,用于各种日期时间计算。

    虽然Time::Piece 是核心、优秀且众所周知,但它确实存在微妙之处和局限性,对于更多涉及的工作,我推荐无所不知(而且又大又重)DateTime

    perl -MDateTime -wE'
        $t = DateTime->now(time_zone => "local")->subtract(hours => 12); 
        say $t->strftime("%m/%d/%Y %H:%M")'
    

    我认为值得强调的是,这个模块几乎可以用日期时间做所有事情。


    作为说明,请记住夏令时更改带来的问题。在时钟奇迹般的跳跃和偶尔不存在的时间之间可能会有不愉快的惊喜,尽管很少 (an example)。

    这是ikegami 编写的provided 程序,用于测试coming DST(3 月 8 日凌晨 2 点 -> 凌晨 3 点)

    use strict;
    use warnings;
    
    use DateTime      qw( );
    use POSIX         qw( strftime );
    use Time::Piece   qw( localtime );
    use Time::Seconds qw( ONE_HOUR );
    
    my $epoch = 1583683200;  # 2020-03-08T12:00:00
    
    CORE::say
       for
          DateTime->from_epoch( epoch => $epoch, time_zone => $ENV{TZ} )
                  ->subtract( hours => 12 ),
          strftime("%FT%T", localtime($epoch - 12*60*60)),
          ( localtime($epoch) - 12*ONE_HOUR )->strftime("%FT%T");
    

    然后设置TZ环境变量并运行

    TZ=America/New_York perl test_DST.pl
    

    (在 bash 中,在 tcsh 中为 setenv TZ "America/New_York"; perl test_DST.pl

    输出

    2020-03-07T23:00:00 2020-03-07T23:00:00 2020-03-07T23:00:00

    具有该名称的函数存在于许多环境中,并且始终返回格式化字符串。

    【讨论】:

    • @ikegami 啊,太棒了!有趣的是,所有(此页面上显示的三种方法 - localtime 调整和此答案中的两种)“工作”相同。我不明白它是如何在晚上 11 点结束(而不是)结束的......(我认为在这个答案中包含你的代码是个好主意)
    • America/New_York 对 start ts 使用 EDT,但对较早的 ts 使用 EST。美国东部时间中午前 12 小时是美国东部时间午夜或美国东部时间晚上 11 点。
    • @ikegami 呃,对。谢谢。我已将您的程序添加到帖子中
    【解决方案2】:

    使用Time::MomentTime::Moment::Role::TimeZone(更正夏令时更改):

    perl -MTime::Moment -MWith::Roles -E'say Time::Moment->with::roles("+TimeZone")->now
      ->minus_hours(12)->with_system_offset_same_instant->strftime("%m/%d/%Y %H:%M")'
    

    【讨论】:

      猜你喜欢
      • 2015-04-05
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 2016-10-04
      相关资源
      最近更新 更多