[also to Dave Rolsky in case he can help]

Dave: in summary, I am proposing a module Time::mkgmtime to provide a
single function, mkgmtime() that behaves exactly as POSIX::mktime()
except using GMT rather than localtime offset. Specifically it handles
denormalised values, see below.

On Thu, Jun 14, 2012 at 01:26:12PM -0400, Ryan Voots wrote:
> On 06/14/2012 12:18 PM, Paul LeoNerd Evans wrote:
> 
> > On Thu, Jun 14, 2012 at 05:13:04PM +0100, Paul LeoNerd Evans wrote:
> >> Time::Local complains about out-of-range values. It cannot do 25th hour
> >> or -3rd day or whatever. Time::mkgmtime specifically allows these, the
> >> same way POSIX::mktime() does.
> Try using the unchecked versions of the functions from Time::Local
> $ perl -MTime::Local=timegm_nocheck -E 'say scalar gmtime timegm_nocheck
> 0,0,-3,12,6-1,2012-1900'
> Mon Jun 11 21:00:00 2012

So, I have tried that and it does appear to work, in that so far I
cannot find a counterexample, a set of values that works for my mkgmtime
but fails timegm_nocheck.

However, this part of documentation scares me:

  If you supply data which is not valid (month 27, second 1,000) the
  results will be unpredictable (so don't do that).

The specific point about my mkgmtime() function is that is allows
denormalised values in the same way that POSIX::mktime() does, and
rounds them in. The 1000th second really -is- the 40th second of the
16th following minute, which may have to round the hour/day/month/year
fields if appropriate. It is because of this that datetime maths,
specifically offsets, become so much simpler. Adding 1 day 3 hours and
12 minutes can simply become:

  my @t = gmtime $time;
  $t[3] += 1;
  $t[2] += 3;
  $t[1] += 12;
  return mkgmtime @time;

This isn't quite so simple if you roundtrip via localtime/mktime because
of discontinuities around DST changes. You may find that if you added an
hour that crossed a DST boundary, you've actually added two.

While it is currently observed that Time::Local::timegm_nocheck()
happens to allow this, it is documented that the results are
unpredictable. That won't do for my purposes if that remains the case.
Either the documentation and the module will have to be altered to
guarantee good results, or I shall have to provide a module that /does/
guarantee these results under denormalisation.

Dave: Do you have any thoughts here? Since it is observed that
Time::Local does in fact cope just fine with denormalised values, would
you be happy changing the documentation and adding some unit tests to
ensure this fact? (I have some good ones if you want). Depending on an
existing, core module is preferrable to creating a new one on CPAN just
to get over this comparatively minor inconvenience.

-- 
Paul "LeoNerd" Evans

leon...@leonerd.org.uk
ICQ# 4135350       |  Registered Linux# 179460
http://www.leonerd.org.uk/

Attachment: signature.asc
Description: Digital signature

Reply via email to