what is a good/fast way to format date string?

Discussion in 'Perl Misc' started by it_says_BALLS_on_your forehead, Mar 6, 2006.

  1. I inherited a script that uses Date::Manip. powerful module, but
    painfully slow. Methods from this module are called perhaps over 100
    million times for log processing, so even small incremental gains in
    speed would accumulate to substantial savings (i hope).

    i have replaced Date::Manip with Date::Calc, but i'm losing the padded
    0's on the left. what's the fastest way of left-padding the zeroes back
    on? just a map? (although i think if i transform a list in place, it's
    better to use a for loop per PBP, although Damian Conway says that's
    for readability--i'll have to benchmark since this is simple enough i
    wouldn't lose much readability, but may gain speed if i use a map---

    @new_date = map { /^(\d)$/ and "0$1" or $_ } @new_date;

    ) i don't want to lose the time i've saved by inefficiently formatting
    the output.

    currently the input and output is:
    ========
    use strict; use warnings;

    use Date::Manip;

    my $date = '2006-03-02';
    my $time = '05:04:44';

    print "original date: $date\n";
    print "original time: $time\n";

    my $timeDiff = 4;

    my $goodTime = DateCalc(ParseDate($date.$time),"-$timeDiff hours");

    $date =
    substr($goodTime,0,4)."-".substr($goodTime,4,2)."-".substr($goodTime,6,2);
    $time = substr($goodTime,8,8);

    print "adjusted date: $date\n";
    print "adjusted time: $time\n";

    __END__
    original date: 2006-03-02
    original time: 05:04:44
    adjusted date: 2006-03-02
    adjusted time: 01:04:44


    my new script is:
    =====
    use strict; use warnings;

    use Date::Calc qw/ Add_Delta_DHMS /;

    my $date2 = '2006-03-02';
    my $time2 = '05:04:44';

    my $old_date = $date2 . ':' . $time2;

    my @pre_date = split /[\-:]/, $old_date;
    my @new_date = Add_Delta_DHMS( @pre_date, 0, -4, 0, 0 );

    #@new_date = map { /^(\d)$/ and "0$1" or $_ } @new_date;
    #print "@new_date\n";

    $date2 = join( '-', @new_date[0..2] );
    $time2 = join( ':', @new_date[3..$#new_date] );

    print "date2: $date2\n";
    print "time2: $time2\n";


    __END__
    date2: 2006-3-2
    time2: 1:4:44

    # with map
    date2: 2006-03-02
    time2: 01:04:44
     
    it_says_BALLS_on_your forehead, Mar 6, 2006
    #1
    1. Advertisements

  2. it_says_BALLS_on_your forehead

    J. Gleixner Guest

    it_says_BALLS_on_your forehead wrote:

    > i have replaced Date::Manip with Date::Calc, but i'm losing the padded
    > 0's on the left. what's the fastest way of left-padding the zeroes back
    > on?


    > #@new_date = map { /^(\d)$/ and "0$1" or $_ } @new_date;


    Using sprintf is the way to go. In addition to being much
    more readable, it's much faster. Using one sprintf call, seemed
    to provide very good results.

    ($date2, $time2 ) = split (' ',
    sprintf("%d-%02d-%02d %02d:%02d:%02d",
    @new_date )
    );
     
    J. Gleixner, Mar 6, 2006
    #2
    1. Advertisements

  3. J. Gleixner wrote:
    > it_says_BALLS_on_your forehead wrote:
    >
    > > i have replaced Date::Manip with Date::Calc, but i'm losing the padded
    > > 0's on the left. what's the fastest way of left-padding the zeroes back
    > > on?

    >
    > > #@new_date = map { /^(\d)$/ and "0$1" or $_ } @new_date;

    >
    > Using sprintf is the way to go. In addition to being much
    > more readable, it's much faster. Using one sprintf call, seemed
    > to provide very good results.
    >
    > ($date2, $time2 ) = split (' ',
    > sprintf("%d-%02d-%02d %02d:%02d:%02d",
    > @new_date )
    > );


    excellent, just what i was looking for! thanks!
     
    it_says_BALLS_on_your forehead, Mar 6, 2006
    #3
  4. Christian Winter wrote:
    > it_says_BALLS_on_your forehead schrieb:
    > [...]
    > > i have replaced Date::Manip with Date::Calc, but i'm losing the padded
    > > 0's on the left. what's the fastest way of left-padding the zeroes back
    > > on? just a map? (although i think if i transform a list in place, it's
    > > better to use a for loop per PBP, although Damian Conway says that's
    > > for readability--i'll have to benchmark since this is simple enough i
    > > wouldn't lose much readability, but may gain speed if i use a map---
    > >
    > > @new_date = map { /^(\d)$/ and "0$1" or $_ } @new_date;

    >
    > Normally a sprintf should be cheaper than applying a regex.
    > @new_date = map { sprintf "%02i", $_ } @new_date;
    >
    > But you might get even more speed if you omit the re-assignment
    > of the list at all:
    >
    > $_ = sprintf( "%02i", $_ ) for( @newdate );


    thank you Chris!
     
    it_says_BALLS_on_your forehead, Mar 6, 2006
    #4
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brian Candy
    Replies:
    2
    Views:
    1,431
    Janaka
    Feb 18, 2004
  2. DC
    Replies:
    5
    Views:
    3,218
    Brendan Reynolds
    Jul 1, 2005
  3. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,776
    Michael Borgwardt
    May 30, 2004
  4. Chu
    Replies:
    3
    Views:
    4,478
    Shawn
    Aug 15, 2006
  5. davyb
    Replies:
    7
    Views:
    394
    Gregory Brown
    Nov 18, 2005
  6. Greg Hauptmann
    Replies:
    6
    Views:
    449
    ara.t.howard
    Aug 6, 2008
  7. Josh Sharpe
    Replies:
    1
    Views:
    328
    Brian Candler
    Sep 21, 2010
  8. Chris Angelico
    Replies:
    3
    Views:
    397
    Mark Lawrence
    Mar 1, 2013
Loading...