Number of days since 1/1/2000

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

Threaded View
•  Subject
• Author
• Posted on
I am using the following subroutine to calculate the  number of days
since 1/1/2000 . Is there any possible bug in it? I know  I can use
Date::Manip but it will slow down my program which is around 100 kb
long.

use strict;
use warnings;

my \$days = &calc_days;

print "The number of days since 1/1/2000 is \$days\n";

###############

sub calc_days {

my ( \$mday, \$mon, \$year ) = ( localtime(time) )[3,4,5];
if (\$mday < 10) { \$mday = "0\$mday"; }

\$year += 1900;

# assign the Beginning date values

my (\$MTH,\$TDD,\$YRW) = (1,1,2000);

my @TM = (31,28,31,30,31,30,31,31,30,31,30,31);
my \$total_days = 0;

while (\$MTH <= (\$mon + 1) && \$YRW == \$year || \$MTH <= 12 && \$YRW <
\$year)  {

## test for leap year
my    \$yeardiv = (\$YRW / 4);
my    \$yearint = int(\$yeardiv);
my    \$yeardiv1 = (\$YRW / 100);
my    \$yearint1 = int(\$yeardiv1);
if (\$yeardiv eq \$yearint && \$yeardiv1 ne \$yearint1) {
\$TM[1] = 29;
}else {    \$TM[1] = 28;
}

if (\$MTH == (\$mon + 1) && \$YRW == \$year)   {

while (++\$TDD <= \$mday)  { \$total_days += 1; }

}else{
while (++\$TDD <= \$TM[\$MTH - 1])  { \$total_days += 1; }

\$TDD = 0;   # reset TDD after each full month
}   # end inside if/else

\$MTH += 1;

if  (\$MTH == 13 )  {
\$MTH =1;
\$YRW += 1;
}
}  # end outside loop

return \$total_days;

} # end sub

Re: Number of days since 1/1/2000

On Mon, 18 Feb 2008 11:20:30 -0800, oprah.chopra wrote:

Seeing you use a loop to calculate the difference, are you sure
Date::Manip is slower? Did you benchmark it? You might be surprised.

M4

Re: Number of days since 1/1/2000

Martijn Lievaart wrote:

surprised. >

One problem with Date::Manip is it is not a standard module and not
available on some of the servers I run the code on. Since my code is
alrady 100+kb long, I would think requireinf another few hundred kb
would be overkill for something I can do in one subroutine?

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com writes:

If my choice was between installing a prepackaged, tested, measily 100K
of code or reverse engineering a 100K of code, I know I wouldn't easily
take the second option.

Even if the module contains XS code (I don't think Date::Manip does, but
I haven't checked) you can generally install the module into a local
tree and copy it with your own code, provided the systems have all have
the same specs (OS and perl version, more or less).

Also, many unix systems have system packages for lots of perl modules
(on linux, I'd be surprised if any large vendor doesn't ship
Date::Manip, even if it's not installed by default).

--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl /

Re: Number of days since 1/1/2000

On Feb 18, 1:22 pm, oprah.cho...@gmail.com wrote:

I've had similar problems.  I've often had to write Perl scripts
for customers who either don't have access to CPAN or are forbidden to
install additional packages (outside of the Perl script I write).  As
a result, I tend to prefer solutions that can be implemented with
standard modules.

In my opinion, any code that contains an array with the days of the
month, like this:

my @TM = (31,28,31,30,31,30,31,31,30,31,30,31);

is a hint that the program is going down the wrong path.  For one
thing, it requires a loop that has to have knowledge if the second
element is correct (which it won't be on leap years).

This approach might seem simple for you, but it's error prone and
difficult for other maintainers (that is, people who are NOT you) to
debug and make sure is correct and accurate.

If you're adamant on not using Date::Manip, try the following
algorithm which happens to not have any loops in it:

# Returns the number of days since January 1, 2000:
sub calc_days
{
# Calculate the epoch time for midnight, January 1, 2000:
use Time::Local;  # for timegm()
my \$epochTimeFor2000Jan1 = timegm(0,0,0, 1,0,100);

# Get the number of seconds that have elapsed since then:
my \$elapsedSeconds = time() - \$epochTimeFor2000Jan1;

# Calculate the number of days that have elapsed since then:
my \$elapsedDays = int( \$elapsedSeconds / (60*60*24) );

return \$elapsedDays;
}

And that's it!  Notice that the calc_days() subroutine only has
three lines of code (not counting the "use" and "return" lines).
There are no loops involved.  Also, the Time::Local module is a
standard module, which means that all the servers you run it on should
already have it.

Here's something to be aware of:  My code above uses the timegm()
function, which assumes the time passed in (that is, midnight on
January 1, 2000) is in UTC time, and not local time.  If you really
want to use local time, you probably will want to change timegm() to
timelocal().  (But be aware that, when using localtime, not every day
of the year has 24*60*60 seconds, as there are usually two days per
year that have a different amount.  Usually this shouldn't be much of
an issue, but just be aware of it anyway.)

You might think that a while-loop with a large block is easier to
read than these three lines of code that use epoch time, but many
maintainers will beg to differ, especially since your while-loop
condition contains || and several &&s.

By the way, if you want to check if the answer from the programs is
correct, you can write a short one-line Perl script.  For example, if
your program output:

The number of days since 1/1/2000 is 2971

then type the following:

perl -MTime::Local=timegm_nocheck -lwe "print scalar gmtime
timegm_nocheck(0,0,0,2971+1,0,100)"

(Remember to change the "timegm"s to "timelocal"s if you're using
local time.)

If the date you get back is today's date, then your script calculated
the correct number of days since January 1, 2000.  If it didn't, then
you need to track down the bug.

I hope this helps.

-- Jean-Luc

P.S.  I happen to agree with the others that using the Date::Manip
module won't include that much overhead.  If anything, it'll simplify
your code, and possibly make it even faster in that it would allow you
to eliminate your while-loop.

Re: Number of days since 1/1/2000

4434-aaa0-30db5bad2ec4@d21g2000prf.googlegroups.com:

We have been through this a few times in the past, IIRC.

Just copy and paste the code for the module in your script.

Sinan

--
(remove .invalid and reverse each component for email address)
clpmisc guidelines: <URL:http://www.rehabitation.com/clpmisc.shtml

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com wrote:

Please correct me anybody if I'm wrong.
You can copy your Date.pm module with whole subdirectory structure to some
directory on server (say /home/modules/) and add path to @INC near the script
top. Hosting company will not be happy but this work fine :-)

--
Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)

Please reply to <petr AT practisoft DOT cz>

Re: Number of days since 1/1/2000

oprah> One problem with Date::Manip is it is not a standard module and not
oprah> available on some of the servers I run the code on. Since my code is
oprah> alrady 100+kb long, I would think requireinf another few hundred kb
oprah> would be overkill for something I can do in one subroutine?

If you are not using Perl in an environment where you can install additional
modules from the CPAN, you are missing out on at least half of what Perl has
to offer.

If an ISP says "we support Perl" and then doesn't give you a way to install
modules in this day and age, I will accuse them of being unethical as a
business.

print "Just another Perl hacker,"; # the original

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Re: Number of days since 1/1/2000

Randal L. Schwartz wrote:

You are right but many cheap hosting (about \$3.99 per month) "support" Perl
but not allow to install additional modules. Some hostings install modules by
request on tech.support but some not.
What you think about my way to "install" modules?
--
Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)

