perl中的时间计算

时间:2015-01-29 16:00:08

标签: perl

我是perl脚本的新手,我想做一些时间计算。我使用localtime()来获取当前时间。

  my ($sec,$min,$hour,$day,$mon,$year) = localtime(time());
  my ($ysec,$ymin,$yhour,$yday,$ymon) = localtime(time() - 60*60*24);
  my ($wsec,$wmin,$whour,$wday,$wmon,$wyr)  = localtime(time() - 8*60*60*24);

这是我计算当天,昨天和一周后退时间的时间。 但我也想计算一个月和一年的时间。我遵循了类似的模式:

#my ($msec,$mmin,$mhour,$mday,$mmon,$myr)  = localtime(time()-30*60*60*24);
#my ($ysec,$ymin,$yhour,$yday,$ymon,$yyr)  = localtime(time()-365*60*60*24);

但我想知道是否有更好的方法来进行这段时间的计算。有人可以帮助我进行这个月和年的计算吗?你能否建议是否有更好的方法来做这些事情?

4 个答案:

答案 0 :(得分:2)

任何语言的日期和时间计算都非常复杂。需要考虑很多细节,以及许多奇怪的特殊情况(例如夏令时或闰秒)。最好找一个经过充分测试的现成包装来做脏工作。

Perl最好的两个是DateTimeTime::Piece。另一个有用的知识是Date :: Manip;它不太适合一般的编程使用,但是从“2015年1月29日”到“上周六”解析各种草率的用户输入非常方便。

答案 1 :(得分:2)

一个易于使用的访问模块是Time::Piece,它是自Perl版本5.9.5以来的核心。时间数学的常量可以通过Time::Seconds

进行访问
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;   # used for constants ONE_WEEK etc

my $time_now = localtime();
my $time_hour = $time_now - ONE_HOUR;
my $time_month = $time_now - ONE_MONTH;

print "$_\n" for $time_now, $time_hour, $time_month;

输出:

Thu Jan 29 17:20:55 2015
Thu Jan 29 16:20:55 2015
Tue Dec 30 06:51:51 2014

答案 2 :(得分:0)

Perl跟踪时间是从纪元开始的秒数,通常是1970年1月1日.Perl使用内置的C API来获取有关月,日,日期和时间的信息,星期几等等。

内置于Perl的基本命令集是localtimegmtime。这些将返回一组时间元素。具有讽刺意味的是,反向函数不是标准Perl包的一部分。但是,Time::Local模块包含反转功能​​timelocaltimegm。这些采用数组并返回自纪元以来的秒数。

多年来,这是使用这些时间函数的标准工具包。如你所见,它们并不是特别容易使用。编写了数十个时间模块来帮助填补空白。在Perl 5.10中,Time::Piece作为标准Perl模块包含在内,这意味着任何版本为5.10或更高版本的Perl都将包含此模块。将它与Time::Seconds中的常量相结合,您可以轻松地在Perl中计算日期和时间。

这个模块的一个大问题是,它是面向对象的,如果你不熟悉Object Oriented Perl,可能会很难使用它。另一个批评是Time::Seconds做出糟糕的假设,比如一天是24小时。这可能听起来不错且合乎逻辑,直到您意识到由于夏令时,某些日子里有25或23个小时。

但是,它们确实提供了一个易于使用的界面。首先,您需要创建一个Time::Piece 对象,然后在该对象上使用各种方法来获得您想要的内容。将方法视为函数,将对象视为保存信息的东西(例如您正在使用的日期),并且它不是那么糟糕。

要创建Time::Piece 对象,请使用strptime

use Time::Piece;

my $datestring = "Jan 31, 2015 - 12:20pm";
my $timeformat = "%b %e, %Y - %I:%M%p";
my $time_object = Time::Piece->strptime( $datestring, $format );

$timeformat使用百分号后跟一个字母来表示日期的某些方面。您通常可以查看这些内容,查看datestrftime的联机帮助页。创建对象后,您可以执行各种漂亮的技巧:

use Time::Piece;

say "The day of the week is " . $time_object->day;
say "The year is " . $time_object->year;
say "The time in MM/DD/YY is " . $time_object->mdy("/");

您也可以轻松地使用这些计算。

use Time::Piece;
use Time::Seconds;

$time_object + ( 2 * ONE_DAY );
say "The date two days later is " . $time_object->mdy("/");

或者两天之间的差异:

my $time_diff = $time_object - $time_object2;
say "The difference is " . $time_diff->days;

正如我所说的,这是一个面向对象的模块,所以开始Perl程序员的语法有点奇怪(那个->是什么?),如果你不熟悉面向对象的编程,概念可能很难理解。其他模块如Date::Manip很受欢迎,因为它们是功能接口,很多像DateTime这样的人可以处理小数秒并包含更多方法。但是,Time::Piece包含在Perl中,因此您知道您始终可以访问它。

答案 3 :(得分:-1)

您是否考虑过使用DateTime套餐?它包含许多日期操作和计算例程,包括添加日期的功能。

有一个FAQ,带有示例here(特别是,请参阅有关示例计算和DateTime格式的部分)。

这是一个片段:

use strict;
use warnings;

use DateTime;

my $dt = DateTime->now();
print "Now: " . $dt->datetime() . "\n";
print "Now (epoch): " . $dt->epoch() . "\n";

my $two_days_from_now = $dt->add(days => 2);
print "Two days from now: " . $two_days_from_now->datetime() . "\n";
print "Two days from now (epoch): " . $two_days_from_now->epoch() . "\n";

产生以下输出:

Now: 2013-02-23T18:30:58
Now (epoch): 1361644258
Two days from now: 2013-02-25T18:30:58
Two days from now (epoch): 1361817058