Finding date 1 day earlier than a given date!

Discussion in 'Perl Misc' started by Edward, Sep 8, 2004.

  1. Edward

    Edward Guest

    Hi all,

    The below script works fine for all dates (change the value in $time),
    except if the date is the 2nd of the month.

    Given a date of 02/09/04 the script returns the date 32/08/04.

    It's kind of the correct result in terms of number of days/months, but
    should obviously read 01/09/04!

    Anyone know how I can fix it??

    Thanks,

    Edward.


    #!/path/to/perl

    use POSIX;

    $time="01/09/04";
    my ($d, $m, $y) = split ('/', $time);
    my $s = mktime (0, 0, 0, $d - 1, $m - 1, $y - 1900);
    ($d, $m, $y) = (localtime($s - 86400))[3..5];
    $time = sprintf ('%02d/%02d/%04d', $d + 1, $m + 1, $y + 1900);
    print "$time\n";
    Edward, Sep 8, 2004
    #1
    1. Advertising

  2. Edward

    Paul Lalli Guest

    "Edward" <> wrote in message
    news:...
    > The below script works fine for all dates (change the value in $time),
    > except if the date is the 2nd of the month.
    >
    > Given a date of 02/09/04 the script returns the date 32/08/04.


    No it doesn't. As written, it prints nothing at all. Partially because
    you didn't enable warnings, and partially because you gave the time in a
    2-digit format, but told mktime to expect it in a 4-digit format.

    DO NOT RETYPE CODE. Always always always copy and paste what you
    actually have into your post.

    > It's kind of the correct result in terms of number of days/months, but
    > should obviously read 01/09/04!
    >
    > Anyone know how I can fix it??
    > #!/path/to/perl

    use strict;
    use warnings;
    > use POSIX;
    >
    > $time="01/09/04";

    my $time = '01/09/2004';

    > my ($d, $m, $y) = split ('/', $time);
    > my $s = mktime (0, 0, 0, $d - 1, $m - 1, $y - 1900);


    This makes $s a timestamp to represent one day ago. So far so good...

    > ($d, $m, $y) = (localtime($s - 86400))[3..5];


    This subtracts another full day from the time [1]

    > $time = sprintf ('%02d/%02d/%04d', $d + 1, $m + 1, $y + 1900);


    This creates a time one day ahead of $s.

    > print "$time\n";


    So the question becomes - why are you subtracting two days and then
    adding one. Granted, x -2 + 1 is always equal to x - 1, but wouldn't it
    be easier to just subtract the one day and be done with it? This is, of
    course, the cause of the problem you're seeing. You subtract two days
    from Sept 2nd, leaving you with Aug 31, and then you manually add to the
    day count, rather than having the time functions do the day count.

    #!/usr/bin/perl
    use strict;
    use warnings;
    use POSIX;
    my $time="02/09/2004";
    my ($d, $m, $y) = split ('/', $time);
    my $s = mktime (0, 0, 0, $d - 1, $m - 1, $y - 1900);
    ($d, $m, $y) = (localtime($s))[3..5];
    $time = sprintf ('%02d/%02d/%04d', $d, $m + 1, $y + 1900);
    print "$time\n";

    __END__

    I suspect that your problem was in not understanding the $mday parameter
    to mktime() and $mday return value from localtime(). Allow me to
    suggest you reread
    perldoc -f localtime
    and
    perldoc POSIX

    Paul Lalli

    [1] This is generally a bad idea, as not every day consists of exactly
    38400 seconds. Daylight Savings Time must be accounted for. The
    builtins you used account for it, your manual calculation of 60 x 60 x
    24 does not.
    Paul Lalli, Sep 8, 2004
    #2
    1. Advertising

  3. Edward <> wrote:

    > Given a date of 02/09/04 the script returns the date 32/08/04.



    > #!/path/to/perl



    You should always enable warnings when developing Perl code.


    > use POSIX;
    >
    > $time="01/09/04";
    > my ($d, $m, $y) = split ('/', $time);
    > my $s = mktime (0, 0, 0, $d - 1, $m - 1, $y - 1900);

    ^^^^^^^^^
    ^^^^^^^^^ $y + 100


    > ($d, $m, $y) = (localtime($s - 86400))[3..5];
    > $time = sprintf ('%02d/%02d/%04d', $d + 1, $m + 1, $y + 1900);

    ^^^^^^

    The day value from localtime() is not off-by-one.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 8, 2004
    #3
  4. Edward wrote:
    > The below script works fine for all dates (change the value in
    > $time), except if the date is the 2nd of the month.


    No, it does not. It does not work for any date.

    > Anyone know how I can fix it??


    Read the docs for the function you are using and find out which
    arguments it expects. Compare that with what you actually are passing
    to the function.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Sep 8, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gelmir Tinehtelë
    Replies:
    10
    Views:
    674
    Aidan
    Jun 9, 2004
  2. Replies:
    10
    Views:
    896
    Dale King
    May 15, 2006
  3. Replies:
    8
    Views:
    276
  4. Andy
    Replies:
    1
    Views:
    684
  5. Joey Martin
    Replies:
    28
    Views:
    260
    Bob Barrows [MVP]
    Jun 25, 2008
Loading...

Share This Page