Velocity Reviews > Perl > Critic, please: Rounding off using Date Manipulation

# Critic, please: Rounding off using Date Manipulation

Lax
Guest
Posts: n/a

 02-06-2006
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

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

Lax

A. Sinan Unur
Guest
Posts: n/a

 02-06-2006
"Lax" <(E-Mail Removed)> wrote in
news:(E-Mail Removed) oups.com:

> 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 <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:

Dr.Ruud
Guest
Posts: n/a

 02-06-2006
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."

A. Sinan Unur
Guest
Posts: n/a

 02-06-2006
"Dr.Ruud" <(E-Mail Removed)> 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 <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:

Guest
Posts: n/a

 02-06-2006
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]);

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

John W. Krahn
Guest
Posts: n/a

 02-07-2006
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

Guest
Posts: n/a

 02-07-2006
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'?

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

Anno Siegel
Guest
Posts: n/a

 02-07-2006
John W. Krahn <(E-Mail Removed)> 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