Number of days since 1/1/2000 - Page 3

•  Subject
• Author
• Posted on

Re: Number of days since 1/1/2000

On Feb 18, 2:20 pm, oprah.cho...@gmail.com wrote:

The time on 1/1/2000 is unlikely to change.  You don't need to
recalculate it.  Just set it as a constant in your program
and you don't need any modules.  Not many people recalculate
PI from a series expansion every time they use it.

use constant Y2000 =>  946702800;
use constant Y2038 => 2145934800;

sub calc_days {
my \$diff = time;
warn "Is this still right?" if \$diff > Y2038;
\$diff -= Y2000;
int(\$diff / 86400);
}

print calc_days(),"\n";

2971

Re: Number of days since 1/1/2000

smallpond wrote:

In the code below I make use of a constant SUMMERNIGHT which contains
what time() will return 15 minutes after midnight at June, 20.

C:\home>type test.pl
use Time::Local;
use constant Y2000       =>  946702800;
use constant Y2038       => 2145934800;
use constant SUMMERNIGHT => 1213913700;

sub calc_days1 {  # smallpond's code
my \$diff = SUMMERNIGHT;
warn "Is this still right?" if \$diff > Y2038;
\$diff -= Y2000;
int(\$diff / 86400);
}

sub calc_days2 {  # Gunnar's code
my \$start = timelocal 0, 0, 0, 1, 0, 2000;
my \$today = timelocal 0, 0, 0, (localtime SUMMERNIGHT)[3..5];
sprintf '%.0f', (\$today - \$start) / 86400;
}

print 'calc_days1: ', calc_days1(), "\n",
'calc_days2: ', calc_days2(), "\n";

C:\home>test.pl
calc_days1: 3092
calc_days2: 3093

Oops!!

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

Re: Number of days since 1/1/2000

oops indeed.  I get 3092 for both.  Perhaps you should
investigate DST in your two conversions to see which is
correct.  I'm pretty sure that Unix clock seconds are
fairly constant.

Re: Number of days since 1/1/2000

smallpond wrote:

The reason why you get the same result is that the SUMMERNIGHT constant
was based on the CET timezone, while you seem to be running the code in
the EST zone. (This illustrates that static time related constants make
the code non-portable.)

If you set the constants like this, the different number of days will
probably appear when you run the code too:

use constant Y2000       => timelocal 0,0,0,1,0,2000;
use constant Y2038       => timelocal 0,0,0,1,0,2038;
use constant SUMMERNIGHT => timelocal 0,15,0,20,5,2008;

The point I'm trying to make is that my code take DST into account,
while your code doesn't. It would be very difficult to properly deal
with DST without using any module.

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

Re: Number of days since 1/1/2000

I know what you meant, and I don't want to get into an argument
over what is the right answer.  The problem is not well
specified.  However, in most applications the number of
elapsed days over a given time interval should not change
depending on the timezone of the person running the code
and should be expected to increase monotonically with time.
-- S

Re: Number of days since 1/1/2000

smallpond wrote:

How would you avoid that when you count whole days between dates in the
local time zone, and not some specific zone such as UTC? Are you
claiming that "most applications" ignore the daylight savings issue?

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

Re: Number of days since 1/1/2000

Who says the problem was "counting whole days between dates in
the local time zone"?

Re: Number of days since 1/1/2000

smallpond wrote:

Both you and I do. You do it implicitly with your code. ;-)

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

Re: Number of days since 1/1/2000

As I said, it is not worth arguing.   My code
counts 24-hour periods as defined by the Unix clock.  It will give
the same result regardless of TZ setting.  Counting dates using
local time zone leads to odd behavior at DST boundaries but is
certainly the correct way to count calendar days.

--S

Re: Number of days since 1/1/2000

smallpond wrote:

I disagree.

This sub-thread started when you said: "Just set it as a constant in
your program and you don't need any modules." I found, and still find,
it be bad advice to try to tackle this kind of problem without using any
modules.

was over-hasty?

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

Re: Number of days since 1/1/2000

At 2008-02-20 10:41AM, "Gunnar Hjalmarsson" wrote:

This seems very apropos right about now:  http://xkcd.com/386 /

--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry

Re: Number of days since 1/1/2000

LOL.  I think we can get it to go another week if we try, however:

I WAS WRONG.  COUNTING CALENDAR DAYS CORRECTLY SHOULD BE DONE WITH A
TESTED, CORRECT MODULE AND NOT WITH AN AD-HOC SOLUTION.

But the OP was looking for a solution that did not require
modules.

Re: Number of days since 1/1/2000

smallpond wrote:

Thanks. Now I'm going to sleep well tonight. :)

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

Re: Number of days since 1/1/2000

Hello,

You may want to take a look at the DateTime project
http://datetime.perl.org /

Many very smart people have spent many hours making sure DateTime
calculations are correct. Why reinvent the wheel when you don't have to.

use strict;
use warnings;
use DateTime;

my \$dt = DateTime->now;

my \$base_date = DateTime->new(
year      => 2000,
month     => 1,
day       => 1,
time_zone => 'UTC',
);

print int( \$dt->jd - \$base_date->jd );

I hope this helps

Mothra

Re: Number of days since 1/1/2000

Mothra schreef:

DateTime can surprise too:

perl -MData::Dumper -MDateTime -e'
\$dt = DateTime->new( safe =>1,
year => 2008, month => 3, day => 25, time_zone =>
"Africa/Cairo",
print Dumper(\$dt)
' |less

perl -MData::Dumper -MDateTime -e'
\$dt = DateTime->new( safe => 1,
year => 2008, month => 4, day => 26, time_zone =>
"Africa/Cairo",
)->subtract(days => 1);
print Dumper(\$dt)
' |less

perl -MData::Dumper -MDateTime -e'
\$dt = DateTime->new( safe => 1,
year => 2008, month => 4, day => 25, time_zone =>
"Africa/Cairo",
);
print Dumper(\$dt)
' |less

--
Affijn, Ruud

"Gewoon is een tijger."

Re: Number of days since 1/1/2000

Hi Dr. Ruud,

(snipped)

Hmm, safe=>1,
I am not fimilar with that one.
In any event, looking at my previous post I should have done
my \$dt = DateTime->now(time_zone => 'UTC'); To specify
a specific time zone instead of using a floating one (default)
when doing date/time math it is best to convert to UTC
do the math and convert back to the timezone of choice.
This would be the workaround for the problem that you have just
discribed.

Hope this helps

Mothra

Re: Number of days since 1/1/2000

Mothra schreef:

Oops, no, it is a (to me obvious) mode I am supposing, but it isn't in
DateTime yet. (see datetime mailing list).

--
Affijn, Ruud

"Gewoon is een tijger."

Re: Number of days since 1/1/2000

On Mon, 18 Feb 2008 11:20:30 -0800 (PST), oprah.chopra@gmail.com wrote:

[snip]

print calc_days(),"\n";
sub calc_days {int ((time() - 946713600)/86400);}

Re: Number of days since 1/1/2000

dummy@phony.info wrote:

We just finished a long sub-thread that discusses that approach to this
problem.

The approach is not portable because
- the epoch is not the same on all systems, and
- there are other time zones in this world but US/Pacific. ;-)

Furthermore, you are mixing a local time zone with UTC, and the approach
ignores the DST issue.

I think that this code takes all those objections into account:

use Time::Local;
use constant Y2000 => timelocal 0,0,0,1,0,2000;

print calc_days(), "\n";
sub calc_days {
my \$sec = timelocal(0,0,0,(localtime)[3..5]) - Y2000;
sprintf '%.0f', \$sec/86400;
}

--