time format +1 hour

S

Slickuser

I have this value:
20091008155222
YYYY_MM_DD_HH_MM_SS

Is there any module out there if I add 1 hour to my current timestamp,
it will also roll over to DD, MM, and year if possible.
This might happen at 23 hours (0-23), 0-6 days, 0-12 months..

I can put a lot of "if" statement but have to do all possible case.


my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime(time);
$mon += 1;
$year += 1900;

## add on a 0 if less than 10
if ($mon < 10) {
$mon = "0" . $mon;
}
if ($mday < 10) {
$mday = "0" . $mday;
}
if ($hour < 10) {
$hour = "0" . $hour;
}
if ($min < 10) {
$min = "0" . $min;
}
my $timenow = "$year$mon$mday$hour$min$sec\n";
print $timenow;
 
J

Jürgen Exner

Slickuser said:
I have this value:
20091008155222
YYYY_MM_DD_HH_MM_SS

Is there any module out there if I add 1 hour to my current timestamp,
it will also roll over to DD, MM, and year if possible.
This might happen at 23 hours (0-23), 0-6 days, 0-12 months..

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime(time);

What's wrong with a simple

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= localtime(time + 3600);

jue
 
J

Jim Gibson

Slickuser said:
I have this value:
20091008155222
YYYY_MM_DD_HH_MM_SS

Is there any module out there if I add 1 hour to my current timestamp,
it will also roll over to DD, MM, and year if possible.
This might happen at 23 hours (0-23), 0-6 days, 0-12 months..

I can put a lot of "if" statement but have to do all possible case.


my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime(time);
$mon += 1;
$year += 1900;

## add on a 0 if less than 10
if ($mon < 10) {
$mon = "0" . $mon;
}
if ($mday < 10) {
$mday = "0" . $mday;
}
if ($hour < 10) {
$hour = "0" . $hour;
}
if ($min < 10) {
$min = "0" . $min;
}
my $timenow = "$year$mon$mday$hour$min$sec\n";
print $timenow;

If you are doing arithmetic on dates and times, it is best to use a
representation of a Date/Time that supports simple arithmetic. Once
such representation is "seconds-from-a-fixed-date-time", as returned by
the Perl built-in time() function. Now, your problem becomes converting
between the numeric representation and your YYYYMMDDHHMMSS format. See
the DateTime module on CPAN for some help on doing the conversions. The
module Date::Calc can also do arithmetic on dates.
 
J

John W. Krahn

Slickuser said:
I have this value:
20091008155222
YYYY_MM_DD_HH_MM_SS

Is there any module out there if I add 1 hour to my current timestamp,
it will also roll over to DD, MM, and year if possible.
This might happen at 23 hours (0-23), 0-6 days, 0-12 months..

$ perl -le'
use POSIX qw/ mktime strftime /;

my $date = q/20091008155222/;

my ( $cent, $year, $mon, $day, $hour, $min, $sec ) = $date =~ /\d\d/g;

print strftime q/%Y%m%d%H%M%S/, localtime 3600 + mktime $sec, $min,
$hour, $day, $mon - 1, "$cent$year" - 1900;
'
20091008165222




John
 
J

Josef Moellers

Slickuser said:
I have this value:
20091008155222
YYYY_MM_DD_HH_MM_SS

Is there any module out there if I add 1 hour to my current timestamp,
it will also roll over to DD, MM, and year if possible.
This might happen at 23 hours (0-23), 0-6 days, 0-12 months..

Have a look at Date::Calc.
There's a sub called "Add_Delta_DHMS" that will do what you need.

Josef
 
J

Josef Moellers

Jürgen Exner said:
What's wrong with a simple

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= localtime(time + 3600);

It will work in 99.99999% of all cases until you fall over one of these
years where they add/subtract a leap second ;-)

Better use Date::Calc.

Josef
 
S

Slickuser

Forgot to mention that original time is fixed and get modify to a new
one (not local time).

An example below.

my $time_org = "20091009090832";
my $time_mod = "20091009100832";
 
R

Randal L. Schwartz

Slickuser> Forgot to mention that original time is fixed and get modify to a
Slickuser> new one (not local time).

Slickuser> An example below.

Slickuser> my $time_org = "20091009090832";
Slickuser> my $time_mod = "20091009100832";

Is this GMT, or a local time? If a local time, which timezone, and
under what DST rules?
 
P

Peter J. Holzer

It will work in 99.99999% of all cases until you fall over one of these
years where they add/subtract a leap second ;-)

No. The unix time_t value ignores leap seconds. A day is always counted
as 86400 seconds (it wouldn't be possible to compute the time_t value
for future dates otherwise).

hp
 
S

Slickuser

I have this string fixed (opened from a text document) as
"20091009090832" (YYYY_MM_DD_HH_MM_SS).

Now I want +1 hour to this string so it can be "20091009100832".

Sorry for the confusion.
 
R

Randal L. Schwartz

Slickuser> I have this string fixed (opened from a text document) as
Slickuser> "20091009090832" (YYYY_MM_DD_HH_MM_SS).

Slickuser> Now I want +1 hour to this string so it can be "20091009100832".

Slickuser> Sorry for the confusion.

