Quickly get to YYYY-mm-dd HH: MM: SS to Pearl

When writing Perl scripts, I often find it necessary to get the current time, represented as a string formatted as YYYY-mm-dd HH:MM:SS (say 2009-11-29 14:28:29 ).

However, I find myself in this rather cumbersome way:

  • man perlfunc
  • /localtime to search for local time - repeat five times ( / + \n ) to go to the corresponding section manpage
  • Copy the line ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); from the man page to my script.
  • Try my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
  • Remember that gotcha # 1: you need to add from 1900 to $ year to get the current year.
  • Try my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
  • Remember that gotcha # 2: you need to add from 1 to $ mon to get the current month.
  • Try my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  • Everything seems to be in order. Done!

While the process described above works, it is far from optimal. I'm sure there is a smarter way, so my question is simple:

What is the easiest way to get YYYY-mm-dd HH:MM:SS current date / time in Perl?

Where “easy” encompasses both “easy-to-write” and “easy-to-remember”.

+60
datetime timestamp formatting perl
Nov 29 '09 at 0:01
source share
9 answers

Use strftime in the standard POSIX module. The strftime arguments in the Perls binding were designed to align with return values ​​from localtime and gmtime . compare

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

from

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

Command line example

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

or from the source file, as in

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

Some systems do not support the abbreviations %F and %T , so you will have to explicitly specify

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

or

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

Note that time returns the current time when called, while $^T is committed at the time your program starts. With gmtime return value is the current time in GMT. Get time in your time zone with localtime .

+69
Nov 29 '09 at 0:05
source share

What does the DateTime module not use to do the dirty work? Easy to write and remember!

 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; 

Once you know what is going on, you can get rid of the pace and save a few lines of code:

 use strict; use warnings; use DateTime; my $dt = DateTime->now; print join ' ', $dt->ymd, $dt->hms; 
+32
Nov 29 '09 at 8:07
source share

Try the following:

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

The strftime method does the job efficiently for me. Very simple and efficient.




+30
Oct 16 '12 at 5:10
source share

Time :: Piece (in the kernel since Perl 5.10) also has a strftime function and by default overloads localtime and gmtime to return Time :: Piece objects:

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

or without redefined local time:

 use Time::Piece (); print Time::Piece::localtime->strftime('%F %T'); 
+13
Oct 16 '12 at 10:28
source share

I did a small test (Perl v5.20.1 under FreeBSD in VM) that calls the following blocks: 1,000,000 times each:

BUT

 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); 

AT

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

FROM

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

with the following results:

A: 2 seconds

B: 11 seconds

C: 19 seconds

This, of course, is not a thorough test or benchmark, but at least it reproduces for me, so although it is more complicated, I would prefer the first method if generating a datetimestamp is required very often.

Call (for example, under FreeBSD 10.1)

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

may not be such a good idea, because it is OS independent and takes a lot of time.

Regards, Holger

+5
Sep 22 '15 at 8:51
source share

Time::Piece::datetime() can eliminate T

 use Time::Piece; print localtime->datetime(T => q{ }); 
+3
Feb 05 '14 at 15:31
source share

if you just want a human-readable time string and not the exact format:

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

prints

 Mon Apr 27 10:16:19 2015 

or whatever is configured for your locale.

+3
Apr 27 '15 at 9:19
source share

Short and sweet, no additional modules required:

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

The result, for example, will be: 04/25/2012 9:30:33 AM

+1
Apr 25 '17 at 13:36 on
source share

In many cases, the required "current time" is rather $ ^ T, that is, the time at which the script started working, in whole seconds (assuming only 60 seconds), starting from the UNIX era.

This prevents the use of a different date (or daylight saving time) in the early part of the script than in the later part of the script, for example, in query conditions and other derived values.

For this "current time" option, you can use a constant, and also document that it was frozen at compile time: use constant YMD_HMS_AT_START => POSIX::strftime( "%F %T", localtime $^T );

Alternative start time with higher resolution: 0+ [ Time::HiRes::stat("/proc/$$") ]->[10]

0
Jun 08 '19 at 11:37
source share



All Articles