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

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

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

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,174
    Janaka
    Feb 18, 2004
  2. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,285
    Michael Borgwardt
    May 30, 2004
  3. Greg Hauptmann
    Replies:
    6
    Views:
    293
    ara.t.howard
    Aug 6, 2008
  4. Chris Angelico
    Replies:
    3
    Views:
    157
    Mark Lawrence
    Mar 1, 2013
  5. Peter Otten
    Replies:
    0
    Views:
    135
    Peter Otten
    Feb 28, 2013
Loading...

Share This Page