Critic, please: Rounding off using Date Manipulation

Discussion in 'Perl Misc' started by Lax, Feb 6, 2006.

  1. Lax

    Lax Guest

    Hi all,
    Could someone please critic my solution to a date/time rounding off
    solution?
    It works, but I think its really ugly and maybe Date::Manip itself has
    some useful routine to do this. I havent been able to find one.

    Issue: Given current time, I'd like to find the ten-minute interval
    it'd be in.
    e.g, if my current time is: "20060206 16:35:43", I'd like the upper and
    lower ends of its interval, like "Upper: 20060206 16:40:00" and "Lower:
    20060206 16:30:00"

    This is what I've come up with, but was wondering if there are more
    elegant soultions?

    1. I get the current time-stamp from Date::Manip's ParseDate.
    2. I convert the result into a number by removing the semi-colons ":"
    3. To get the lower limit, I substitute the last three digits with
    zeroes.
    4. To get upper limit, I substitute the last three digits with zeroes
    and add one to the "fourth from last" digit.

    ====================================================
    #!/usr/local/bin/perl

    use strict ;
    use warnings ;

    use Date::Manip ;
    my $date = ParseDate("today") ;
    $date =~ s/\://g ;
    print "Orig : $date\n" ; # Original time stamp, e.g, 20060206163543

    my @arr = split(//,$date) ;

    # Make last three digits zeroes.
    for ( my $i = 0 ; $i <= 2 ; $i++ )
    {
    $arr[$#arr - $i] = 0 ;
    }

    my $lower = join("",@arr) ;
    print "Lower: $lower\n" ; # 20060206163000

    # Add one to the last but fourth.
    $arr[$#arr - 3]++ ;
    my $upper = join("",@arr) ;
    print "Upper: $upper\n" ; # 20060206164000

    --------------------------------------------------------------------------------------------------

    Thanks for your time,
    Lax
    Lax, Feb 6, 2006
    #1
    1. Advertising

  2. "Lax" <> wrote in
    news::

    > Issue: Given current time, I'd like to find the ten-minute interval
    > it'd be in. e.g, if my current time is: "20060206 16:35:43", I'd like
    > the upper and lower ends of its interval, like "Upper: 20060206
    > 16:40:00" and "Lower: 20060206 16:30:00"


    ....

    > 1. I get the current time-stamp from Date::Manip's ParseDate.
    > 2. I convert the result into a number by removing the semi-colons ":"
    > 3. To get the lower limit, I substitute the last three digits with
    > zeroes.
    > 4. To get upper limit, I substitute the last three digits with zeroes
    > and add one to the "fourth from last" digit.


    Well, if you are going to use Date::Manip, you can use DateCalc to get
    10 minutes later.

    On the other hand, you can use Perl's time function, and Time::Local to
    do this fairly easily:

    #!/usr/bin/perl

    use strict;
    use warnings;

    use Time::Local;

    my $t = '20060206 16:35:43';

    my ($year, $month, $mday, $hour, $min, $sec) = (
    $t =~ m{\A (\d{4})(\d{2})(\d{2}) \s+ (\d{2}):(\d{2}):(\d{2}) \z}x
    );

    my $lower_min;
    {
    use integer;
    $lower_min = 10 * ($min % 10);
    }

    my $lower_time = timelocal(0, $lower_min, $hour, $mday, $month, $year);
    my $upper_time = $lower_time + 600;

    print 'Lower: ' . localtime($lower_time), "\n",
    'Upper: ' . localtime($upper_time), "\n";

    __END__

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Feb 6, 2006
    #2
    1. Advertising

  3. Lax

    Dr.Ruud Guest

    A. Sinan Unur:

    > my $lower_min;
    > {
    > use integer;
    > $lower_min = 10 * ($min % 10);


    Change either to

    $lower_min = 10 * ($min / 10);

    or to

    $lower_min = $min - $min % 10;

    > }


    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Feb 6, 2006
    #3
  4. "Dr.Ruud" <> wrote in news:ds8lpo.1l4.1
    @news.isolution.nl:

    > A. Sinan Unur:
    >
    >> my $lower_min;
    >> {
    >> use integer;
    >> $lower_min = 10 * ($min % 10);

    >
    > Change either to
    >
    > $lower_min = 10 * ($min / 10);
    >
    > or to
    >
    > $lower_min = $min - $min % 10;
    >
    >> }


    Ahem ... see, that's what we call "high math" ;-)

    Thanks for spotting the error. I thought I had fixed that before
    posting, but apparently not.

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Feb 6, 2006
    #4
  5. Lax wrote:
    > Could someone please critic my solution to a date/time rounding off
    > solution?
    > It works, but I think its really ugly and maybe Date::Manip itself has
    > some useful routine to do this. I havent been able to find one.
    >
    > Issue: Given current time, I'd like to find the ten-minute interval
    > it'd be in.
    > e.g, if my current time is: "20060206 16:35:43", I'd like the upper and
    > lower ends of its interval, like "Upper: 20060206 16:40:00" and "Lower:
    > 20060206 16:30:00"


    I wouldn't use any module for that.

    my $time = time;
    my $l_time = $time - $time % 600;
    my @lo = (localtime $l_time)[0..5];
    my @hi = (localtime $l_time + 600)[0..5];
    print 'Lower: ', sprintf("%d%02d%02d %02d:%02d:%02d\n",
    $lo[5]+1900, $lo[4]+1, @lo[3,2,1,0]);
    print 'Higher: ', sprintf("%d%02d%02d %02d:%02d:%02d\n",
    $hi[5]+1900, $hi[4]+1, @hi[3,2,1,0]);

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Feb 6, 2006
    #5
  6. Lax wrote:
    > Hi all,
    > Could someone please critic my solution to a date/time rounding off
    > solution?
    > It works, but I think its really ugly and maybe Date::Manip itself has
    > some useful routine to do this. I havent been able to find one.
    >
    > Issue: Given current time, I'd like to find the ten-minute interval
    > it'd be in.
    > e.g, if my current time is: "20060206 16:35:43", I'd like the upper and
    > lower ends of its interval, like "Upper: 20060206 16:40:00" and "Lower:
    > 20060206 16:30:00"
    >
    > This is what I've come up with, but was wondering if there are more
    > elegant soultions?
    >
    > 1. I get the current time-stamp from Date::Manip's ParseDate.
    > 2. I convert the result into a number by removing the semi-colons ":"
    > 3. To get the lower limit, I substitute the last three digits with
    > zeroes.
    > 4. To get upper limit, I substitute the last three digits with zeroes
    > and add one to the "fourth from last" digit.
    >
    > ====================================================
    > #!/usr/local/bin/perl
    >
    > use strict ;
    > use warnings ;
    >
    > use Date::Manip ;
    > my $date = ParseDate("today") ;
    > $date =~ s/\://g ;
    > print "Orig : $date\n" ; # Original time stamp, e.g, 20060206163543
    >
    > my @arr = split(//,$date) ;
    >
    > # Make last three digits zeroes.
    > for ( my $i = 0 ; $i <= 2 ; $i++ )
    > {
    > $arr[$#arr - $i] = 0 ;
    > }
    >
    > my $lower = join("",@arr) ;
    > print "Lower: $lower\n" ; # 20060206163000
    >
    > # Add one to the last but fourth.
    > $arr[$#arr - 3]++ ;
    > my $upper = join("",@arr) ;
    > print "Upper: $upper\n" ; # 20060206164000



    use Date::Manip;
    my $date = ParseDate( 'today' );
    $date =~ tr/://d;
    print "Orig : $date\n"; # Original time stamp, e.g, 20060206163543

    substr $date, -3, 3, '';

    my $lower = $date . '000';
    print "Lower: $lower\n"; # 20060206163000

    # Add one to the last but fourth.
    my $upper = ++$date . '000';
    print "Upper: $upper\n"; # 20060206164000



    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Feb 7, 2006
    #6
  7. John W. Krahn wrote:
    > Lax wrote:
    >>Issue: Given current time, I'd like to find the ten-minute interval
    >>it'd be in.

    >
    > use Date::Manip;
    > my $date = ParseDate( 'today' );
    > $date =~ tr/://d;
    > print "Orig : $date\n"; # Original time stamp, e.g, 20060206163543
    >
    > substr $date, -3, 3, '';
    >
    > my $lower = $date . '000';
    > print "Lower: $lower\n"; # 20060206163000
    >
    > # Add one to the last but fourth.
    > my $upper = ++$date . '000';
    > print "Upper: $upper\n"; # 20060206164000


    What if the original time stamp is e.g. '20060206235543'?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Feb 7, 2006
    #7
  8. Lax

    Anno Siegel Guest

    John W. Krahn <> wrote in comp.lang.perl.misc:
    > Lax wrote:
    > > Hi all,
    > > Could someone please critic my solution to a date/time rounding off
    > > solution?
    > > It works, but I think its really ugly and maybe Date::Manip itself has
    > > some useful routine to do this. I havent been able to find one.
    > >
    > > Issue: Given current time, I'd like to find the ten-minute interval
    > > it'd be in.
    > > e.g, if my current time is: "20060206 16:35:43", I'd like the upper and
    > > lower ends of its interval, like "Upper: 20060206 16:40:00" and "Lower:
    > > 20060206 16:30:00"


    > use Date::Manip;
    > my $date = ParseDate( 'today' );
    > $date =~ tr/://d;
    > print "Orig : $date\n"; # Original time stamp, e.g, 20060206163543
    >
    > substr $date, -3, 3, '';
    >
    > my $lower = $date . '000';
    > print "Lower: $lower\n"; # 20060206163000
    >
    > # Add one to the last but fourth.
    > my $upper = ++$date . '000';
    > print "Upper: $upper\n"; # 20060206164000


    Like the OPs solution, this fails to propagate a "carry" if the
    incrementation of $upper crosses an hour limit, as in 20060207125500.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Feb 7, 2006
    #8
    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. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,226
    Michael Borgwardt
    May 30, 2004
  2. Toby A Inkster

    Re: Please critic this page

    Toby A Inkster, Aug 6, 2003, in forum: HTML
    Replies:
    0
    Views:
    394
    Toby A Inkster
    Aug 6, 2003
  3. DU
    Replies:
    8
    Views:
    425
    Toby A Inkster
    Aug 8, 2003
  4. Lauri Raittila

    Re: Please critic this page

    Lauri Raittila, Aug 6, 2003, in forum: HTML
    Replies:
    15
    Views:
    582
    Jukka K. Korpela
    Aug 9, 2003
  5. Sam Hughes

    Re: Please critic this page

    Sam Hughes, Aug 8, 2003, in forum: HTML
    Replies:
    8
    Views:
    700
    Toby A Inkster
    Aug 10, 2003
Loading...

Share This Page