views:

948

answers:

2

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

In doing this I find myself taking this quite cumbersome path:

  • man perlfunc
  • /localtime to search for localtime - repeat five times (/ + \n) to reach the relevant section of the manpage
  • Copy the string ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); from the manpage to my script.
  • Try with my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
  • Remember gotcha #1: Must add 1900 to $year to get current year.
  • Try with my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
  • Remember gotcha #2: Must add 1 to $mon to get current month.
  • Try with my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  • Seems ok. Done!

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

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

Where "easy" encompasses both "easy-to-write" and "easy-to-remember".

+19  A: 

Use strftime in the standard POSIX module:

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

The arguments to strftime in Perl's binding were designed to align with the return values from localtime and gmtime.

Greg Bacon
Oh, very nice! Exactly what I was looking for. Excellent!
knorv
You're welcome! Glad to help.
Greg Bacon
Thanks. And in a non-one-liner format:use POSIX;print strftime("%Y-%m-%d %H:%M:%S\n", localtime(time));
Mike
+4  A: 

What not use the DateTime module to do the dirty work for you? It's 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's going on, you can get rid of the temps and save a few lines of code:

use strict;
use warnings;
use DateTime;

my $dt = DateTime->now;
print join $", $dt->ymd, $dt->hms;
Zaid
`$var->method` is *not* interpolated in a string. `"${\$var->method}"` or `"@{[$var->method]}"` if you really want to inline it, but that's ugly. Just write `join $", $dt->ymd, $dt->hms` or something like that.
ephemient
@ephemient: Duly updated. Thanks for the info.
Zaid