【问题标题】:Looking for Perl 5.12 code that generates yesterday's date in DDMMYY format寻找以 DDMMYY 格式生成昨天日期的 Perl 5.12 代码
【发布时间】:2014-09-25 02:38:45
【问题描述】:

我想要一种简单的方法来获取昨天的日期(当地时间)作为 Perl 脚本中的字符串。最好不要依赖模块,因为我们安装了基本的 Perl 5.12。

所以,类似:

my $yesterdays_date=...; # Puts for example '301011' into $yesterdays_date, 
                         # if today is October 31st, 2011

【问题讨论】:

  • 昨天并不总是 86_400 秒前,这要归功于夏令时和闰秒。您需要知道 86_400 秒前的日期(如当前答案所示),还是需要知道昨天的日历日期?
  • 我在昨天的日历日期之后,但考虑到我们当地的凌晨 2 点 -> 凌晨 1 点,反之亦然 DST 转换,你能想出一个案例,减去 86,400 秒不会给你昨天的日期吗?
  • 在我的时区,2011 年 3 月 13 日只有 23 小时。那么,第二天 2011 年 3 月 14 日 00:30 前 86_400 秒是哪一天?在我的时区,2011 年 11 月 6 日将有 25 小时。 2011 年 11 月 6 日 23:30 前 86_400 秒是哪一天?

标签: perl


【解决方案1】:

Time::Piece 是核心:

use Time::Piece;
use Time::Seconds qw(ONE_DAY);

my $yesterday = localtime() - ONE_DAY();
print $yesterday->strftime('%d%m%y'), "\n";

如果您担心夏令时,可以将当前时间标准化为接近中午:

use Time::Piece;
use Time::Seconds qw(ONE_DAY ONE_HOUR);

my $today = localtime;
my $yesterday = $today + ONE_HOUR * ( 12 - $today->hour ) - ONE_DAY;
print $yesterday->strftime("%d%m%y"), "\n";

如果你可以忍受依赖,那么使用DateTime:

use DateTime;

print DateTime->now->subtract(days => 1)->strftime('%d%m%y'), "\n";

【讨论】:

  • 你的意思当然是 $yesterday->strftime('%d%m%y'),但是这样就行了,谢谢!
  • 既然你似乎已经回答并跑掉了,我 FTFY :)
  • FWIW,第二种技术,从今天 00:00 开始回归,可以完全使用 POSIX.pm:strftime q|%d%m%y|, localtime(mktime(0, 0, 0, (localtime)[3,4,5], 0 ,0) - 2*60) 完成。不能保证避免 DST/civil-time-adjustment 错误,但与幼稚的方法相比,遇到这些错误的可能性较小。
  • 如果你觉得你真的必须通过加减一天的秒数来做日期数学,最安全的方法是将日期调整到中午(如果需要,保存时间部分)然后做任何数学(然后在需要时恢复保存的时间部分)。
  • @Ven'Tatsu:已更新。有时,您必须使用可用的东西并且没有时间获得基础设施来在生产中安装东西。我在可用时使用 DateTime。
【解决方案2】:

如果您愿意使用依赖项,DateTime 通常会做任何您需要的事情。

use strict;
use warnings;
use 5.012;

use DateTime;

say DateTime->now->subtract(days => 1)->strftime('%d%m%y');

【讨论】:

  • 我的意思是,我理解不想要依赖关系,但是在我开始使用 DateTime 处理所有事情之后,我对“如何正确处理日期和时间的 $x”的头痛真的消失了。
  • @Ven'Tatsu,听,听。 +1 回答和 +1 评论。
  • @runrig:至少需要 5.10 才能说。
【解决方案3】:

只需从当前时间减去 24 小时(24 小时 * 60 分钟 * 60 秒)即可得到本地时间:

say scalar localtime(time - 60*60*24);
# Sun Oct 30 21:04:30 2011

注意,localtime 仅在标量上下文中以字符串格式返回时间。 如果您需要生成“DDMMYY”,您可以使用列表上下文返回的数据结构:

my @tm = localtime(time - 60*60*24);
my $date = sprintf("%02d%02d%2d", $tm[3], $tm[4]+1, $tm[5] + 1900);
# 30102011

【讨论】:

    【解决方案4】:

    您可以这样使用 POSIX 模块:

    perl -MPOSIX=strftime -le 'print strftime "%m%d%y",localtime(time-(60*60*24))'
    

    【讨论】:

    • 小心在 localtime 中减去 24 小时。许多当地人一年一次,一天只有 23 小时,一年一次,一天有 25 小时。无论哪种情况,如果您的代码在正确的时间运行,结果将是两天前或今天。
    • 如果我们的 DST 转换是凌晨 1 点 -> 凌晨 2 点,反之亦然,那么在一天中的什么时间从本地时间减去 24 小时会出现问题?我可以看到这对于其他时区来说可能是个问题,但生活在 CST 下会让生活更轻松。
    • @MichaelGoldshteyn :美国的实际转换时间为 01:59:59,向前到 03:00:00 或向后到 01:00:00。
    • 如果你从时间 '2011-11-06 23:30' 中减去 24 小时(以秒为单位)得到的时间是 '2011-11-06 00:30',这是因为日期 2011- 11-06 在美国一天有 25 小时。
    猜你喜欢
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    相关资源
    最近更新 更多