go ahead... be a heretic PerlMonks

d-mmm-yyyy to DOY (day of year)

 on May 13, 2013 at 21:08 UTC Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, hopefully someone might be able to help as I've been searching all night for a solution to this, and am running out of time.

I have to convert this date field (or add another field) to the day of year (DOY). It is currently in d-mmm-yyyy.

By Day of year, I mean 1st January 2013 would be 1. 2nd January would be 2.

Here is a snippet of my very large (7,000,000 row table)

Date,GridID,new_l,O_Count,B_Count,E_Count,P_Count,C_Count,O_Y,B_Y,E_Y, +P_Y,C_Y,DayRain,Antecedent20RainSum,Antecedent10RainSum,Antecedent05R +ainSum,Antecedent02RainSum 1-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 2-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 3-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,11.60,11.60,11.60,11.60,11.6 +0
many, many thanks

Tim

Replies are listed 'Best First'.
Re: d-mmm-yyyy to DOY (day of year)
by johngg (Abbot) on May 13, 2013 at 21:41 UTC

The strftime() function from POSIX might be what you need.

\$ perl -Mstrict -Mwarnings -MPOSIX=strftime -e ' my \$mno = 0; my %monthLookup = map { \$_ => \$mno ++ } qw{ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec }; open my \$inFH, q{<}, \ <<EOD or die \$!; 1-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 2-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 3-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,11.60,11.60,11.60,11.60,11.6 +0 EOD while ( <\$inFH> ) { my \$date = ( split m{,} )[ 0 ]; my( \$d, \$m, \$y ) = split m{-}, \$date; print strftime( qq{\$date is day %j\n}, 0, 0, 0, \$d, \$monthLookup{ \$m }, \$y - 1900 ); }' 1-Apr-2012 is day 092 2-Apr-2012 is day 093 3-Apr-2012 is day 094 \$

Cheers,

JohnGG

Re: d-mmm-yyyy to DOY (day of year)
by bart (Canon) on May 13, 2013 at 21:44 UTC
A good starting point could be to use the module Date::Calc. A bit heavy, maybe, but it includes everything and the kitchen sink, including parsing dates, and the function Day_of_Year.
\$doy = Day_of_Year(\$year,\$month,\$day);

If parsing dates doesn't work out so well without an explicit format, you can fall back on POSIX::strptime.

Re: d-mmm-yyyy to DOY (day of year)
by Kenosis (Priest) on May 13, 2013 at 21:46 UTC

Another use of POSIX::strptime:

use strict; use warnings; use POSIX::strptime; while (<DATA>) { my (\$date) = /^([^,]+)/; my \$doy = ( POSIX::strptime( \$date, '%d-%b-%C' ) )[-1] + 1; print "Date: \$date; DOY: \$doy\n"; } __DATA__ 1-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 2-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00 3-Apr-2012,615265,2.4,0,0,0,0,0,0,0,0,0,0,11.60,11.60,11.60,11.60,11.6 +0

Output:

Date: 1-Apr-2012; DOY: 92 Date: 2-Apr-2012; DOY: 93 Date: 3-Apr-2012; DOY: 94

Hope this helps!

Re: d-mmm-yyyy to DOY (day of year)
by runrig (Abbot) on May 13, 2013 at 21:49 UTC
Re: d-mmm-yyyy to DOY (day of year)
by ambrus (Abbot) on May 14, 2013 at 10:13 UTC

Try the Date::Manip module.

use Date::Manip; \$day_of_year = 0 + UnixDate("3-Apr-2012", "%j");
Re: d-mmm-yyyy to DOY (day of year)
by sundialsvc4 (Abbot) on May 14, 2013 at 02:31 UTC

A follow-on question that might help clarify your decision is ... “what else do you need to do with, or know about, that date?”   What future requirements might you anticipate, e.g. from the Marketing Department?   Sometimes, a kitchen-sink is just what the doctor ordered ... taking the entire date-handling issue off your hands.

guys,

thanks so much for your replies. These look helpful. I will let you know how I get on. Ideally, I will be able to use that code to add another field to the table and be off and running.

many thanks again, from a first time perl user. Tim

Guys, sorry to be a pain, but I'm having trouble installing the POSIX strptime module. I'm using a windows machine at work and trying to use Perl Package Manager to find the module. (It wasn't there).

I've unpacked the folders in c:Perl64/site/lib and c:Perl64/lib, but my perl script is still not seeing that package. It is saying:

can't locate loadable object for module POSIX::strptime in @INC...

any advice would be gratefully recieved.

Thanks

Tim

Re: d-mmm-yyyy to DOY (day of year)
by sundialsvc4 (Abbot) on May 14, 2013 at 13:53 UTC

Also, if you do find that you need to “install something” in order to address your problem ... by all means, stop and “look for a Plan-B.”   There are many date-manipulation packages in Perl ... literally, hundreds of them.   Something is already going to be installed, that you can use to get this job done.   See for example perldoc perllocal.   You don’t need to smash down this particular door, to get to where you need to be, given such a simple requirement.

Here’s a handy one-liner:   perl -e 'use Date::Manip;' ... enter that on the shell command-line exactly as shown.   If that command succeeds (no nasty messages spew out), then you know that this module Date::Manip in this case) is available on your system, so perldoc Date::Manip to learn how it works.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1033358]
Approved by ww
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2017-06-27 19:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How many monitors do you use while coding?

Results (612 votes). Check out past polls.