编写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);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
虽然上面概述的过程有效,但远非最佳。我确信有一种更聪明的方式,所以我的问题很简单:
在Perl中获取当前日期/时间YYYY-mm-dd HH:MM:SS
的最简单方法是什么?
“简单”包含“易于理解”和“易于记忆”。
答案 0 :(得分:69)
在标准POSIX
模块中使用strftime
。 Perl绑定中strftime
的参数旨在与localtime
和gmtime
的返回值保持一致。比较
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]