http://qs321.pair.com?node_id=1033358

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 (Canon) 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 $

    I hope this is helpful.

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

        So, I've downloaded the strptime module from here (http://search.cpan.org/~gozer/POSIX-strptime-0.05/lib/POSIX/strptime.pm)

        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

A reply falls below the community's threshold of quality. You may see it by logging in.