Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

getting Date calculation in simpler way

by jesuashok (Curate)
on Apr 13, 2006 at 12:51 UTC ( #543058=perlquestion: print w/replies, xml ) Need Help??
jesuashok has asked for the wisdom of the Perl Monks concerning the following question:

Hi all

$input= "200604131145" #( yyyymmddhhmi)
I would like to add 15 with the $input
I should get the output as $output = "200604130200"
I would like to get this done in simpler way.
I am already advised by the perlmonks that using perl module will make the work very simple.
But people who are sitting above me, strictly told that I should not use modules.
Please bear with me.

($YY, $MM, $DD, $hh, $mm) = ($dtstamp =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d) +(\d\d)/); $period1 =sprintf("%02d/%02d/%04d %02d:%02d", $MM, $DD, $YY, $hh, $mm+15); $period2 =sprintf("%02d/%02d/%04d %02d:%02d", $MM, $DD, $YY, $hhm2, $hm2-$hhm2*60); $period3 =sprintf("%02d/%02d/%04d %02d:%02d", $MM, $DD, $YY, $hh, $mm); $period4 =sprintf("%02d/%02d/%04d %02d:%02d", $MM, $DD, $YY, $hhm2, $hm2-(($hhm2*60)-15));
Existing code is given in the above lines.
How to simplify that one.

"Keep pouring your ideas"

Replies are listed 'Best First'.
Re: getting Date calculation in simpler way
by dragonchild (Archbishop) on Apr 13, 2006 at 13:03 UTC
    But people who are sitting above me, strictly told that I should not use modules.

    Are you not allowed to use a keyboard, either? I mean, punchcards should be sufficient, right?

    Modules are written for a reason. You will want to use DateTime, Date::Calc, or Date::Manip. They have been written by people with an interest in the topic and the code has been vetted on over 100 different OSes by people with an interest in the topic. In other words, the code is nearly bug-free, fast, and completely useful.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: getting Date calculation in simpler way
by davidrw (Prior) on Apr 13, 2006 at 13:17 UTC
    first, your post says 1145 + 15 ==> 0200 ...
    I would like to get this done in simpler way.
    Second, the only way to do it in a simple way (w.r.t to you) is to use a module and let it do all the work for you .. you don't want to be adding the time in there yourself and dealing w/the gregorian calendar .. e.g. add 15 minutes to each of these: 200002282345, 200402282345, 200602282345 ; and also 200512312345

    Tell the people above you that you can a) spend a lot of time reinventing the wheel, then more time testing your code, and probably still have a bug or 2, or b) spend 5 min looking at modules docs and write a 2-line, very robust, very maintainable snippet.
    Do we even want to know their "reasoning" for not wanting to use modules?

    As for solutions, see these two threads:
Re: getting Date calculation in simpler way
by johngg (Abbot) on Apr 13, 2006 at 14:25 UTC
    I would be amazed if your bosses disallow use of modules that come as part of the standard Perl distribution. You need to use Time::Local to turn a date into seconds since the epoch. Other than using this module, the following script does pretty much as ff suggests.

    use strict; use warnings; # Need this to turn date into seconds since epoch. Standard # part of Perl distribution. # use Time::Local; # Initialise date string, print it and then increment by # fifteen minutes and print ten times just to show it works. # our $dateStr = "200604132341"; print "$dateStr\n"; $dateStr = plus15($dateStr), print "$dateStr\n" for 1 .. 10; sub plus15 { # Get date string, set seconds to zero, pull the rest of # the date from the string with a match; # my $dateStr = shift; my $sec = 0; my ($year, $mth, $day, $hr, $min) = $dateStr =~ /^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)$/; # Get seconds since the epoch, note months start from zero for # January to 11 for December. Add 15 minutes-worth of seconds. # my $timeVal = timelocal($sec, $min, $hr, $day, $mth - 1, $year); $timeVal += 15 * 60; # Turn back in to separate parts, year, month etc. Note that # localtime() returns years since 1900. Construct a new date # string and return it. # my @timeParts = localtime($timeVal); my $newStr = $timeParts[5] + 1900 . sprintf("%02d", $timeParts[4] + 1) . sprintf("%02d", $timeParts[3]) . sprintf("%02d", $timeParts[2]) . sprintf("%02d", $timeParts[1]); return $newStr; }

    I you can't even use this module then you are forced to increment the minutes, roll the hour and set back the minutes if they go over 59, etc., etc. Painful, but character building.

    Best of luck,


Re: getting Date calculation in simpler way
by ff (Hermit) on Apr 13, 2006 at 13:35 UTC
    How accurate does your resulting timestamp need to be? Perhaps you just need a unique number that looks like a timestamp. Add 15 to a valid timestamp and there you have it, e.g. 200604131155 becomes 200604131170 (which of course means 200604131210). Oh, you want minutes to roll to hours to roll to days to roll to months to roll to years? Get ready to write up a bunch of special cases, write incrementing routines for those various flavors, and put them together. Though if what you have above works for you, it looks pretty simple to me.

    Quick, another approach: use time to generate what time it is 'now', add 15 minutes worth of seconds to that number, and feed that number back as a parameter to localtime and get the figures you want out of the array.

Re: getting Date calculation in simpler way
by salva (Abbot) on Apr 13, 2006 at 14:39 UTC
    without using any module...
    #!/usr/bin/perl use strict; use warnings; sub time_to_str { my ($sec, $min, $hour, $mday, $mon, $year) = localtime(shift); return sprintf "%04d%02d%02d%02d%02d%02d", $year+1900, $mon+1, $mday +, $hour, $min, $sec; } sub find_time { my $tstr = shift; my $max = 2**31; my $min = 0; while ($max != $min) { my $mid = int (($max + $min) / 2); my $midstr = time_to_str $mid; if ($tstr gt $midstr) { $min = $mid + 1; } else { $max = $mid; } } return $max; } sub add_seconds { my ($timestr, $seconds) = @_; my $time = find_time $timestr; return time_to_str($time + $seconds) } while (<DATA>) { next if /^\s*(?:#.*)?$/; my ($date, $seconds) = split; printf "%s + %ds = %s\n", $date, $seconds, add_seconds($date, $secon +ds); } __DATA__ # YYYYMMDDhhmmss seconds 20060413020000 900 20060413024500 900 20061231235700 900
Re: getting Date calculation in simpler way
by ambrus (Abbot) on Apr 13, 2006 at 17:18 UTC

    Ok, so first let's see how a module would make this really simple.

    perl -we 'use Date::Manip; $input = "200604131145"; $output = UnixDate(DateCalc(ParseDate($input), "15 minutes"), "%Q%H%M" +); warn $output;'

    Now if you are not allowed to use modules, you may still be able to copy the source of the Date::Manip module (surrounded by braces) to your perl script, or even copy only the relevant parts (I did that once on an online competition with a C library).

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://543058]
Approved by marto
[LanX]: blocked by FW :(
oldtechaa takes a cookie from the platter on the sideboard.
[choroba]: LanX Check it on a phone :)

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2017-04-26 12:08 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (474 votes). Check out past polls.