how many days ago is 2003-07-20 ?

Discussion in 'Perl Misc' started by Marcus, Aug 28, 2004.

  1. Marcus

    Marcus Guest

    Can someone pls show the most solid way in perl to retrieve the number
    of days ago a specific date string was?

    Input: 2003-07-20
    Output: 395

    Thanks
    M
     
    Marcus, Aug 28, 2004
    #1
    1. Advertising

  2. Marcus wrote:
    > Can someone pls show the most solid way in perl to retrieve the
    > number of days ago a specific date string was?
    >
    > Input: 2003-07-20
    > Output: 395


    What have you tried? Personally I'd probably use Time::Local, which
    would require a couple of extra lines of code, while others would use
    e.g. Date::Calc.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 28, 2004
    #2
    1. Advertising

  3. In comp.lang.perl.misc on 27 Aug 2004 16:35:04 -0700
    Marcus <> wrote:
    > Can someone pls show the most solid way in perl to retrieve the number
    > of days ago a specific date string was?
    >
    > Input: 2003-07-20
    > Output: 395
    >


    Date::Manip is one way.

    4. The amount of time between two dates.

    $date1=&ParseDate($string1);
    $date2=&ParseDate($string2);
    $delta=&DateCalc($date1,$date2,\$err);
    => 0:0:WK:DD:HH:MM:SS the weeks, days, hours, minutes,
    and seconds between the two
    $delta=&DateCalc($date1,$date2,\$err,1);
    => YY:MM:WK:DD:HH:MM:SS the years, months, etc. between
    the two

    There are other Date modules, that's just the one I've been using
    because I handle dates in all sorts of weird formats and do all sorts of
    weird thigns with them, it handles everything so far.

    Zebee
     
    Zebee Johnstone, Aug 28, 2004
    #3
  4. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Marcus wrote:
    > > Can someone pls show the most solid way in perl to retrieve the
    > > number of days ago a specific date string was?
    > >
    > > Input: 2003-07-20
    > > Output: 395

    >
    > What have you tried? Personally I'd probably use Time::Local, which
    > would require a couple of extra lines of code, while others would use
    > e.g. Date::Calc.


    Do you have a simple, water-tight solution using only Time::Local?
    Note that in the presence of DST a day may have more or less than 24
    hours.

    Anno
     
    Anno Siegel, Aug 28, 2004
    #4
  5. Anno Siegel wrote:
    > Gunnar Hjalmarsson wrote:
    >> Marcus wrote:
    >>> Can someone pls show the most solid way in perl to retrieve the
    >>> number of days ago a specific date string was?
    >>>
    >>> Input: 2003-07-20 Output: 395

    >>
    >> What have you tried? Personally I'd probably use Time::Local,
    >> which would require a couple of extra lines of code, while others
    >> would use e.g. Date::Calc.

    >
    > Do you have a simple, water-tight solution using only Time::Local?


    Think so.

    sub daysago {
    shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    or die "Invalid date format";
    require Time::Local;
    import Time::Local 'timelocal';
    my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    - timelocal(0,0,0,$3,$2-1,$1-1900);
    $diff >= 0 or die "Future date not allowed";
    sprintf '%.0f', $diff / 86400
    }

    print daysago('2003-07-20'), "\n";

    > Note that in the presence of DST a day may have more or less than
    > 24 hours.


    Doesn't the above sub take care of that?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 28, 2004
    #5
  6. Marcus

    Marcus Guest

    Brilliant. Both solutions works really well. Thanks

    Zebee Johnstone <> wrote in message news:<>...
    > In comp.lang.perl.misc on 27 Aug 2004 16:35:04 -0700
    > Marcus <> wrote:
    > > Can someone pls show the most solid way in perl to retrieve the number
    > > of days ago a specific date string was?
    > >
    > > Input: 2003-07-20
    > > Output: 395
    > >

    >
    > Date::Manip is one way.
    >
    > 4. The amount of time between two dates.
    >
    > $date1=&ParseDate($string1);
    > $date2=&ParseDate($string2);
    > $delta=&DateCalc($date1,$date2,\$err);
    > => 0:0:WK:DD:HH:MM:SS the weeks, days, hours, minutes,
    > and seconds between the two
    > $delta=&DateCalc($date1,$date2,\$err,1);
    > => YY:MM:WK:DD:HH:MM:SS the years, months, etc. between
    > the two
    >
    > There are other Date modules, that's just the one I've been using
    > because I handle dates in all sorts of weird formats and do all sorts of
    > weird thigns with them, it handles everything so far.
    >
    > Zebee
     
    Marcus, Aug 29, 2004
    #6
  7. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Marcus wrote:
    > >>> Can someone pls show the most solid way in perl to retrieve the
    > >>> number of days ago a specific date string was?
    > >>>
    > >>> Input: 2003-07-20 Output: 395
    > >>
    > >> What have you tried? Personally I'd probably use Time::Local,
    > >> which would require a couple of extra lines of code, while others
    > >> would use e.g. Date::Calc.

    > >
    > > Do you have a simple, water-tight solution using only Time::Local?

    >
    > Think so.
    >
    > sub daysago {
    > shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    > or die "Invalid date format";
    > require Time::Local;
    > import Time::Local 'timelocal';
    > my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    > - timelocal(0,0,0,$3,$2-1,$1-1900);
    > $diff >= 0 or die "Future date not allowed";
    > sprintf '%.0f', $diff / 86400
    > }
    >
    > print daysago('2003-07-20'), "\n";
    >
    > > Note that in the presence of DST a day may have more or less than
    > > 24 hours.

    >
    > Doesn't the above sub take care of that?


    I don't know, but it is only obviously correct if the interval between
    the two times is a multiple of 24 hours. Since that isn't always so,
    I'd prefer a solution that has been checked for these cases instead of
    checking myself.

    Anno
     
    Anno Siegel, Aug 29, 2004
    #7
  8. Anno Siegel wrote:
    > Gunnar Hjalmarsson wrote:
    >> Anno Siegel wrote:
    >>> Do you have a simple, water-tight solution using only
    >>> Time::Local?

    >>
    >> Think so.
    >>
    >> sub daysago {
    >> shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    >> or die "Invalid date format";
    >> require Time::Local;
    >> import Time::Local 'timelocal';
    >> my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    >> - timelocal(0,0,0,$3,$2-1,$1-1900);
    >> $diff >= 0 or die "Future date not allowed";
    >> sprintf '%.0f', $diff / 86400
    >> }
    >>
    >> print daysago('2003-07-20'), "\n";
    >>
    >>> Note that in the presence of DST a day may have more or less
    >>> than 24 hours.

    >>
    >> Doesn't the above sub take care of that?

    >
    > I don't know, but it is only obviously correct if the interval
    > between the two times is a multiple of 24 hours.


    Hey, how is your math? ;-) We know it may differ 1/24 day, and since
    that it far less than 1/2, to me it's pretty obvious that sprintf()
    makes it return the correct number of days.

    > Since that isn't always so, I'd prefer a solution that has been
    > checked for these cases instead of checking myself.


    Sometimes I feel that there is something religious about the faith in
    using oversized modules. :(

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 29, 2004
    #8
  9. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Anno Siegel wrote:
    > >>> Do you have a simple, water-tight solution using only
    > >>> Time::Local?
    > >>
    > >> Think so.
    > >>
    > >> sub daysago {
    > >> shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    > >> or die "Invalid date format";
    > >> require Time::Local;
    > >> import Time::Local 'timelocal';
    > >> my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    > >> - timelocal(0,0,0,$3,$2-1,$1-1900);
    > >> $diff >= 0 or die "Future date not allowed";
    > >> sprintf '%.0f', $diff / 86400
    > >> }
    > >>
    > >> print daysago('2003-07-20'), "\n";
    > >>
    > >>> Note that in the presence of DST a day may have more or less
    > >>> than 24 hours.
    > >>
    > >> Doesn't the above sub take care of that?

    > >
    > > I don't know, but it is only obviously correct if the interval
    > > between the two times is a multiple of 24 hours.

    >
    > Hey, how is your math? ;-) We know it may differ 1/24 day, and since
    > that it far less than 1/2, to me it's pretty obvious that sprintf()
    > makes it return the correct number of days.


    Then there's the problem of non-existent and ambiguous times that
    comes with DST.

    > > Since that isn't always so, I'd prefer a solution that has been
    > > checked for these cases instead of checking myself.

    >
    > Sometimes I feel that there is something religious about the faith in
    > using oversized modules. :(


    There is a well-founded preference for peer-reviewed solutions over
    ad-hoc ones.

    Anno
     
    Anno Siegel, Aug 29, 2004
    #9
  10. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Anno Siegel wrote:
    > >>> Do you have a simple, water-tight solution using only
    > >>> Time::Local?
    > >>
    > >> Think so.
    > >>
    > >> sub daysago {
    > >> shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    > >> or die "Invalid date format";
    > >> require Time::Local;
    > >> import Time::Local 'timelocal';
    > >> my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    > >> - timelocal(0,0,0,$3,$2-1,$1-1900);
    > >> $diff >= 0 or die "Future date not allowed";
    > >> sprintf '%.0f', $diff / 86400
    > >> }
    > >>
    > >> print daysago('2003-07-20'), "\n";
    > >>
    > >>> Note that in the presence of DST a day may have more or less
    > >>> than 24 hours.
    > >>
    > >> Doesn't the above sub take care of that?

    > >
    > > I don't know, but it is only obviously correct if the interval
    > > between the two times is a multiple of 24 hours.

    >
    > Hey, how is your math? ;-) We know it may differ 1/24 day, and since
    > that it far less than 1/2, to me it's pretty obvious that sprintf()
    > makes it return the correct number of days.


    ....supposing that the rounded number is indeed what is wanted in
    this case. It may differ from the number of complete calendar days
    between the dates.

    Then there's the problem of non-existent and ambiguous times that
    comes with DST.

    > > Since that isn't always so, I'd prefer a solution that has been
    > > checked for these cases instead of checking myself.

    >
    > Sometimes I feel that there is something religious about the faith in
    > using oversized modules. :(


    There is a well-founded preference for peer-reviewed solutions over
    ad-hoc ones.

    Anno
     
    Anno Siegel, Aug 29, 2004
    #10
  11. Anno Siegel wrote:
    > Gunnar Hjalmarsson wrote:
    >> Anno Siegel wrote:
    >>> Gunnar Hjalmarsson wrote:
    >>>> Anno Siegel wrote:
    >>>>>
    >>>>
    >>>> sub daysago {
    >>>> shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    >>>> or die "Invalid date format";
    >>>> require Time::Local;
    >>>> import Time::Local 'timelocal';
    >>>> my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    >>>> - timelocal(0,0,0,$3,$2-1,$1-1900);
    >>>> $diff >= 0 or die "Future date not allowed";
    >>>> sprintf '%.0f', $diff / 86400
    >>>> }
    >>>>
    >>>> print daysago('2003-07-20'), "\n";
    >>>>
    >>>>> Note that in the presence of DST a day may have more or
    >>>>> less than 24 hours.
    >>>>
    >>>> Doesn't the above sub take care of that?
    >>>
    >>> I don't know, but it is only obviously correct if the interval
    >>> between the two times is a multiple of 24 hours.

    >>
    >> Hey, how is your math? ;-) We know it may differ 1/24 day, and
    >> since that it far less than 1/2, to me it's pretty obvious that
    >> sprintf() makes it return the correct number of days.

    >
    > ...supposing that the rounded number is indeed what is wanted in
    > this case. It may differ from the number of complete calendar days
    > between the dates.


    I have absolutely no idea what you are refering to here, Anno. Did you
    see that the code disregards the first three elements that localtime()
    returns? Could you possibly give an example when the function would
    return anything else but the number of complete calendar days since
    the date that is passed to it?

    > Then there's the problem of non-existent and ambiguous times that
    > comes with DST.


    What's the nature of that problem?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 29, 2004
    #11
  12. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Anno Siegel wrote:
    > >>> Gunnar Hjalmarsson wrote:
    > >>>> Anno Siegel wrote:
    > >>>>>
    > >>>>
    > >>>> sub daysago {
    > >>>> shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    > >>>> or die "Invalid date format";
    > >>>> require Time::Local;
    > >>>> import Time::Local 'timelocal';
    > >>>> my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    > >>>> - timelocal(0,0,0,$3,$2-1,$1-1900);
    > >>>> $diff >= 0 or die "Future date not allowed";
    > >>>> sprintf '%.0f', $diff / 86400
    > >>>> }
    > >>>>
    > >>>> print daysago('2003-07-20'), "\n";
    > >>>>
    > >>>>> Note that in the presence of DST a day may have more or
    > >>>>> less than 24 hours.
    > >>>>
    > >>>> Doesn't the above sub take care of that?
    > >>>
    > >>> I don't know, but it is only obviously correct if the interval
    > >>> between the two times is a multiple of 24 hours.
    > >>
    > >> Hey, how is your math? ;-) We know it may differ 1/24 day, and
    > >> since that it far less than 1/2, to me it's pretty obvious that
    > >> sprintf() makes it return the correct number of days.

    > >
    > > ...supposing that the rounded number is indeed what is wanted in
    > > this case. It may differ from the number of complete calendar days
    > > between the dates.

    >
    > I have absolutely no idea what you are refering to here, Anno. Did you
    > see that the code disregards the first three elements that localtime()
    > returns? Could you possibly give an example when the function would
    > return anything else but the number of complete calendar days since
    > the date that is passed to it?


    I don't remember saying it doesn't. It would be your job to prove
    that it does, and (a lot harder) to describe the conditions under
    which it does. Only the latter is relevant to my point.

    My point is that the seemingly clear notion of the number of days
    between two calendar dates must be re-defined in view of the fact
    that two midnights aren't necessarily a multiple of 24 hours apart.
    You assume that rounding is the answer, but other answers could be
    given, which might differ by one under various circumstances.

    At this point I might decide to use a module that (presumably)
    has come up with a solution that is both consistent in itself
    and with intuitive notions, and which is reasonably general
    with respect to local DST variations.

    > > Then there's the problem of non-existent and ambiguous times that
    > > comes with DST.

    >
    > What's the nature of that problem?


    Some valid time specifications don't correspond to a point in time
    (when a calendar hour has been jumped over), and others correspond
    to two (when a calendar hour has been repeated). Granted, DST
    regulations don't do that around midnight, but that is a restriction
    in the validity of the algorithm, or it must be taken into account
    anyway.

    Anno
     
    Anno Siegel, Aug 29, 2004
    #12
  13. Anno Siegel wrote:
    > Gunnar Hjalmarsson wrote:
    >> Could you possibly give an example when the function would return
    >> anything else but the number of complete calendar days since the
    >> date that is passed to it?

    >
    > I don't remember saying it doesn't. It would be your job to prove
    > that it does, and (a lot harder) to describe the conditions under
    > which it does.


    My "job"? You asked if I have "a simple, water-tight solution" using
    only Time::Local, and I posted this code, which I claim is just that:

    sub daysago {
    shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    or die "Invalid date format";
    require Time::Local;
    import Time::Local 'timelocal';
    my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    - timelocal(0,0,0,$3,$2-1,$1-1900);
    $diff >= 0 or die "Future date not allowed";
    sprintf '%.0f', $diff / 86400
    }

    print daysago('2003-07-20'), "\n";

    It addresses the trivial task the OP asked for help with: Calculating
    the number of days since a certain date.

    > My point is that the seemingly clear notion of the number of days
    > between two calendar dates must be re-defined in view of the fact
    > that two midnights aren't necessarily a multiple of 24 hours apart.


    Re-defined? Out from which definition? And why?

    The function computes the number of seconds between 00:00:00 at the
    comparison date and 00:00:00 at today's date. Switching to or from DST
    may result in that number being 3600 seconds less or more than a
    multiple of 86400, but such a switch can never affect the full number
    of calendar days after rounding by sprintf().

    > You assume that rounding is the answer, but other answers could be
    > given, which might differ by one under various circumstances.


    Which answers would that be? Note that we are talking about comparing
    dates. Time of the day is not an input, and should obviously not
    affect the result.

    > At this point I might decide to use a module that (presumably) has
    > come up with a solution that is both consistent in itself and with
    > intuitive notions, and which is reasonably general with respect to
    > local DST variations.


    Nothing wrong with doing so, of course. Personally I think twice
    before using a non-standard module, since I usually work with programs
    that are intended for distribution, and non-standard modules
    complicates the distribution.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 30, 2004
    #13
  14. Marcus

    Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Could you possibly give an example when the function would return
    > >> anything else but the number of complete calendar days since the
    > >> date that is passed to it?

    > >
    > > I don't remember saying it doesn't. It would be your job to prove
    > > that it does, and (a lot harder) to describe the conditions under
    > > which it does.

    >
    > My "job"? You asked if I have "a simple, water-tight solution" using
    > only Time::Local, and I posted this code, which I claim is just that:


    Quite. It's your algorithm and your claim.

    > sub daysago {
    > shift =~ /^(\d{4})-(\d{2})-(\d{2})$/
    > or die "Invalid date format";
    > require Time::Local;
    > import Time::Local 'timelocal';
    > my $diff = timelocal(0,0,0,(localtime $^T)[3..5])
    > - timelocal(0,0,0,$3,$2-1,$1-1900);
    > $diff >= 0 or die "Future date not allowed";
    > sprintf '%.0f', $diff / 86400
    > }
    >
    > print daysago('2003-07-20'), "\n";
    >
    > It addresses the trivial task the OP asked for help with: Calculating
    > the number of days since a certain date.
    >
    > > My point is that the seemingly clear notion of the number of days
    > > between two calendar dates must be re-defined in view of the fact
    > > that two midnights aren't necessarily a multiple of 24 hours apart.

    >
    > Re-defined? Out from which definition? And why?


    To calculate the number of cars in a train from its length, you divide
    the length by the length of each car. That's fine as long as all
    cars have the same length. Now DST comes along and introduces non-
    standard long and short cars. For an arbitrary mixture of cars, the
    method breaks down now. What saves it (with the introduction of
    rounding) is the fact that DST introduces its non-standard cars in
    particular ways. It would be necessary to describe exactly what
    DST may do and what not (and to make sure that all local implementations
    of DST comply) to establish the validity of the method. That is not
    trivial.

    Anno
     
    Anno Siegel, Aug 30, 2004
    #14
  15. Anno Siegel wrote:
    > It would be necessary to describe exactly what DST may do and what
    > not (and to make sure that all local implementations of DST comply)
    > to establish the validity of the method. That is not trivial.


    Can you point me to the corresponding descriptions for Date::Calc and
    Date::Manip?

    I can't understand why you are trying to turn this trivial task into
    rocket science. You are reasoning as if it was a general purpose
    date/time module or a calendar app.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 30, 2004
    #15
  16. Gunnar Hjalmarsson <> writes:
    > Anno Siegel wrote:
    >> It would be necessary to describe exactly what DST may do and what
    >> not (and to make sure that all local implementations of DST comply)
    >> to establish the validity of the method. That is not trivial.

    >
    > Can you point me to the corresponding descriptions for Date::Calc and
    > Date::Manip?


    Frankly, I like using Date::Calc because it's trivially obvious what
    it does, and I don't have to work out whether some yobbo on the
    Internet wrote a date-diff function properly or not. :) The fact that
    it does all sorts of other things, including diffs between date/time
    pairs, is a nice bonus.

    > I can't understand why you are trying to turn this trivial task into
    > rocket science. You are reasoning as if it was a general purpose
    > date/time module or a calendar app.


    You're right, there's no reason I *couldn't* write such a function (or
    just use yours) but I have absolutely no motivation to, given that
    Date::Calc exists, and is relatively fast and easy to use.

    -Eric
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
     
    Eric Schwartz, Aug 30, 2004
    #16
  17. Marcus

    M.J.T. Guy Guest

    Anno Siegel <-berlin.de> wrote:
    >Do you have a simple, water-tight solution using only Time::Local?
    >Note that in the presence of DST a day may have more or less than 24
    >hours.


    Easy - always do your calculations in GMT. Then DST issues never arise.


    Mike Guy
     
    M.J.T. Guy, Sep 8, 2004
    #17
    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. Carl Prothman [MVP]

    Re: format dateTime '06/08/2003 12:00' to '1 day ago'

    Carl Prothman [MVP], Aug 7, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    4,809
    Cindy Meister -WordMVP-
    Aug 16, 2003
  2. Dan Ignatov
    Replies:
    0
    Views:
    1,429
    Dan Ignatov
    Aug 11, 2003
  3. Alex Hunsley
    Replies:
    6
    Views:
    474
    opalinski from opalpaweb
    Mar 28, 2006
  4. Replies:
    5
    Views:
    468
    Bo Yang
    Nov 2, 2006
  5. joe shaboo

    calculate date 4 days ago

    joe shaboo, May 4, 2004, in forum: Perl Misc
    Replies:
    10
    Views:
    303
    Jim Cochrane
    May 5, 2004
Loading...

Share This Page