# how many days ago is 2003-07-20 ?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
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

## Re: how many days ago is 2003-07-20 ?

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.

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> 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

## Re: how many days ago is 2003-07-20 ?

Anno Siegel 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)-(\d)-(\d)\$/
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?

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> Anno Siegel 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)-(\d)-(\d)\$/
>            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

## Re: how many days ago is 2003-07-20 ?

Anno Siegel wrote:
>> Anno Siegel wrote:
>>> Do you have a simple, water-tight solution using only
>>> Time::Local?
>>
>> Think so.
>>
>>     sub daysago {
>>         shift =~ /^(\d)-(\d)-(\d)\$/
>>           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. :(

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> Anno Siegel wrote:
> >> Anno Siegel wrote:
> >>> Do you have a simple, water-tight solution using only
> >>> Time::Local?
> >>
> >> Think so.
> >>
> >>     sub daysago {
> >>         shift =~ /^(\d)-(\d)-(\d)\$/
> >>           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

Anno

## Re: how many days ago is 2003-07-20 ?

> Anno Siegel wrote:
> >> Anno Siegel wrote:
> >>> Do you have a simple, water-tight solution using only
> >>> Time::Local?
> >>
> >> Think so.
> >>
> >>     sub daysago {
> >>         shift =~ /^(\d)-(\d)-(\d)\$/
> >>           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

Anno

## Re: how many days ago is 2003-07-20 ?

Anno Siegel wrote:
>> Anno Siegel wrote:
>>>> Anno Siegel wrote:
>>>>>
>>>>
>>>>     sub daysago {
>>>>         shift =~ /^(\d)-(\d)-(\d)\$/
>>>>           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?

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> Anno Siegel wrote:
> >> Anno Siegel wrote:
> >>>> Anno Siegel wrote:
> >>>>>
> >>>>
> >>>>     sub daysago {
> >>>>         shift =~ /^(\d)-(\d)-(\d)\$/
> >>>>           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

## Re: how many days ago is 2003-07-20 ?

Anno Siegel 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)-(\d)-(\d)\$/
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";

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.

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> Anno Siegel 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)-(\d)-(\d)\$/
>            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";
>
> 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

## Re: how many days ago is 2003-07-20 ?

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.

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: how many days ago is 2003-07-20 ?

> 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.

## Re: how many days ago is 2003-07-20 ?

>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