Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Number of day in the year to proper date

by Animator (Hermit)
on Oct 02, 2008 at 23:21 UTC ( [id://715111]=note: print w/replies, xml ) Need Help??


in reply to Number of day in the year to proper date

Your code, slightly rewritten to make it more readable: (reading a one-liner on a site is not easy.)

#!/usr/bin/perl -l use strict; use warnings; use Time::Local; use POSIX qw(strftime); my $fmt = "%A"; # %a = abbreviated weekday %u = weekday number; my $yr1 = 2008 - 1900; for my $yday1 (272, 273, 274) { my $mytime = timelocal(1,0,0,1,1,$yr1); $mytime += ( 86400 * $yday1); my ($sec,$min,$hour,$day,$mon,$yr,$wday,$yday,$whocares) = localtime +($mytime); $yr += 1900; printf("%d/%02d/%02d%s", $yr, $mon, $day, " " ); my $weekday = strftime($fmt, 0, 0, 0, $day , $mon - 1, $yr - 1900, - +1, -1, -1); printf("%s\n", "$weekday"); }

The output of the code:

2008/09/30 Tuesday
2008/09/31 Wednesday
2008/10/01 Wednesday

Why does it produce different dates? You got the monts wrong. January is month 0, february is month 1, ....

In the code: my $mytime = timelocal(1,0,0,1,1,$yr1); => Should be: my $mytime = timelocal(1,0,0,1,0,$yr1); and
$yr += 1900; should be $yr += 1900;$mon += 1;

If you make the changes then the output will be:

2008/09/29 Monday
2008/09/30 Tuesday
2008/10/01 Wednesday

The meaning of your output was:

2008/09/30 Tuesday   => This really was 2008/10/30 with the weekday of 2008/09/30
2008/09/31 Wednesday => This really was 2008/10/31 with the weekday of 2008/10/01
2008/10/01 Wednesday => This really was 2008/11/01 with the weekday of 2008/10/01

An easy way to confirm the date is to add print scalar localtime($mytime); (and to change the $fmt = "%x";). Adding it in the original code will give you the following output:

2008/09/30 2008/30/09 Tuesday
Thu Oct 30 00:00:01 2008

2008/09/31 2008/10/01 Wednesday
Fri Oct 31 00:00:01 2008

2008/10/01 2008/10/01 Wednesday
Sat Nov  1 00:00:01 2008

Now: on to what is wrong with the code?

  • The use of localtime. Do you really want to worry about Daylight Saving Time?
  • Using POSIX::strftime to get the weekday. localtime() and gmtime() return the weekday: ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime....;. In that list $wday is the day of the week. Where 0 is Sunday, 1 is Monday and 6 is Saterday. Why use POSIX::strftime if you already have the weekday?

The solution to all your problems is not to write the date calculation routines yourself. There are several modules out there that do an excellent job!

For example: Date::Calc.
This would turn your code into:

#!/usr/bin/perl -l use strict; use warnings; use Date::Calc qw/Add_Delta_Days Date_to_Text/; my $yr1 = 2008; for my $yday1 (272, 273, 274) { print Date_to_Text(Add_Delta_Days($yr1, 1, 1, $yday1)); }

Benefits?

  • More readable;
  • Shoter;
  • Easier;
  • Correcter (Daylight Saving Time);
  • Faster;

Update: Added: The meaning of your output was
Update2: changed some dates from dd/mm/yyyy into yyyy/mm/dd.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://715111]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (9)
As of 2024-03-28 08:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found