Critic, please: Rounding off using Date Manipulation

L

Lax

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
 
A

A. Sinan Unur

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
 
D

Dr.Ruud

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;
 
A

A. Sinan Unur

A. Sinan Unur:


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
 
G

Gunnar Hjalmarsson

Lax said:
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]);
 
J

John W. Krahn

Lax said:
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
 
G

Gunnar Hjalmarsson

John said:
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'?
 
A

Anno Siegel

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top