Please reply to <petr AT practisoft DOT cz>

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com wrote:

It's doubtful that using Date::Manip would slow it down much, if at
all.  So what if using it added .001 second to the run time? The
valuable lesson is that you probably wasted a couple of hours/days
writing this poor code, when all it would really take is a module and
a call or two. The solution is already written, well tested, and
makes your code much easier to manage. Code re-use is a wonderful
thing.

Good start.

^
Eeeekk.. not so good.

Whenever I see that, instead of sprintf, I say to myself, "Inexperienced
coder."

Upper case variables. Less experienced than I thought.

At this point I'd give up and never use this code, because
it's pretty obvious the programmer really doesn't know
what they're doing.

After looking your example it's probably not surprising that
your code is possibly 100kb. BTW: The number of bytes of
code has nothing to do with how long it might take to execute.

Re: Number of days since 1/1/2000

J. Gleixner wrote:

"Inexperienced > coder."

Well I have been coding perl for seven years and and count on one
hand the number of times I used sprintf. print is simple , why make
code more unreadable by unncessarily cluttering it with esoteric
functions? At least that has always been my philosophy. Yes there may
be more 'technically correct' ways to do things, but I am running a
business and have to look at the bigger picture . If I hire a new
perl programmer, will they know the difference between print and
sprintf?

I can tell you have a PhD, because you suffer from the classic
ostrich mentality, i.e head is stuck in the ground lookiing at
details, while you can't see the train coming..

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com writes:

Are you kidding? sprintf isn't esotheric, it's been a standard C
function for ages and pretty much all modern scripting languages
implement it in one way or the other. I don't use sprintf every day but
for general number-to-string conversion it's by far the best and easiest
to use built-in function.

--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl /

Re: Number of days since 1/1/2000

Quoth oprah.chopra@gmail.com:

IMHO you managed to make your code quite unreadable enough without using
sprintf :).

Would you *really* hire someone who didn't, or who couldn't find out in
10 seconds from the docs?

Ben

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com wrote:

Except that sprintf wasn't being proposed as an alternative to print.
If you think it was, than your code is even more unreadable to you than
it is to us.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: Number of days since 1/1/2000

oc> J. Gleixner wrote:
>> Whenever I see that, instead of sprintf, I say to myself,
oc> "Inexperienced > coder."

oc> Well I have been coding perl for seven years and and count on one
oc> hand the number of times I used sprintf. print is simple , why
oc> make code more unreadable by unncessarily cluttering it with
oc> esoteric functions? At least that has always been my
oc> philosophy. Yes there may be more 'technically correct' ways to do
oc> things, but I am running a business and have to look at the bigger
oc> picture . If I hire a new perl programmer, will they know the
oc> difference between print and sprintf?

