Re: Olson querying
Rick == Rick Measham r...@measham.id.au writes: Rick $ olson time 13:48 # where is it currently 13:44? Rick $ olson time 13:48 -Cau # where in Australia is it currently 13:44 Does it offset by 4 minutes automatically? :-) -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.posterous.com/ for Smalltalk discussion
Re: Olson querying
Magic! Cheers! Rick Measham On 09/05/2012, at 6:38, mer...@stonehenge.com (Randal L. Schwartz) wrote: Rick == Rick Measham r...@measham.id.au writes: Rick $ olson time 13:48 # where is it currently 13:44? Rick $ olson time 13:48 -Cau # where in Australia is it currently 13:44 Does it offset by 4 minutes automatically? :-) -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.posterous.com/ for Smalltalk discussion -- Message protected for iSite by MailGuard: e-mail anti-virus, anti-spam and content filtering.http://www.mailguard.com.au Click here to report this message as spam: https://login.mailguard.com.au/report/1EHdSoFRAS/5NsrA9R5r7L6i9em677WM1/0 -- Message protected for iSite by MailGuard: e-mail anti-virus, anti-spam and content filtering.http://www.mailguard.com.au
Re: Olson querying
Anthony Ball wrote: a way to query when the DST changes happen. That'll need additions to the API for the timezone objects. I've got some plans to do that, but it's a later stage. -zefram
Re: Olson querying
Dave Rolsky wrote: The use of Date::ISO8601, Date::JD, and Time::Unix seems a bit odd. Can't you use DateTime to do all this stuff and avoid the additional prereqs? Using DateTime would gain minimal convenience. On the downside, it's a heavy module load (both in memory and startup time) and a big dep tree. It's nearly even a circular dep: it requires DT:TZ, so stuff under DT:TZ had best not require DateTime. The prospective App::olson isn't actually a dep of (any version of) DT:TZ, but is closely allied with DT:TZ:Olson. Date::ISO8601 and Date::JD are already used by DT:TZ:Tzfile and DT:TZ:SystemV. Date::ISO8601 is light, and certainly pulls its weight. Date::JD is a bit heavy for what it achieves, due to eager generation of hundreds of subs; it should probably be autoloading. I wouldn't mind replacing the minimal use of Date::JD in DT:TZ:{Tzfile,SystemV} and App::olson with a literal constant. Time::Unix is surprisingly large for what it does, but still small overall, and unproblematic as a dep. We can safely assume that anyone installing DateTime::TimeZone has DateTime, I think. Has it available, sure, but better not to force its use, because of the heaviness and (in many applications) abstraction inversion of doing so. For what it's worth, I use DT:TZ in handful of places, but I usually use it with cheap fake DateTime objects, as seen in the test suites for DT:TZ:{Tzfile,SystemV}. I've never needed DateTime's arithmetic or other facilities; I only need a DateTime-alike as a container for RD values to query timezone objects. In fact, the one place where I do use DateTime is only using it that way, predates me developing the cheaper substitute, and will be switched when I get round to it. So I'm inclined to keep DT:TZ and allied code free of any real dependency on DateTime. -zefram
Re: Olson querying
New version of the query tool attached. This one has a lot more options for searching for zones. It lets you ask questions like: $ olson areas -Cru # where is Russia? Asia Europe $ olson offsets -ICST # what does CST mean? -06 -05 +08 +09:30 +10:30 $ olson zones -Cau -IEST # which zone might EST be in Australia? Australia/Brisbane Australia/Currie Australia/Hobart Australia/Lindeman Australia/Melbourne Australia/Sydney I've got a todo list with a bunch more features that it ought to support searching on, but I think I'm going to handle them by a radical refactoring that yields more of a query language than this collection of options. -zefram #!perl { use 5.006; } use warnings; use strict; use Date::ISO8601 0.000 qw(present_ymd); use DateTime::TimeZone::Olson (); use DateTime::TimeZone::SystemV (); use DateTime::TimeZone::Tzfile (); use Getopt::Std qw(getopts); use Params::Classify qw(is_string); use Time::OlsonTZ::Data (); use Time::Unix qw(time); our $VERSION = 0.000; my $rdn_epoch_cjdn = 1721425; my %command; $command{version} = sub () { getopts(, {}) or die bad options\n; die bad arguments\n if @ARGV; print modules:\nApp::olson $VERSION\n; foreach my $mod (qw( DateTime::TimeZone::Olson DateTime::TimeZone::SystemV DateTime::TimeZone::Tzfile Time::OlsonTZ::Data )) { no strict refs; print $mod ${qq(${mod}::VERSION)}\n; } print Olson database: @{[DateTime::TimeZone::Olson::olson_version]}\n; }; { package FakeUtcDateTime; sub new { my($class, $rdns) = @_; return bless({ rdn = $rdns-[0], sod = $rdns-[1] }, $class); } sub utc_rd_values { ($_[0]-{rdn}, $_[0]-{sod}, 0) } } { package FakeLocalDateTime; sub new { my($class, $rdns) = @_; return bless({ rdn = $rdns-[0], sod = $rdns-[1] }, $class); } sub local_rd_values { ($_[0]-{rdn}, $_[0]-{sod}, 0) } } sub handle_exception($$) { my($val, $err) = @_; if($err =~ /\A time\ [-:TZ0-9]+\ is\ not\ represented\ in\ the\ [!-~]+ \ timezone\ due\ to\ (zone\ disuse|)\b /x) { return $1 eq zone disuse ? ! : ?; } elsif($err ne ) { return *; } else { return $val; } } sub is_exception($) { return is_string($_[0]) $_[0] =~ /\A[!?*]\z/; } sub rdns_offset($$) { my($rdns, $offset) = @_; return $rdns if is_exception($rdns); return $offset if is_exception($offset); my($rdn, $sod) = @$rdns; $sod += $offset; use integer; my $doff = $sod 0 ? -((86399-$sod) / 86400) : $sod / 86400; $rdn += $doff; $sod -= 86400*$doff; return [$rdn, $sod]; } sub present_rdns($) { my($rdns) = @_; return $rdns x 19 if is_exception($rdns); my($rdn, $sod) = @$rdns; use integer; return present_ymd($rdn + $rdn_epoch_cjdn). T.sprintf(%02d:%02d:%02d, $sod/3600, $sod/60%60, $sod%60); } sub now_utc_dt() { my $now_unixtime = time; my $now_utc_rdn = 719163 + int($now_unixtime/86400); my $now_utc_sod = $now_unixtime % 86400; return FakeUtcDateTime-new([$now_utc_rdn, $now_utc_sod]); } my $current_utc_dt = now_utc_dt(); sub utc_to_local_dt($$) { my($utcdt, $offset) = @_; return $utcdt if is_exception($utcdt); return $offset if is_exception($offset); return FakeLocalDateTime-new( rdns_offset([$utcdt-utc_rd_values], $offset)); } sub local_to_utc_dt($$) { my($lcldt, $offset) = @_; return $lcldt if is_exception($lcldt); return $offset if is_exception($offset); return FakeUtcDateTime-new( rdns_offset([$lcldt-utc_rd_values], -$offset)); } sub present_utc_dt($) { my($dt) = @_; return present_rdns(is_exception($dt) ? $dt : [$dt-utc_rd_values]).Z; } sub present_local_dt($) { my($dt) = @_; return present_rdns(is_exception($dt) ? $dt : [$dt-local_rd_values]); } sub present_offset($) { my($offset) = @_; return $offset x 3 if is_exception($offset); my $sign = $offset 0 ? - : +; $offset = abs($offset); use integer; my $disp = sprintf(%s%02d:%02d:%02d, $sign, $offset/3600, $offset/60%60, $offset%60); $disp =~ s/(?::00)+\z//; return $disp; } sub present_initialism($) { my($initialism) = @_; return is_exception($initialism) ? $initialism x 3 : $initialism; } sub present_isdst($) { my($isdst) = @_; return is_exception($isdst) ? $isdst : $isdst ? + : -; } { my $areas; sub areas() { $areas ||= do { my %areas; foreach my $country (
Re: Olson querying
Nice utility. I wouldn't mind something like this too: $ olson time 13:48 # where is it currently 13:44? $ olson time 13:48 -Cau # where in Australia is it currently 13:44 Australia/Currie Australia/Hobart Australia/Lindeman Australia/Melbourne Australia/Sydney Feels like a useful way to offer a limited number of zones to a customer when you know their localtime (eg. in a web interface) Cheers! Rick Measham On 6/03/2012 9:21 AM, Zefram wrote: New version of the query tool attached. This one has a lot more options for searching for zones. It lets you ask questions like: $ olson areas -Cru # where is Russia? Asia Europe $ olson offsets -ICST # what does CST mean? -06 -05 +08 +09:30 +10:30 $ olson zones -Cau -IEST # which zone might EST be in Australia? Australia/Brisbane Australia/Currie Australia/Hobart Australia/Lindeman Australia/Melbourne Australia/Sydney I've got a todo list with a bunch more features that it ought to support searching on, but I think I'm going to handle them by a radical refactoring that yields more of a query language than this collection of options. -zefram smime.p7s Description: S/MIME Cryptographic Signature
Olson querying
As part of the plan for replacing DT:TZ, we discussed the need for a way to list the available timezones, to replace the static DT:TZ:Catalog document. Attached is a prototype of a command-line tool that could take this role. I'd appreciate comments about its current operation and about what it ought to additionally support. -zefram #!perl { use 5.006; } use warnings; use strict; use Date::ISO8601 0.000 qw(present_ymd); use Date::JD 0.005 qw(rdn_to_cjdnn); use DateTime::TimeZone::Olson (); use Getopt::Std qw(getopts); use Params::Classify qw(is_string); use Time::OlsonTZ::Data (); use Time::Unix qw(time); our $VERSION = 0.000; my %command; $command{version} = sub () { getopts(, {}) or die bad options\n; die bad arguments\n if @ARGV; print modules:\nApp::olson $VERSION\n; foreach my $mod (qw(DateTime::TimeZone::Olson Time::OlsonTZ::Data)) { no strict refs; print $mod ${qq(${mod}::VERSION)}\n; } print Olson database: @{[DateTime::TimeZone::Olson::olson_version]}\n; }; { package FakeUtcDateTime; sub new { my($class, $rdns) = @_; return bless({ rdn = $rdns-[0], sod = $rdns-[1] }, $class); } sub utc_rd_values { ($_[0]-{rdn}, $_[0]-{sod}, 0) } } { package FakeLocalDateTime; sub new { my($class, $rdns) = @_; return bless({ rdn = $rdns-[0], sod = $rdns-[1] }, $class); } sub local_rd_values { ($_[0]-{rdn}, $_[0]-{sod}, 0) } } sub handle_exception($$) { my($val, $err) = @_; if($err =~ /\A time\ [-:TZ0-9]+\ is\ not\ represented\ in\ the\ [!-~]+ \ timezone\ due\ to\ (zone\ disuse|)\b /x) { return $1 eq zone disuse ? ! : ?; } elsif($err ne ) { return *; } else { return $val; } } sub is_exception($) { return is_string($_[0]) $_[0] =~ /\A[!?*]\z/; } sub rdns_offset($$) { my($rdns, $offset) = @_; return $rdns if is_exception($rdns); return $offset if is_exception($offset); my($rdn, $sod) = @$rdns; $sod += $offset; use integer; my $doff = $sod 0 ? -((86399-$sod) / 86400) : $sod / 86400; $rdn += $doff; $sod -= 86400*$doff; return [$rdn, $sod]; } sub present_rdns($) { my($rdns) = @_; return $rdns x 19 if is_exception($rdns); my($rdn, $sod) = @$rdns; use integer; return present_ymd(rdn_to_cjdnn($rdn)). T.sprintf(%02d:%02d:%02d, $sod/3600, $sod/60%60, $sod%60); } sub now_utc_dt() { my $now_unixtime = time; my $now_utc_rdn = 719163 + int($now_unixtime/86400); my $now_utc_sod = $now_unixtime % 86400; return FakeUtcDateTime-new([$now_utc_rdn, $now_utc_sod]); } sub utc_to_local_dt($$) { my($utcdt, $offset) = @_; return $utcdt if is_exception($utcdt); return $offset if is_exception($offset); return FakeLocalDateTime-new( rdns_offset([$utcdt-utc_rd_values], $offset)); } sub local_to_utc_dt($$) { my($lcldt, $offset) = @_; return $lcldt if is_exception($lcldt); return $offset if is_exception($offset); return FakeUtcDateTime-new( rdns_offset([$lcldt-utc_rd_values], -$offset)); } sub present_utc_dt($) { my($dt) = @_; return present_rdns(is_exception($dt) ? $dt : [$dt-utc_rd_values]).Z; } sub present_local_dt($) { my($dt) = @_; return present_rdns(is_exception($dt) ? $dt : [$dt-local_rd_values]); } sub present_offset($) { my($offset) = @_; return sprintf(%-9s, $offset x 3) if is_exception($offset); my $sign = $offset 0 ? - : +; $offset = abs($offset); use integer; my $disp = sprintf(%s%02d:%02d:%02d, $sign, $offset/3600, $offset/60%60, $offset%60); $disp =~ s/(?::00)+\z//; return sprintf(%-9s, $disp); } sub present_abbreviation($) { my($abbrev) = @_; return sprintf(%-6s, is_exception($abbrev) ? $abbrev x 3 : $abbrev); } sub present_isdst($) { my($isdst) = @_; return is_exception($isdst) ? $isdst : $isdst ? + : -; } { my $continents; sub continents() { $continents ||= do { my %continents; foreach my $country ( values %{DateTime::TimeZone::Olson::olson_country_selection()} ) { foreach my $region (values %{$country-{regions}}) { $continents{$1} = undef if $region-{timezone_name} =~ m#\A([^/]+)/#; } } \%continents; } } } $command{zones} = sub () { my %opts; getopts(C:N:tado, \%opts) or die bad options\n; die bad arguments\n if @ARGV; my @match; if(exists $opts{C}) { my %conts = map {
Re: Olson querying
On Sun, 4 Mar 2012, Zefram wrote: As part of the plan for replacing DT:TZ, we discussed the need for a way to list the available timezones, to replace the static DT:TZ:Catalog document. Attached is a prototype of a command-line tool that could take this role. I'd appreciate comments about its current operation and about what it ought to additionally support. The use of Date::ISO8601, Date::JD, and Time::Unix seems a bit odd. Can't you use DateTime to do all this stuff and avoid the additional prereqs? We can safely assume that anyone installing DateTime::TimeZone has DateTime, I think. -dave /* http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) */