53

I'm working on a Perl program at work and stuck on (what I think is) a trivial problem. I simply need to build a string in the format '06/13/2012' (always 10 characters, so 0's for numbers less than 10).

Here's what I have so far:

use Time::localtime;
$tm=localtime;
my ($day,$month,$year)=($tm->mday,$tm->month,$tm->year);
bstpierre
  • 30,042
  • 15
  • 70
  • 103
dvanaria
  • 6,593
  • 22
  • 62
  • 82
  • 12
    If you have any say in the matter, please consider using the unambiguous and sortable ISO 8601 format`YYYY-MM-DD` rather than `MM/DD/YYYY`. – Keith Thompson May 20 '15 at 16:14

7 Answers7

67

You can do it fast, only using one POSIX function. If you have bunch of tasks with dates, see the module DateTime.

use POSIX qw(strftime);

my $date = strftime "%m/%d/%Y", localtime;
print $date;
Pavel Vlasov
  • 3,455
  • 21
  • 21
61

You can use Time::Piece, which shouldn't need installing as it is a core module and has been distributed with Perl 5 since version 10.

use Time::Piece;

my $date = localtime->strftime('%m/%d/%Y');
print $date;

output

06/13/2012


Update

You may prefer to use the dmy method, which takes a single parameter which is the separator to be used between the fields of the result, and avoids having to specify a full date/time format

my $date = localtime->dmy('/');

This produces an identical result to that of my original solution

Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 2
    @lepe: There are three utility "date" functions, `dmy`, `mdy` and `ymd`, and `date` is an alias for `ymd`. All produce dates with the standard hyphen separator by default, and may be passed an alternative separator, so `localtime->ymd` produces `2015-09-28` and *not* `20150928` as you say. This is the big weakness of those methods -- they don't in themselves describe what they do, which is why I chose `strftime('%m/%d/%Y')` – Borodin Sep 28 '15 at 10:28
  • 1
    Standard Perl (v5.10.1) on my server does not have the library... Will stick with POSIX, sorry. – Orabîg Mar 14 '16 at 10:21
  • @BramVanroy: Then you have a non-standard installation of perl. `Time::Piece` was [first incorporated into "experimental" version 9.5](http://search.cpan.org/~dapm/perl-5.14.4/pod/perl595delta.pod#New_Core_Modules) and has never been removed, The first stable release after that would be version 10.0, so if you have a version 10.1 without `Time::Piece` then someone has explicitly removed it from the installation. In any case, the CPAN library is one of Perl's biggest strengths, and it is foolish to restrict oneself to only the core modules. – Borodin Dec 04 '16 at 11:30
  • `This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi` on CentOS. But it's possible that our sysadmin tinkered with it a little, I cannot verify that. – Bram Vanroy Dec 04 '16 at 12:17
  • @BramVanroy: If you download `perl-5.10.1.tar.gz` from [www.cpan.org/src/](http://www.cpan.org/src/) and unpack it, you will see that `Time::Piece` is in the `ext` subfolder at `perl-5.10.1\ext\Time-Piece`. If your sysadmin chose to build perl from scratch, then he would only have to answer *none* to the question *What extensions do you wish to include?* instead of selecting the default, and you would have an installation without most of the core modules. – Borodin Dec 05 '16 at 13:11
  • If you need the date without zero padding, use this format: `%-m/%-d/%Y` (note the **-** after **%**) as explained in the [POSIX documentation](http://search.cpan.org/~dexter/POSIX-strftime-GNU-0.02/lib/POSIX/strftime/GNU.pm). – lepe Mar 17 '17 at 01:52
18
use DateTime qw();
DateTime->now->strftime('%m/%d/%Y')   

expression returns 06/13/2012

daxim
  • 39,270
  • 4
  • 65
  • 132
8

If you like doing things the hard way:

my (undef,undef,undef,$mday,$mon,$year) = localtime;
$year = $year+1900;
$mon += 1;
if (length($mon)  == 1) {$mon = "0$mon";}
if (length($mday) == 1) {$mday = "0$mday";}
my $today = "$mon/$mday/$year";
charlesbridge
  • 1,172
  • 10
  • 21
  • 3
    Ever [since Time::Piece has been in core](http://perlpunks.de/corelist/mversion?module=Time%3A%3APiece), doing it the hard way was not necessary any more. – daxim Jun 13 '12 at 21:14
  • 3
    `Time::Piece` appeared in core in 5.9.5 – JRFerguson Jun 14 '12 at 19:30
  • 3
    There are plenty of sites in production around the world using perl 5.8 vintage 2006. $ `perldoc perlhist | perl -ne 'die "$_\n" if m/5.9.5.*20[01].{8}/'` says that 5.9.5 was released 2007-Jul-07 – MarkHu Oct 08 '13 at 21:59
4

Perl Code for Unix systems:

# Capture date from shell
my $current_date = `date +"%m/%d/%Y"`;

# Remove newline character
$current_date = substr($current_date,0,-1);

print $current_date, "\n";
Christopher Bottoms
  • 11,218
  • 8
  • 50
  • 99
Bharat Pahalwani
  • 1,404
  • 3
  • 25
  • 40
4
use Time::Piece;
...
my $t = localtime;
print $t->mdy("/");# 02/29/2000
dezhik
  • 990
  • 10
  • 16
  • 1
    It seems to be a more convenient example of use case. Unfortunately i can't comment Mr. Borodin's response. – dezhik Jan 22 '15 at 17:06
2

Formating numbers with leading zero is done easily with "sprintf", a built-in function in perl (documentation with: perldoc perlfunc)

use strict;
use warnings;
use Date::Calc qw();
my ($y, $m, $d) = Date::Calc::Today();
my $ddmmyyyy = sprintf '%02d.%02d.%d', $d, $m, $y;
print $ddmmyyyy . "\n";

This gives you:

14.05.2014

horshack
  • 103
  • 1
  • 1
  • 6