You simply restated the problem without answering my question, and the answer
to you depends on you answering my question, which I will now ask again. If
you don't know the answer to it, then you don't know enough to solve your
problem, and should ask the person who asked you to solve this:

Please answer that. You *need* to know that to "add an hour". Really, you
do.

print "Just another Perl hacker,"; # the original
 
S

Slickuser

Is this GMT, or a local time? If a local time, which timezone, and
Local time, Pacific, and 1 for DST.
 
J

Josef Moellers

Peter said:
No. The unix time_t value ignores leap seconds. A day is always counted
as 86400 seconds (it wouldn't be possible to compute the time_t value
for future dates otherwise).

These leap seconds are a PITA ;-)
It probably depends upon what you define as being "one hour after":
- 3,600 seconds later or
- 1 hour later, but minutes and seconds identical.

The unix time_t counts seconds since the epoch. However, once you try to
convert this into a human readable time onvolving years, months, days,
hours, minutes, seconds, you *do* need to know leap days and seconds to
do that.
So, if you happen to want to know the time and date of *exactly* 1 hour
after *exactly* 11pm on the 31st of december 2008, the answer depends
upon the fact that 2008 had a leap second appended to the last minute of
the year!
If you just added 3,600 seconds to the time_t value of 12/31/2008
11:00:00pm, then you'd end up at 12/31/2008 11:59:60pm.

But I must admit, this doesn't even help *me* and I'm not even sure any
more that I am helping.

Josef, dazed and confused
 
J

Jürgen Exner

Josef Moellers said:
The unix time_t counts seconds since the epoch. However, once you try to
convert this into a human readable time onvolving years, months, days,
hours, minutes, seconds, you *do* need to know leap days and seconds to
do that.
So, if you happen to want to know the time and date of *exactly* 1 hour
after *exactly* 11pm on the 31st of december 2008, the answer depends
upon the fact that 2008 had a leap second appended to the last minute of
the year!

While all this is true I would think that in almost all real-world
scenarios it really doesn't matter if you get a result that is off by
one second. There aren't many applications that need that kind of
precision.
IMO the problem pointed out by Randal is much more significant, because
it doesn't happens once in a blue moon for one second but regularly
twice every year for an hour, i.e. 24 seconds total for leap seconds
since 1972 compared to over 250000 seconds of summer time switching
hours since then.

jue
 
R

Randal L. Schwartz

Slickuser> Local time, Pacific, and 1 for DST.

In that case, you understand that there will be once a year (in fall) where
"add an hour" changes nothing in your string, and once a year (in spring)
where "add an hour" changes the apparent time by two hours. It would be less
ambiguous if you included the timezone as part of your string.

Or maybe you should just use GMT, which doesn't have this problem.
 
P

Peter J. Holzer

These leap seconds are a PITA ;-)
It probably depends upon what you define as being "one hour after":
- 3,600 seconds later or
- 1 hour later, but minutes and seconds identical.

The unix time_t counts seconds since the epoch.

Yes and no. It defines "seconds since the epoch" differently than a
phycisist would. In

http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15

the explicit formula for converting calendar time (in UTC) into "seconds
since the epoch" is given, and it doesn't allow for leap seconds. This
is not an oversight, the text confirms:

| How any changes to the value of seconds since the Epoch are made to
| align to a desired relationship with the current actual time is
| implementation-defined. As represented in seconds since the Epoch, each
| and every day shall be accounted for by exactly 86400 seconds.

While I admit that the language of that section isn't as clear as the
formula, the fact is that all POSIX implementations implement the
formula as given and agree that 2008-01-01T00:00:00Z is 1199145600
"seconds since the epoch" and 2009-01-01T00:00:00Z is 1230768000
"seconds since the epoch", while in the real world there were 31622401
seconds between these two times, not 31622400.

Because "seconds since the epoch" are not really seconds since the epoch
in the physical sense I avoid the term and talk about a "POSIX time_t
value" instead.

However, once you try to convert this into a human readable time
onvolving years, months, days, hours, minutes, seconds, you *do* need
to know leap days and seconds to do that.

You need to know about leap days of course, but these are fixed.
You do not need to know about leap seconds, since they aren't used in
this conversion. However, you do need to know about them for an accurate
implementation of difftime(). Strictly speaking,
difftime(1230768000, 1199145600) should return 31622401.0, but I doubt
there is any implementation which does.
So, if you happen to want to know the time and date of *exactly* 1 hour
after *exactly* 11pm on the 31st of december 2008, the answer depends
upon the fact that 2008 had a leap second appended to the last minute of
the year!
If you just added 3,600 seconds to the time_t value of 12/31/2008
11:00:00pm, then you'd end up at 12/31/2008 11:59:60pm.

Yes, but there is no time_t value corresponding to that time: 1230767999
is 2009-12-31T23:59:59Z, and 1230768000 is 2009-01-01T00:00:00Z by
definition!

time_t value is implementation defined.
But I must admit, this doesn't even help *me* and I'm not even sure any
more that I am helping.

Just ignore leap seconds unless you need to make time measurements which
cannot tolerate a one second error. For "normal" calendar time keeping
you don't need to know about them.

However, daylight savings time is quite a different matter.

hp
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top