如何从 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) 忽略 wdayydayisdst 字段正是出于这个原因。您可以安全地将 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 中的随机纪元时间戳获取纪元形式的月份开始?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 postgres 获取时间戳作为 Unix 纪元?

如何从给定城市的给定日期和时间获取 unix 纪元时间戳(以秒为单位)?

将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本

从 Postgres 中的纪元列表中获取特定时间段

获取表示当前日期的纪元时间戳范围

如何使用 Perl 找到今天(本地时区)的最小纪元时间?