aennen has asked for the wisdom of the Perl Monks concerning the following question:

Been all over the web some books and just can't seem to get a clear answer on how to do the following. Current Day - 1 day Want to do this and not have to worry about month and year boundries. Thought I could use time() and get number of seconds then subtract one days worth of seconds. I can get the seconds but I can't seem to convert the new value back to a date string. (note I don't have POSIX module) perldocs says the return of time is suitable for locatime but I am finding this not to be the case.

Replies are listed 'Best First'.
•Re: Simple date calc
by merlyn (Sage) on Dec 19, 2002 at 16:49 UTC

    Simple version

    Since time is the current moment in time, as a Unix Epoch second value, just subtract 86400 from that, and use localtime in a scalar context to make a date string:
    my $yesterday = localtime (time - 86400);
    You can extract month/day/year from that string, or use the more general list context version and do the processing yourself:
    my @yesterday_values = localtime(time - 86400);

    More precise version

    Those versions suffer from the "daylight savings time" switch, and so it fails once or twice a year when a day has 25 hours or 23 hours in it. To get around that, aim for something "mid-day" yesterday, since you don't care about the specific time:
    my $current_hour = (localtime)[2]; my $yesterday_around_noon = localtime(time - ($current_hour + 12) * 36 +00);
    This works by getting us back to roughly midnight today, then going back another 12 hours. Even if the day is 23 or 25 hours, this'll still be within the mid-day span.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Ahhh what I just found interesting is that if I inlcude Time::localtime i get
      Time::tm=ARRAY(0x400978cc)
      in the interpolation of the array. Code ::
      use Time::localtime; $offset = time(); @yesterday_values = localtime($offset); print "@yesterday_values\n"
Re: Simple date calc
by thewalledcity (Friar) on Dec 19, 2002 at 16:45 UTC
    I take it you mean that you want to be able to get yesterdays date w/o having to worry about today being Jan 1, 2000 (for example). You might want to check out Date::Calc. It is pretty easy to use and provides lots of functionality including what you are looking for.
      Yep that's what I needed, thanks, just have to look in the right places
Re: Simple date calc
by mojotoad (Monsignor) on Dec 19, 2002 at 19:29 UTC
    Try Date::Manip:

    use Date::Manip; print "One day ago was: ", DateCalc('today', '- 1 day'), "\n";

    A lot of people will carp and moan about it being slower than other date modules, and this is true. However, 99% of the time date calculations do not end up being the bottleneck in a program. For me the flexibility of the module is worth it.

    Matt

Re: Simple date calc
by Ovid (Cardinal) on Dec 19, 2002 at 16:38 UTC

    aennen: I have read your question several times, but I can't figure out what you are trying to do. Your question appears to be in the line "Current Day - 1 day Want to do this and not have to worry about month and year boundries." While I don't think you intended it, that line is not a complete sentence.

    We may be able to help you if you can give some concrete examples of what you are trying to do, perhaps with some code snippets to illustrate your attempts.

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: Simple date calc
by pfaut (Priest) on Dec 19, 2002 at 16:38 UTC

    It sounds like you're on the right track. It would be easier to help you if you could post any code that you've already tried.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
Re: Simple date calc
by aennen (Acolyte) on Dec 19, 2002 at 16:46 UTC
    Ok here is a simple example of part of what I am trying to do
    #!/usr/local/bin/perl use Getopt::Std; use Time::Local; use Time::localtime; $offset = time(); @seg = localtime($offset); print "--$offset--$seg--@seg--\n\n";

      This is misbehaving (in the sense of not doing what you want; in the strictly technical sense, it's behaving perfectly), because you're assigning localtime to an array. When you do this, you get a nine element array with the following components: ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)

      On the other hand, if you assigned it to a scalar, then you'd get a printable string:

      $yesterday=localtime(time()-86400); print $yesterday;
      Wed Dec 18 16:58:19 2002

      --
      Tommy
      Too stupid to live.
      Too stubborn to die.