sprintf is not esoteric. you are thinking baby perl if you assume
that. the bigger picture is better code for MOST perl hackers, not just
the kiddies you think are out there.

oc> I can tell you have a PhD, because you suffer from the classic
oc> ostrich mentality, i.e head is stuck in the ground lookiing at
oc> details, while you can't see the train coming..

wow. no more soup for you!

PS. i do perl code review for a living. i don't tolerate clients who
don't appreciate quality criticism.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

Re: Number of days since 1/1/2000

oc> J. Gleixner wrote:
>> Whenever I see that, instead of sprintf, I say to myself,
oc> "Inexperienced > coder."

oc> Well I have been coding perl for seven years and and count on one
oc> hand the number of times I used sprintf. print is simple , why make
oc> code more unreadable by unncessarily cluttering it with esoteric
oc> functions? At least that has always been my philosophy. Yes there may
oc> be more 'technically correct' ways to do things, but I am running a
oc> business and have to look at the bigger picture . If I hire a new
oc> perl programmer, will they know the difference between print and
oc> sprintf?

while (++\$TDD <= \$mday)  { \$total_days += 1; }

}else{
while (++\$TDD <= \$TM[\$MTH - 1])  { \$total_days += 1; }

and is + more esoteric than ++ or += 1??

that code is some of the poorest and slowest code i have seen in a
while. i will steal it for some bad code examples i will use in
teaching. you don't mind, do you?

note the masssive redundancy of all but the <= part. note the
inconsistant use of ++ vs += 1. note the absence of basic math with
subtraction and addition being unused but increment in a loop is used.

esoteric indeed!

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

Re: Number of days since 1/1/2000

oprah.chopra@gmail.com wrote in news:d6a7945f-8a2b-4109-8e01-
e74118d4fe9c@d21g2000prf.googlegroups.com:

For some reason, your thought process made me think of pots and kettles.

To recap, the relevant part of the thread was:

Jurgen was being polite. Whenever I see code like that, I think to me
myself, "oh, I have to deal with another stupid code monkey!"

There is no excuse for "0\$mday".

There is also no excuse for refusing to learn and insisting on using the
inexcusable construct.

Bye bye ...

Sinan

--
(remove .invalid and reverse each component for email address)
clpmisc guidelines: <URL:http://www.rehabitation.com/clpmisc.shtml

Re: Number of days since 1/1/2000

A. Sinan Unur wrote:

Let me guess, you have a PhD too? You are all the same, unable to see
the big picture. Instead they focus on the tiny flaws of a system to
convince people that the entire system is flawed. I suppose such
behaviour is fine in the research lab, but in the real world it
creates unncessary red tape to get things done.

It's the old, 'I know better than you' syndrome. we are all at risk
of it, even us uneducated mob. Indeed the more papers one has to
prove how much one knows, the bigger the chance that this syndrome
will strike.

You will always argue they are more accurate while failing to
understand the problems at hand in the real world.

Take this as some 'friendly' humble-pie. You will be surprised how
far little tact will take you.

Re: Number of days since 1/1/2000

oc> A. Sinan Unur wrote:
>> Jurgen was being polite. Whenever I see code like that, I think to
>> me myself, "oh, I have to deal with another stupid code monkey!"

>> There is no excuse for "0\$mday".
>>
>> There is also no excuse for refusing to learn and insisting on
>> using the inexcusable construct.

oc> Let me guess, you have a PhD too? You are all the same, unable to see
oc> the big picture. Instead they focus on the tiny flaws of a system to
oc> convince people that the entire system is flawed. I suppose such
oc> behaviour is fine in the research lab, but in the real world it
oc> creates unncessary red tape to get things done.

let me guess, you are a self taught perl coder? you exhibit all the
symptoms, poor style, no interest in learning more perl, not listening
to experienced coders. we see it all the time. and your 'real world'
experience is probably very provincial. try reading some cpan code which
is truly real world as much of it is used all over the world.

oc> It's the old, 'I know better than you' syndrome. we are all at risk
oc> of it, even us uneducated mob. Indeed the more papers one has to
oc> prove how much one knows, the bigger the chance that this syndrome
oc> will strike.

so you admit you are uneducated. must be supporter of shrub then!

oc> You will always argue they are more accurate while failing to
oc> understand the problems at hand in the real world.

you have no clue about the real world no matter how much you claim you
do. bad code is rampant in the real world. that doesn't make it
right. and "0\$mday" is bad code as it does more work than sprintf does.

oc> Take this as some 'friendly' humble-pie. You will be surprised how
oc> far little tact will take you.

and you need to learn how to learn. too bad for you. as i said before, i
make a living cleaning up messes like your code. too bad you won't ever
hire me or learn from anyone better than you. i have pity on you, your
projects and your bosses. they all will fail over time.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

Re: Number of days since 1/1/2000

J. Gleixner wrote:

http://search.cpan.org/perldoc?Date%3A%3AManip#SHOULD_I_USE_DATE::MANIP

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