快速达到YYYY-mm-dd HH:MM:SS in Perl

时间:2009-11-29 00:01:50

标签: perl datetime formatting timestamp

编写Perl脚本时,我经常发现需要获取当前时间,表示为格式为YYYY-mm-dd HH:MM:SS的字符串(比如2009-11-29 14:28:29)。

在这样做的过程中,我发现自己采取了这条相当繁琐的道路:

  • man perlfunc
  • /localtime搜索本地时间 - 重复五次(/ + \n)以访问联机帮助页的相关部分
  • 将联机帮助页中的字符串($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);复制到我的脚本中。
  • 尝试使用my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
  • 记住问题#1:必须加上1900到$年才能获得当年。
  • 尝试使用my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
  • 记住问题#2:必须将1加到$ mon才能获得当月。
  • 尝试使用my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  • 似乎没问题。完成!

虽然上面概述的过程有效,但远非最佳。我确信有一种更聪明的方式,所以我的问题很简单:

在Perl中获取当前日期/时间YYYY-mm-dd HH:MM:SS的最简单方法是什么?

“简单”包含“易于理解”和“易于记忆”。

9 个答案:

答案 0 :(得分:69)

在标准POSIX模块中使用strftime。 Perl绑定中strftime的参数旨在与localtimegmtime的返回值保持一致。比较

strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)

my          ($sec,$min,$hour,$mday,$mon,$year,$wday,     $yday,     $isdst) = gmtime(time);

命令行使用示例

$ perl -MPOSIX -le 'print strftime "%F %T", localtime $^T'

或来自

中的源文件
use POSIX;

print strftime "%F %T", localtime time;

某些系统不支持%F%T缩写,因此您必须明确

print strftime "%Y-%m-%d %H:%M:%S", localtime time;

print strftime "%Y-%m-%d %H:%M:%S", gmtime time;

请注意,time会在调用时返回当前时间,而$^T将固定为程序启动时的时间。使用gmtime时,返回值是GMT中的当前时间。使用localtime检索您当地时区的时间。

答案 1 :(得分:32)

什么不使用DateTime模块为你做脏工作?写很容易记住!

use strict;
use warnings;
use DateTime;

my $dt   = DateTime->now;   # Stores current date and time as datetime object
my $date = $dt->ymd;   # Retrieves date as a string in 'yyyy-mm-dd' format
my $time = $dt->hms;   # Retrieves time as a string in 'hh:mm:ss' format

my $wanted = "$date $time";   # creates 'yyyy-mm-dd hh:mm:ss' string
print $wanted;

一旦你知道发生了什么,你可以摆脱临时并保存几行代码:

use strict;
use warnings;
use DateTime;

my $dt = DateTime->now;
print join ' ', $dt->ymd, $dt->hms;

答案 2 :(得分:30)

试试这个:

use POSIX qw/strftime/;
print strftime('%Y-%m-%d',localtime);

strftime方法可以为我有效地完成工作。非常简单有效。


答案 3 :(得分:13)

Time::Piece(自Perl 5.10以来的核心)也有一个strftime函数,默认情况下会重载localtime和gmtime来返回Time :: Piece对象:

use Time::Piece;
print localtime->strftime('%Y-%m-%d');

或没有被覆盖的本地时间:

use Time::Piece (); 
print Time::Piece::localtime->strftime('%F %T');

答案 4 :(得分:5)

我做了一点测试(在VM中FreeBSD下的Perl v5.20.1),每个调用以下块1.000.000次:

A

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);

my $now = strftime('%Y%m%d%H%M%S',localtime);

C

my $now = Time::Piece::localtime->strftime('%Y%m%d%H%M%S');

具有以下结果:

A:2秒

B:11秒

C:19秒

这当然不是一个彻底的测试或基准,但至少它对我来说是可重复的,所以即使它更复杂,如果经常需要生成日期时间戳,我更喜欢第一种方法。 / p>

调用(例如,在FreeBSD 10.1下)

my $now = `date "+%Y%m%d%H%M%S" | tr -d "\n"`;

可能不是一个好主意,因为它不依赖于操作系统并且需要相当长的时间。

祝你好运, 霍尔格

答案 5 :(得分:3)

Time::Piece::datetime()可以取消T

use Time::Piece;
print localtime->datetime(T => q{ });

答案 6 :(得分:3)

如果您只想要一个人类可读的时间字符串而不是那种确切的格式:

$t = localtime;
print "$t\n";

打印

Mon Apr 27 10:16:19 2015

或为您的语言环境配置的任何内容。

答案 7 :(得分:1)

简短而甜蜜,无需额外的模块:

my $toDate = `date +%m/%d/%Y" "%l:%M:%S" "%p`;

输出例如是:04/25/2017 9:30:33 AM

答案 8 :(得分:1)

在许多情况下,所需的“当前时间”相当是$ ^ T,它是脚本开始运行的时间,自UNIX时代以来以整秒为单位(假设只有60秒)。

这是为了防止脚本的早期部分使用与脚本的后期部分不同的日期(或夏时制),例如在查询条件和其他派生值中。

对于“当前时间”的变体,可以使用一个常量,也可以证明它是在编译时冻结的:

use constant YMD_HMS_AT_START => POSIX::strftime( "%F %T", localtime $^T );

替代高分辨率启动时间:

0+ [ Time::HiRes::stat("/proc/$$") ]->[10]