in reply to Re: Date Time problem.
in thread Date Time problem.

The general way to do "time math" is to convert to epoch seconds, do math in seconds and then convert back to a string.

Except it doesn't work. Not all days have 24*60*60 seconds.

the OP's idea of adding zero is a GREAT idea.

And POSIX's strftime is the way to do it if you're already dealing with localtime or gmtime (It handles the y+1900 and the m+1 for you.)

use POSIX qw( strftime ); print( strftime('%Y%m%d', localtime), "\n");

Replies are listed 'Best First'.
Re^3: Date Time problem.
by Marshall (Canon) on Sep 05, 2009 at 04:00 UTC
    Dealing with "leap seconds" is a complex thing.
    For leap seconds for awhile see:
    http://en.wikipedia.org/wiki/Leap_second

    For most logging and reporting activities, leap seconds are of no consequence. One "day" is 86,400 seconds (24*60*60) seconds. There may or may not be a "leap second" in a given year. The Op's question was for one day ago.

    No problem with strftime. It "works" albeit slower than other ways.

      As previously mentioned, I don't think leap seconds matter with time. In any case, I'm talking of the days with 23*60*60 seconds and the days with 25*60*60 seconds.

      Previously written example:

      # Set your timezone to America/New_York before running. # In this time zone, DST ends on Nov 2, 2008 at 2:00 AM. # "Sets" the current time to 5 seconds past midnight on Oct 28, 2008. use Time::Local qw( timelocal ); my $time = timelocal(5,0,0,28,10-1,2008); use POSIX; print( strftime( "%m-%d\n", localtime( (24*60*60) * $_ + $time ) ) ) for 1..30;

      Output

      10-29 10-30 10-31 11-01 11-02 \ 11-02 seen twice 11-02 / 11-03 11-04 11-05 11-06 11-07 11-08 11-09 11-10 11-11 11-12 11-13 11-14 11-15 11-16 11-17 11-18 11-19 11-20 11-21 11-22 11-23 11-24 11-25 11-26 > 11-27 never seen

      You don't need any inefficient code to do it right, so you might as well do it right. Sewi showed a way that will probably always work. The following will always work:

      use Time::Local qw( timegm ); use POSIX qw( strftime ); my $date = timegm(localtime); $date += 24*60*60; print(strftime("%Y%m%d\n", gmtime($date)));

      GMT always has 24*60*60 seconds per day. Note the result is still local time.

        When logging times, I use GMT.
        strftime() is an expensive critter in terms of perforance. BUT, expensive is relative and often this does not matter. Use if it you want to. Other ways shown below.
        #!/usr/bin/perl -w use strict; use Time::Local; # Sets the current time to 5 seconds past midnight on Oct 28, 2008. my $start_time = timelocal(5,0,0,28,10-1,2008); my $start_time_string = localtime($start_time); print "Local time=$start_time_string\n"; #Tue Oct 28 00:00:05 2008 foreach my $delta_days (1..35) { my $new_time = $start_time; $new_time = $start_time + ($delta_days*24*60*60); my $new_time_string = gmtime($new_time); print "$new_time_string\n"; } __END__ OUTPUT: Local time=Tue Oct 28 00:00:05 2008 Wed Oct 29 07:00:05 2008 Thu Oct 30 07:00:05 2008 Fri Oct 31 07:00:05 2008 Sat Nov 1 07:00:05 2008 Sun Nov 2 07:00:05 2008 Mon Nov 3 07:00:05 2008 Tue Nov 4 07:00:05 2008 Wed Nov 5 07:00:05 2008 Thu Nov 6 07:00:05 2008 Fri Nov 7 07:00:05 2008 Sat Nov 8 07:00:05 2008 Sun Nov 9 07:00:05 2008 Mon Nov 10 07:00:05 2008 Tue Nov 11 07:00:05 2008 Wed Nov 12 07:00:05 2008 Thu Nov 13 07:00:05 2008 Fri Nov 14 07:00:05 2008 Sat Nov 15 07:00:05 2008 Sun Nov 16 07:00:05 2008 Mon Nov 17 07:00:05 2008 Tue Nov 18 07:00:05 2008 Wed Nov 19 07:00:05 2008 Thu Nov 20 07:00:05 2008 Fri Nov 21 07:00:05 2008 Sat Nov 22 07:00:05 2008 Sun Nov 23 07:00:05 2008 Mon Nov 24 07:00:05 2008 Tue Nov 25 07:00:05 2008 Wed Nov 26 07:00:05 2008 Thu Nov 27 07:00:05 2008 Fri Nov 28 07:00:05 2008 Sat Nov 29 07:00:05 2008 Sun Nov 30 07:00:05 2008 Mon Dec 1 07:00:05 2008 Tue Dec 2 07:00:05 2008