Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Is there an official DST border day detection module?

by flowdy (Scribe)
on Oct 27, 2014 at 16:39 UTC ( [id://1105177]=perlquestion: print w/replies, xml ) Need Help??

flowdy has asked for the wisdom of the Perl Monks concerning the following question:

In the test suite of my urgency-based ranking task & time management system some tests fail at days with 23 or 25 hours (i.e. days we have to set the clock because a DST period starts or ends), simply due to the fact that the expected test results are wrong for these days. I kind of cheated by adding to the test description "fails at DST border days", but, well, failing tests are failing tests hence expose non-perfection of the implementation, right?

So, I am looking for an official module that finds out if a given date is a day with <> 24 hours. Sure I could use my own function:

sub detect_dst_clockface_sector { my $t1 = Mktime(@_, 0, 0, 0); my $t2 = Mktime(Add_Delta_Days(@_, 1), 0, 0, 0); my $shift = 24 - ($t2 - $t1) / 3600; return if !$shift; my ($i, $it1, $it2) = 0; while ( $i < 24 ) { $it2 = $t1 + $i * 3600; $it1 = $it2 - 1; $_ = (localtime($_))[2] for $it1, $it2; last if $it2 == ($it1+$shift+1) % 24; } continue { $i++; } if ( $i < 24 ) { return $i, $shift; } else { die "Couldn't figure out position of $shift dst-affected hours +"; } }

in a subcomponent module of my project. But it is idiotic practice to calculate expected values with code to test, so I would rather use something external. Do you know something? Plus, I do not cling to the code above, it seems of poor performance this algorithm, so maybe I could get rid of it in favor of that module searched for alltogether?

Best regards,
flowdy

Replies are listed 'Best First'.
Re: Is there an official DST border day detection module?
by RonW (Parson) on Oct 27, 2014 at 17:26 UTC

    I suggest logging your results in UTC time (aka GMT), only converting to local time when generating a report. That way, the results will be evaluated in a consistent temporal reference.

      Thanks yeah, that would be the way to go, in most cases. Unfortunately, most employers use in their business the official local time of their country instead of UTC. And when there is a due date at 10, a software saying it is at 11 (because it counts only the seconds within working time declared by the user, mapping every segment of checked expenditure to them, so the time-related criteria in urgency calculation is realistic), well, it can turn out as a annoyance for the user to have to calculate around it when entering tasks and planning their time model. That is why I chose local time. I the developer may have to solve these issues, not him.

        There's nothing preventing the users from entering times/dates in local times. Convert the entered times/dates to UTC (or, possibly to a "raw" time value), perform your logic, then convert back to local time.

        I think that Date::Calc] will be very helpful to you.

Re: Is there an official DST border day detection module? (localtime)
by tye (Sage) on Oct 27, 2014 at 20:38 UTC
    sub today_is_24hours { my $now = 60*60*int( time()/60/60 ); # Start of this hour my $hour = ( localtime($now) )[2]; $now -= $hour*60*60; # Start of this day return ( localtime($now) )[8] == ( localtime($now+24*60*60) )[8]; }

    (DST never changes twice in a single day.)

    - tye        

      Hi tye,

      thanks to you a lot. As I want to get amount of hours in the day, I tried to modify your suggestion to:

      sub hours_in_day { my $now = 60*60*int( shift()/60/60 ); # Start of this hour my $hour = ( localtime($now) )[2]; $now -= $hour*60*60; # Start of this day $hour = ( localtime($now+24*60*60) )[2]; $hour -= 24 if int($hour/12); return 24-$hour; }

      But it is not working, hm ...

      Thinking & probing,
      flowdy

        I think your logic is slightly amiss when you calculate the "start of this day". This variant works for me:

        #!/usr/bin/perl -Tw use strict; print "Today: " . hours_in_day (time) . "hours.\n"; print "Sun: " . hours_in_day (time-170000) . "hours.\n"; sub hours_in_day { my $now = 60*60*int( shift()/60/60 ); # Start of this hour my $hour = ( localtime($now) )[2]; $now -= $hour*60*60; # Offset from start of thi +s day $hour = ( localtime($now) )[2]; $hour += 24 unless int($hour/12); return $hour; }

        and gives this output for me (Sunday was the switch from BST to GMT here):

        Today: 24hours. Sun: 25hours.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1105177]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-04-16 07:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found