如何从 Perl 中的随机纪元时间戳获取纪元形式的月份开始?
Posted
技术标签:
【中文标题】如何从 Perl 中的随机纪元时间戳获取纪元形式的月份开始?【英文标题】:How can I get start of month in epoch form from random epoch timestamp in Perl? 【发布时间】:2012-11-16 15:06:11 【问题描述】:我从数据库中获取了一些时间,并尝试使用 epoch 表单按月存储它们。 所以我可以有一些随机时间,比如:
1354120744
1328978360
1297388332
对于每个我想找到代表该月第一天的纪元值 所以对于最后一个时间戳,它将是:
1296518400
(使用可爱的epochconverter.com
)。
我知道我可以使用POSIX mktime
将时间戳减少到天、分钟等并相应地更改它们等,就像我不久前发布的帖子的答案一样:How to go back months in Perl taking account of different days in month?
我遇到的麻烦是,虽然我可以零次,但我担心通过更改日期,星期几将不匹配,因此本质上是一个无效的日期。这可能是不必要的担心;我不知道如果时间得到验证,一周中的错误日期是否会有所不同。
我看不到任何其他似乎有用的 POSIX 方法。任何帮助表示赞赏!
【问题讨论】:
【参考方案1】:自从遇到DateTime,我就不再担心时间戳问题了:
$ perl -MDateTime -E 'say DateTime->from_epoch(epoch => 1354120744)->truncate(to => "month")->epoch;'
1351728000
【讨论】:
不错的模块,但时区是硬编码的,它可以在白天出现段错误 DateTime 是一种方式,但我认为我们需要通过给from_epoch
一个time_zone
参数来尊重时区差异。
似乎运作良好,但不看文档就不太容易理解 - @PSIAlt 所说的很有趣
作为 DateTime->from_epoch() 文档状态,“默认情况下,返回的对象将在 UTC 时区。”。当然,你可以声明DateTime->from_epoch(epoch => 1354120744, time_zone => "local")
@darch 纪元时间(unix 时间戳)是 UTC,因此与时区无关。 creaktive,我没有我以前工作的代码。但是日期时间数学有一些东西【参考方案2】:
我的第一个想法是使用Time::Local 将localtime
结果转换回纪元,并根据需要将适当的值强制为 0 或 1。请注意,星期几不在它所期望的输入值中,因此您不必担心如果输入错误会发生什么。
$start_of_month_epoch = timelocal(0, 0, 0, 1, $month, $year);
【讨论】:
在这里,我天真地认为 localtime 和 timelocal 是一样的......我傻了!谢谢:) localtime 和 timelocal 是相反的; localtime 将一个纪元整数转换为 6 个(或 9 个)分解字段,而 timelocal 将这 6 个字段转换回一个纪元整数。它们非常适合解决这类问题。【参考方案3】:我遇到的麻烦是,虽然我可以零次,但我担心通过更改日期,星期几将不匹配,因此本质上是一个无效的日期。
mktime(3)
忽略 wday
、yday
和 isdst
字段正是出于这个原因。您可以安全地将 mday
调整为 1,然后再次调用 POSIX::mktime()
将其恢复为纪元值。
my @t = localtime();
$t[0] = $t[1] = $t[2] = 0; # sec/min/hour
$t[3] = 1; # mday
my $epoch_start_of_month = mktime @t;
或者更简单
my $epoch = mktime 0, 0, 0, 1, (localtime)[4,5];
【讨论】:
以上是关于如何从 Perl 中的随机纪元时间戳获取纪元形式的月份开始?的主要内容,如果未能解决你的问题,请参考以下文章
如何从给定城市的给定日期和时间获取 unix 纪元时间戳(以秒为单位)?