Re: How to check if a DateTime is invalid (again - but this time without using eval)?
Haven't those issues with eval been addressed in more recent versions of Perl? For example, in older Perls this used to reset $@, but now $@ is retained: use strict; use warnings; sub Foo::DESTROY { print "in Foo Destroy\n"; eval { 1 }; print "Foo has \$@ as '$@'\n" return; } eval { my $foo = bless {}, 'Foo'; die "BOOM\n"; }; print "eval with $@\n"; Returns: in Foo Destroy Foo has $@ as '' eval with BOOM On Wed, Jul 5, 2017 at 8:52 AM, Dave Rolsky <auta...@urth.org> wrote: > On Wed, Jul 5, 2017 at 10:23 AM, Eric Brine <ikeg...@adaelis.com> wrote: > >> On Wed, Jul 5, 2017 at 10:59 AM, Thomas (HFM) Wyant < >> harryfm...@comcast.net> wrote: >> >>> One of the edge cases with eval {} is ... >>> >> >> All the edge cases are covered by the previously linked: >> https://metacpan.org/pod/Try::Tiny#BACKGROUND >> > > Yes, this is exactly why I would recommend always using Try::Tiny over > plain eval. > > Cheers, > > Dave Rolsky > http://blog.urth.org > https://github.com/autarch > > -- Bill Moseley mose...@hank.org
Storable and DateTime::Format::Strptime
Howdy! I upgraded Storable on an old app and started to get this error from Storable: Can't store REGEXP items at ... Turns out the ORM we have is setting a DateTime::Format::Strptime formatter on the DateTime objects and the formatter has a regex for the parser. This happens as they are "inflated" from the DB, Some of these are later cached which triggers the error. Should or can the formatter have a Storable hook to remove the parser? Any suggestions on an easy workaround? Granted, it's questionable putting the formatter on the DateTime objects when pulled from the database instead of in, say, a view. But removing it now would mean hunting down all the places where the DateTime objects are rendered for display. use strict; use warnings; use DateTime; use Storable 'nfreeze'; use DateTime::Format::Strptime; my $dt = DateTime->now; my $format = DateTime::Format::Strptime->new( pattern => '%x %X', locale => 'en_us' ); $dt->set_formatter( $format ); nfreeze( $dt ); -- Bill Moseley mose...@hank.org
Re: Did April go missing in Asia/Amman?
Thank you Eric and Zefram! On Sun, Apr 24, 2016 at 10:11 AM, Eric Brine <ikeg...@adaelis.com> wrote: > Released DateTimeX::Start to cpan > http://search.cpan.org/perldoc?DateTimeX::Start > > On Sat, Apr 23, 2016 at 5:29 PM, Eric Brine <ikeg...@adaelis.com> wrote: > >> Thanks! Yeah, knowing that, I can easily make my code only consider >> minutes. I'll also incorporate your "rd" optimziation >> >> On Sat, Apr 23, 2016 at 5:16 PM, Zefram <zef...@fysh.org> wrote: >> >>> Eric Brine wrote: >>> >Thanks. I'll study this. I didn't think dividing by 60, adding 60 and >>> >subtracting 60 was safe before of leap seconds. >>> >>> POSIX time, what DateTime calls "epoch" time, doesn't count leap seconds. >>> Each multiple of 60 corresponds to the top of a UTC minute. >>> >>> -zefram >>> >> >> > -- Bill Moseley mose...@hank.org
Re: Did April go missing in Asia/Amman?
On Sat, Apr 23, 2016 at 10:14 AM, Zefram <zef...@fysh.org> wrote: > Bill Moseley wrote: > >hour=> 12, # Assume this exists > > This does not always exist. Africa/Khartoum on 2000-01-15, for example. > In fact, thanks to cases such as Pacific/Apia on 2011-12-30, not only is > there no hour that exists on every day in every zone, there are actually > some zone days for which no hour exists. > $ perl -le 'use DateTime; my $dt = DateTime->new( year => 2000, month => 1, day => 15, hour => 12 )->set_time_zone( "Africa/Khartoum")' Invalid local time for date in time zone: Africa/Khartoum Fun. The code Eric pointed me to sets the hour to 12 on a floating $dt and then sets the timezone. Sounds like there's cases where that could still fail. If I cannot assume hour 12 exists (or assume anything) how can I find my starting valid $dt in the target time zone to look back for the starting time? > > >And for the end time of the month (to the second): > > Rather than subtract a second and use a <= comparison, it's cleaner to > use the start time of the next month and a < comparison. > Yes, that makes sense. This is for a form where a user can enter a start and end date (not a time) and expect to see all events during those days. i.e. From 2016-04-01 to 2016-04-30. The form's defaults are suppose to be the dates for the *current* start and end of the month *in the user's time zone*. I then need to convert those into a timestamp (including offset) that the database can compare against. The database's session is not in the target timezone so I cannot simply compare the date part. > > >I was thinking of an implementation that assumed DST change happened at an > >hour boundary and simply try incrementing hours until no more exceptions. > > That's a bad assumption. You can assume *minute* boundaries, but > not hours. > > -zefram > Thanks! -- Bill Moseley mose...@hank.org
Re: Did April go missing in Asia/Amman?
Thanks -- that makes sense. My error not considering that 00:00:00 might not exist on the first of the month. Suggestion how best to do this? I'm running queries where I want to fetch rows with a timestamp within a given month -- but that time range should be in the time zone of the user I'm running the query for. In other words, I'm trying to find the start and end times for the current month based on a given timezone and then use those in my database query. On Fri, Apr 22, 2016 at 3:51 PM, Zefram <zef...@fysh.org> wrote: > Bill Moseley wrote: > >Why can't I truncate to the month? > > Because 2016-04-01T00:00:00 didn't exist in Asia/Amman. Its DST rules > include a switch from winter time to summer time at 24:00 on the last > Thursday in March. This has the effect of skipping the hour from 00:00 > to 01:00 on some Friday morning. This year the last Thursday in March was > the last day in March, so the affected Friday was the first day of April. > > -zefram > -- Bill Moseley mose...@hank.org
Did April go missing in Asia/Amman?
Happy (almost end) of April! $DateTime::VERSION = '0.77'; $DateTime::Locale::VERSION = '0.45'; $DateTime::TimeZone::VERSION = '1.46'; Can someone explain what's happening here? Did April vanish? My end goal is to get the start of the month in a specific timezone. Here we are now: $ perl -wle 'use DateTime; my $t = DateTime->now->set_time_zone( "Asia/Amman" ); print $t' 2016-04-23T00:53:02 Why can't I truncate to the month? $ perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Amman" )->truncate( to => "month" ); print $t' Invalid local time for date in time zone: Asia/Amman Try a few days from now... $ perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Amman" )->add( days => 7)->truncate( to => "month" ); print $t' Invalid local time for date in time zone: Asia/Amman But add enough days to roll over to May: $ perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Amman" )->add( days => 8)->truncate( to => "month" ); print $t' 2016-05-01T00:00:00 Try going backwards: $ perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Amman" )->subtract( days => 22)->truncate( to => "month" ); print $t' Invalid local time for date in time zone: Asia/Amman And make it to march: $ perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Amman" )->subtract( days => 23)->truncate( to => "month" ); print $t' 2016-03-01T00:00:00 Some kind of April fool's issue? Exists elsewhere in same offsets: perl -wle 'use DateTime; my $t = DateTime->now( time_zone => "Asia/Tel_Aviv" )->subtract( days => 22)->truncate( to => "month" ); print $t' 2016-04-01T00:00:00 -- Bill Moseley mose...@hank.org
Hard to keep up with DST changes
Four days lead time isn't quite enough! http://www.thecairopost.com/news/147029/news/cabinet-suspends-daylight-saving-time-for-2015 Was suppose to be the 24th: $ perl -le 'use DateTime; $dt = DateTime-new( year = 2015, month = 4, day = 24, time_zone = Africa/Cairo )' Invalid local time for date in time zone: Africa/Cairo -- Bill Moseley mose...@hank.org
Re: localized date formats
I lost track of this and it came up again this morning. I'm not having a lot of luck researching what should be done. I see in http://cldr.unicode.org/cldr-features#TOC-Locale-specific-patterns-for-formatting-and-parsingthere's a heading Translation of Names where there's a list item timezones, timezone cities but no link. But, perhaps a more on point and useful question is: I need to always show times with a timezone, and in a way that is localized for the user.What is the best way to do that currently with DateTime? Should EST be translated? What about UTC? (e.g. if using UTC + offset) I suspect UTC + offset isn't a very friendly timezone for many people. Locale ar-sa shows the following. Is America/New_York and EST not translated on purpose? using format: full: الأحد، 26 يناير، 2014 America/New_York 10:37:42 ص using format: long: 26 يناير، 2014 EST 10:37:42 ص using format: medium : 26/01/2014 10:37:42 ص using format: short : 26/1/2014 10:37 ص On Thu, Jan 16, 2014 at 2:29 PM, Bill Moseley mose...@hank.org wrote: I would like to simplify our localization of dates and, if possible, just use this format for timestamps: $dt-strftime( '%x %X' ); First question, is there any difference between the above and this? join ' ' , $dt-format_cldr( $locale-date_format_default, $locale-time_format_default ) Second, do timezones get localized? For example, here's the default formats for ko: using format: full: 2014년 1월 16일 목요일 오후 05시 10분 28초 America/New_York using format: long: 2014년 1월 16일 오후 05시 10분 28초 EST using format: medium : 2014. 1. 16. 오후 5:10:28 using format: short : 14. 1. 16. 오후 5:10 Won't be using the full format, but showing a timezone is needed. Can (or does?) EST get localized? Thanks, -- Bill Moseley mose...@hank.org -- Bill Moseley mose...@hank.org
Re: localized date formats
On Sun, Jan 26, 2014 at 7:34 PM, Dave Rolsky auta...@urth.org wrote: I never got around to doing the time zone localization work. At this point, DateTime::Locale is _years_ out of date with regards to CLDR. The approach I was using to parse CLDR and generate locales was not very robust, so when the CLDR files changed it was a huge amount of work to release a new DateTime::Locale. All this is to say that we could really use an updated DateTime::Locale ;) There are a few ways to do this: 1. Essentially what I'm doing now - which can be good enough, but is hard to get 100% correct because of things like fallback locales, locale inheritance, etc. 2. Implement an ICU library in Perl that handles the full lookup reslution logic required by CLDR. Said logic was not actually documented anywhere last I looked, of course. So that means poking around in the Java and/or C libraries to figure out what it should do. 3. Implement Perl bindings to libicu. I like this idea except I wonder if this makes Windows support much harder. On the plus side, it'd almost certainly be faster than #2 and much more correct than #1. Yes, that does sound like the way to go. I'll ask at work if anyone has experience with libicu, but it wouldn't be anyone also with XS experience. Any suggestions on what to do in the near term working with current DateTime? Punt with 26 يناير، 2014 EST 10:37:42 ص? Thanks, -- Bill Moseley mose...@hank.org
localized date formats
I would like to simplify our localization of dates and, if possible, just use this format for timestamps: $dt-strftime( '%x %X' ); First question, is there any difference between the above and this? join ' ' , $dt-format_cldr( $locale-date_format_default, $locale-time_format_default ) Second, do timezones get localized? For example, here's the default formats for ko: using format: full: 2014년 1월 16일 목요일 오후 05시 10분 28초 America/New_York using format: long: 2014년 1월 16일 오후 05시 10분 28초 EST using format: medium : 2014. 1. 16. 오후 5:10:28 using format: short : 14. 1. 16. 오후 5:10 Won't be using the full format, but showing a timezone is needed. Can (or does?) EST get localized? Thanks, -- Bill Moseley mose...@hank.org
Re: Invalid version format
Thanks Dave for looking at this. On Tue, Jan 7, 2014 at 1:53 PM, Dave Rolsky auta...@urth.org wrote: On Mon, 6 Jan 2014, Bill Moseley wrote: I have this code running in a Catalyst app running under mod_perl: I'm inclined to blame mod_perl, since in my experience it tends to do weird things when loading modules, depending on how you load them (PerlRequire vs in module loaded via a handler, etc.). Yes, that was one of my guesses, too. But, I find it very odd that only one process does this. And often within the first or second request that child process handles. That message Invalid version format (non-numeric data) comes from version.pm (the XS part). It would be nice to know what that non-numeric data is, so we rebuilt a new version.pm package adding more debugging. And, as you might expect, the problem has not resurfaced with the debugging code in place. The bit in your other message about attempt to reload ... aborted makes me wonder if you are for some reason using Apache(2)::Reload or something similar in production. If you are, you really shouldn't. We are not using Apache2::Reload. I'm pretty sure that's just the same issue as Invalid version format (non-numeric data). Perl fails to compile TimeZone::America::LosAngeles and spits out that invalid version error. Then subsequent attempts to compile it in the same process generates the attempt to reload error. I still don't see how this is an issue with DateTime. Seems more like something bugging on the machine. You may just want to punt and run the app via starman or something like that, too. I find this to be much simpler when using Catalyst. There's less magic. Yes, I agree about Starman. Much cleaner. Unfortunately, the operations team isn't quite ready for the cutting edge -- we are on 5.10.1, after all. :). -dave /* http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) */ -- Bill Moseley mose...@hank.org
Invalid version format
This is a long-shot/stabbing-in-the-dark post -- and I'm guessing this might not have anything to do with DateTime. Anyone have any suggestions what might be happening here? I have this code running in a Catalyst app running under mod_perl: try { $c-stash-{timezone} = DateTime::TimeZone-new( name = $time_zone ); } catch { $c-log-error( Timezone '$time_zone' is invalid for account $account: $_ ); }; And I'm seeing this in the logs: [ERROR] Timezone 'America/Los_Angeles' is invalid for account 77368: *Invalid version format (non-numeric data)* at /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm line 17. BEGIN failed--compilation aborted at /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm line 17. Compilation failed in require at (eval 7248) line 3. Compiles fine: $ perl -c /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm syntax OK On the same machine with same Perl: $ perl -le 'use DateTime; my $tz = DateTime::TimeZone-new( name = America/Los_Angeles ); print $tz-name' America/Los_Angeles The app seems to run fine for quite some time, then it starts logging the error above -- and oddly, it seems to be mostly the same process ID that generates the errors. There's 30 Apache processes. That is, I include the PID in the logs so I can do this: $ fgrep -r Angeles error_log-20140106 | perl -nle 'print $1 if /pid:(\d+)/' | sort | uniq -c 21 31535 6 32763 So, out of 30 Apache processes the errors are happing on only two PIDs and mostly on one. Here's line 17. $ sed -n 17p /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm use Class::Singleton 1.03; $ perl -c /usr/share/perl5/Class/Singleton.pm /usr/share/perl5/Class/Singleton.pm syntax OK On an older CentOS machine: This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi $ perl -MDateTime::TimeZone::America::Los_Angeles -le 'print DateTime::TimeZone::America::Los_Angeles-VERSION' 1.46 $ perl -MClass::Singleton -le 'print Class::Singleton-VERSION' 1.4 -- Bill Moseley mose...@hank.org
Re: Invalid version format
Oh, and there's a different error message I'm seeing at the same place in the code: [ERROR] Timezone 'America/Los_Angeles' is invalid for account 77368: Attempt to reload DateTime/TimeZone/America/Los_Angeles.pm aborted. Compilation failed in require at (eval 7258) line 3. On Mon, Jan 6, 2014 at 9:03 PM, Bill Moseley mose...@hank.org wrote: This is a long-shot/stabbing-in-the-dark post -- and I'm guessing this might not have anything to do with DateTime. Anyone have any suggestions what might be happening here? I have this code running in a Catalyst app running under mod_perl: try { $c-stash-{timezone} = DateTime::TimeZone-new( name = $time_zone ); } catch { $c-log-error( Timezone '$time_zone' is invalid for account $account: $_ ); }; And I'm seeing this in the logs: [ERROR] Timezone 'America/Los_Angeles' is invalid for account 77368: *Invalid version format (non-numeric data)* at /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm line 17. BEGIN failed--compilation aborted at /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm line 17. Compilation failed in require at (eval 7248) line 3. Compiles fine: $ perl -c /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm syntax OK On the same machine with same Perl: $ perl -le 'use DateTime; my $tz = DateTime::TimeZone-new( name = America/Los_Angeles ); print $tz-name' America/Los_Angeles The app seems to run fine for quite some time, then it starts logging the error above -- and oddly, it seems to be mostly the same process ID that generates the errors. There's 30 Apache processes. That is, I include the PID in the logs so I can do this: $ fgrep -r Angeles error_log-20140106 | perl -nle 'print $1 if /pid:(\d+)/' | sort | uniq -c 21 31535 6 32763 So, out of 30 Apache processes the errors are happing on only two PIDs and mostly on one. Here's line 17. $ sed -n 17p /usr/share/perl5/vendor_perl/DateTime/TimeZone/America/Los_Angeles.pm use Class::Singleton 1.03; $ perl -c /usr/share/perl5/Class/Singleton.pm /usr/share/perl5/Class/Singleton.pm syntax OK On an older CentOS machine: This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi $ perl -MDateTime::TimeZone::America::Los_Angeles -le 'print DateTime::TimeZone::America::Los_Angeles-VERSION' 1.46 $ perl -MClass::Singleton -le 'print Class::Singleton-VERSION' 1.4 -- Bill Moseley mose...@hank.org -- Bill Moseley mose...@hank.org
delta_data and time zones
I was looking at http://search.cpan.org/~drolsky/DateTime-1.03/lib/DateTime.pm where it says: The delta_md and delta_days methods truncate the duration so that any fractional portion of a day is ignored. Both of these methods operate on the date portion of a datetime only, *and so effectively ignore the time zone*. What I'm wondering is if the dates are not floating should they be set to, say, UTC, before comparing -- apples to apples, so to speak. This is what triggered this: my $dt1 = DateTime-new( year = 2013, month = 9, day = 15, hour = 20, time_zone = 'America/Los_Angeles' ); my $dt2 = $dt1-clone; my $dt3 = $dt1-clone; my $dt4 = $dt1-clone; $dt2-set_time_zone( 'Australia/Perth' ); print $dt1-strftime( '%F %T %z' ) . \n; print $dt2-strftime( '%F %T %z' ) . \n; my $days = $dt2-delta_days( $dt1 )-delta_days; print $days days apart\n; $dt3-set_time_zone( 'UTC' ); $dt4-set_time_zone( 'UTC' ); $days = $dt4-delta_days( $dt3 )-delta_days; print $days days apart in UTC\n; 2013-09-15 20:00:00 -0700 2013-09-16 11:00:00 +0800 1 days apart 0 days apart in UTC I'm frankly not sure what delta days should show there. Same point in time but also the dates are different. Should DateTime set them to the same timezone before comparing? Or is this left to the user to decided this? -- Bill Moseley mose...@hank.org
Re: DateTime setting invalid zone.
On Wed, Mar 13, 2013 at 9:10 AM, Dave Rolsky auta...@urth.org wrote: On Tue, 12 Mar 2013, Bill Moseley wrote: So, I found some old that wrapped a set_time_zone in an eval. my $dt = DateTime-new( year = 2013, month = 3, day = 10, hour = 2, minute = 4, time_zone = 'floating', ); eval { $dt-set_time_zone( 'America/Los_Angeles' ); }; print $dt . $dt-time_zone . \n; The code was using the eval to check if the timezone set failed, and if it did went on to do something else with $dt (like set to UTC). But, it seems like even if it fails the time zone gets set. The above returns this invalid time: 2013-03-10T02:04:00 DateTime::TimeZone::America::**Los_Angeles=HASH(**0x7fc4c2aafc90) My question is should DateTime associate that timezone to $dt if the set_time_zone call actually throws an exception? This is almost certainly a bug. Ok, filed as: https://rt.cpan.org/Ticket/Display.html?id=83940 Thanks, -- Bill Moseley mose...@hank.org
DateTime setting invalid zone.
So, I found some old that wrapped a set_time_zone in an eval. my $dt = DateTime-new( year = 2013, month = 3, day = 10, hour = 2, minute = 4, time_zone = 'floating', ); eval { $dt-set_time_zone( 'America/Los_Angeles' ); }; print $dt . $dt-time_zone . \n; The code was using the eval to check if the timezone set failed, and if it did went on to do something else with $dt (like set to UTC). But, it seems like even if it fails the time zone gets set. The above returns this invalid time: 2013-03-10T02:04:00 DateTime::TimeZone::America::Los_Angeles=HASH(0x7fc4c2aafc90) My question is should DateTime associate that timezone to $dt if the set_time_zone call actually throws an exception? -- Bill Moseley mose...@hank.org
Re: How to correctly add a duration to not have it result in invalid date?
On Sun, Mar 10, 2013 at 4:59 PM, Jim Monty jim.mo...@yahoo.com wrote: I believe this is how you might represent the RELATIVE time noon in Caracas on October 12, 2018 using the iCalendar standard: DTSTART;TZID=America/Caracas:20181012T12 So, to compare that to some point in time (e.g. now() ) it must be turned into, well, a point in time like UTC based on what it knows about timezones -- at the moment. It's imposible to know what point in time that is until it actually happens, right? It's politics. Hard to imagine storing that form in a database and doing queries where offset calculations must be done at the time a query is run. Seems very expensive. The iCalendar standard specifies how to handle daylight/standard time boundary cases such as when the same time occurs twice on the same day, or when a time doesn't occur on a transitional day—like today in most of the United States! You know, yesterday I got curious and set both my Android phone and my wife's iPhone for a 2:30am alarm. I was curious when it would go off. Unfortunately, I told my wife about this and the experiment was quickly called off. -- Bill Moseley mose...@hank.org
Re: How to correctly add a duration to not have it result in invalid date?
I don't want to drag discussion on too much longer, and moving way off the original topic, but I do have an implementation question. On Fri, Mar 8, 2013 at 11:48 PM, Jim Monty jim.mo...@yahoo.com wrote: Bill Moseley wrote: UTC is a timezone, too. Yes, poor choice of words. That sentence I wrote doesn't make much sense. I think I was saying to represent a *point in time* you need a timezone, where a timezone is an offset from UTC (including +00:00 offset). I was thinking about Postgresql at that time. But, that's still wrong for the word timezone. I'm not sure how Postgresql internally represents its timestamp with time zone, but it looks more like it's a timestamp with offset. 2012-09-07 15:26:40.338969-07 Offset is from UTC, of course, so that's always a point in time, correct? I think this is the point Karen was emphasizing: don't record times in a computer database in local time (in time zones) because these expressions of time are rule-based and have too many anomalies in them, which UTC representations of time do not have: a missing hour in some days, a repeated hour in other days, etc. Again, I agree with Karen. There's no perfect answer, right? We (humans) mostly work with local times. Say, I set my alarm for 9am local time on March 8th 2015 (when DST is scheduled to begin) and then convert that to UTC and store. Then if DST is abolished between now and then my alarm will go off at the wrong local time. So, here's the implementation question. In a web app a user might enter a time, say 9:00am in the future, when some event should happen. We know their timezone is America/New_York. So, we create a DateTime object DateTime-new ( hour = 9, time_zone = 'America/New_York', ... ); Then we use DateTime::Format::Pg to format that to store in a timestamp with time zone column. Am I correct that DateTime (or the formatter) does its best to determine the * offset* from UTC at that time in the future and stores that? Would you implement that differently? But, between now and that future time politics could change DST resulting in the event not really happening at 9am in New York on that day, correct? That's a risk. There's too many ambiguities. Does the user really mean 9am in New York? Or 9am in whatever their current time zone is on that day? Maybe in this case should really store with a local time zone 9am America/New_York. Probably best to not schedule anything too far into the future... -- Bill Moseley mose...@hank.org
Re: How to correctly add a duration to not have it result in invalid date?
Thanks for the responses! With fifteen or so developers with all different levels of Perl skills not all are going to understand or know the specifics of when duration math might fail. And the hard part is it might not fail for months or years after the code is written. Obviously, they should understand that adding a duration of, say, days may not mean exactly multiples 24 hours, and it could fail. But, I'm wondering if there's an idiom or rule I could provide them so that the math will at least not fail. Like, always defined durations in terms of hours (or seconds?) or always convert to UTC before adding a duration. True, there's no easy solution. What would happen if duration calculations were always done in UTC? That would avoid DST-based failures. It does so by applying a different meaning of day from that which you're currently using. Again, developers of varying skills come and go and work on existing code. So, they may not have any idea that $start_time has a timezone or think about DST issues. Or that a day isn't always 24 hours. $access-disable if $start_time-add( days = $day_limit ) $now; That might be important contractually that it happens at some point instead of never. What if DatTime Duration objects had a flag to say do the math in UTC? Would that avoid the problem if it possibly failing? $access-disable if $start_time-add( days = $day_limit, in_utc = 1 ) $now; Maybe you actually want a definite UT time for the end of the period. If that's the case, you probably want to interpret the duration in UT. Or maybe you need the end of the period to be defined in local time. In that case you'd be better just storing a notional local time without regard to current projection of whether DST will skip it. (You do that with DateTime by using the floating pseudo-timezone.) In my experience the floating times open up other headaches. We store all times with a timezone -- we would rarely have something like 9am your time because of the ambiguity. Thanks very much for the comments. -- Bill Moseley mose...@hank.org
Re: How to correctly add a duration to not have it result in invalid date?
On Fri, Mar 8, 2013 at 3:04 PM, Karen Etheridge p...@froods.org wrote: my $0.02: **always** store timestamps in ISO8601 format (UTC), or in unix epoch (integer) format **only**. Local timezones should only get applied when rendering data for user consumption - i.e. as late as possible, and after all calculations have been performed. When processing timestamps input by a user, convert to UTC as soon as possible, before storage and before applying any math. I know what you are saying and it's good advice. UTC is a timezone, too. If you want to represent a point in time so that you can later render it in a user's timezone or compare it to another time you must include the time zone. In our database we use timestamp with time zone and it doesn't matter what timezone the database session uses as long as we use the timezone when parsing the column data. If you have two DateTime objects (where is_floating is false) then AFAIK they can be compared regardless of time zone of each DateTime, object. That is, they both represent a point in time. When rendering we convert to the user's timezone (as they have chosen in their preferences). And as Zefram noted, durations are not arithmetically well behaved, and so it using UTC is useful when working with durations for the DST issues I originally posted about. There's a good (and lengthy) discussion at https://metacpan.org/module/DateTime#How-DateTime-Math-Works, which ends with very similar advice. Good read, yes. -- Bill Moseley mose...@hank.org
How to correctly add a duration to not have it result in invalid date?
Last night abou 2:15am we had some automated tests fail with this error: Invalid local time for date in time zone: America/Los_Angeles The problem was that (for some reason) we had a duration object of ( years = 7, days = 1 ) which we added to DateTime-now which ended up March 8, 2020 which is a DST change -- and 2:15am does not exist in that time zone on that date. If $dt and $duration can be anything, what's the best way to prevent adding a $duration to a $dt and having it land on a non-existent date? I realize that durations are a bit ambiguous, but is it reasonable to write something like $expires_time = $start_time-clone-add( days = $expire_days ); # or even ( years = 7, days = 1 ) like above and not have it throw an exception? I suspect most of us expect (and hope) that $expires_days in the future will exist. Or should we always write: $dt-add( hours = $expires_days * 24 ); What would happen if duration calculations were always done in UTC? $tz = $dt-time_zone; $dt-set_time_zone( 'UTC' ); $dt += $duration; $dt-set_time_zone( $tz ); What advice should I give to our developers about adding durations safely? It's a common operaton in our apps. Thanks, -- Bill Moseley mose...@hank.org
Re: Time::OlsonTZ::Data 0.201210 announcement
On Mon, Nov 12, 2012 at 7:07 PM, Zefram zef...@fysh.org wrote: Shortly available from all good CPAN mirrors: file: $CPAN/authors/id/Z/ZE/ZEFRAM/Time-OlsonTZ-Data-0.201210.tar.gz size: 592407 bytes md5: 138a1802d50d8315475b66f2c9811f0a Changes from the previous release: * Olson database version 2012j (code 2012j, data 2012j): 440 canonical zones, 142 links Hope this isn't too dumb of a question, but how does one determine when to upgrade to these newer modules. I was wondering about this because I noticed today that some of our production servers have DateTime from 2009 installed. Although there doesn't seem like any significant change in DateTime since then, maybe DateTime depends on something that does matter. -- Bill Moseley mose...@hank.org
The default datetime format for the object’s locale
We have been using formats %c, %x and %X for localizing dates based on Locale. Mostly works ok, but for Korean we are getting this: 2012. 10. 18. 오후 4:09:05 where (I've been told) we would like this format: 2012년 10월 22일 월요일 오후 01:44 PDT Is this formatting done in DateTime? I'm wondering how we can set the default format used by %c for a given locale. In a web app what we are currently doing is setting DateTime-DefaultLocale() per request. The DateTime objects are inflated from database rows with DBIC. -- Bill Moseley mose...@hank.org
Adding methods to DateTime.
Our apps (and the modules they use) use DateTime extensively. We have the need to do a lot of common operations on DateTime objects, for example checking if a DateTime object is in the future. So, I'm wondering what's the recommended approach to provide these common methods. I think what I'd do is add a method $dt-is_in_future, but I'm not clear how we can subclass DateTime since DateTime-new is used directly in code we don't control. I could just stuffhttp://markmail.org/message/pkyimhz5ufwla4ng#query:+page:1+mid:jqxwqrsz564eoimo+state:resultsthe is_in_future() method into the DateTime namespace, or I could use Class::Injection, for example. The other approach is a utility module using Exporter[*] -- then do is_in_future( $dt ), but I'm not thrilled by that. Or maybe use a Moose Role and bring in the method into where ever it's needed and then do: $self-start_time_in_future; Where: with 'My::DateTime::Util'; sub start_time_in_future { my $self = shift; return $self-is_in_future( $self-start_time ); } But, of all of those I'd prefer to do $dt-is_in_future. Is there a recommend approach? (Ok is_in_future is a bad example because it's so easy to write the check directly.) * This started out as a Moose question because I saw some code added to our app that was using Moose Roles as an Exporter-replacement -- that is using with to bring in the role but then calling the code as functions not as methods. Thanks, -- Bill Moseley mose...@hank.org
Re: Adding methods to DateTime.
Thanks for the feedback everyone. On Wed, Sep 21, 2011 at 12:20 AM, Zefram zef...@fysh.org wrote: Bill Moseley wrote: The other approach is a utility module using Exporter[*] -- then do is_in_future( $dt ), but I'm not thrilled by that. This is the most sensible approach. It won't step on anyone else's toes. Yes, and it's a time-honored usage and probably the way to go. What doesn't thrill me by that approach is our old code has a collection of modules like this in various Util namespaces, and looking at them it's clear to see that it's often really code that the programmer didn't know where else to put.Perhaps that's a separate issue, though, but often it's indicative of a design problem. Hard to articulate, but sets off waring bells in the back of my head. ;) Kind of like seeing C for loops in Perl. Plus, if is_in_future() is something that only can be passed a DateTime then it kind of feels like it's a method. Don't worry too much about which syntax you're using. Are you saying don't worry that a Moose Role is being used an an Exporter replacement? Here's my original post of the code that is doing that: http://www.nntp.perl.org/group/perl.moose/2011/09/msg2236.html Thanks again, -- Bill Moseley mose...@hank.org
Re: DateTime::Locale::load
On Sat, Nov 20, 2010 at 8:09 PM, Dave Rolsky auta...@urth.org wrote: If there is a locale in DateTime::Locale for the id, then it will provide the same set of datetime localization information as any other locale. Does that answer your question? Yes. Thanks. -- Bill Moseley mose...@hank.org
DateTime::Locale::load
First, in load() there's this line: die Invalid locale name or id: $name\n; Can the newline be removed? It's not that hard to track down, but it would be nice to see where it's coming from. Second, is all locale information provided in the DateTime::Locale classes? I guess my question is if we start supporting more languages in our app is there other system-level language files that need to be updated other than just DateTime? (i.e. system locale packages). Thanks, -- Bill Moseley mose...@hank.org
Re: DateTime::Locale::load
On Sat, Nov 20, 2010 at 10:17 AM, Dave Rolsky auta...@urth.org wrote: That might be better as a croak anyway. Yes, probably. I have full backtrace on errors in the logs, but the error that gets emailed out is just the message. But, might be helpful for others. What is all locale information? If you mean everything in the CLDR project, no, it's not even close. In fact, it's not even all the datetime-related info in CLDR. I've been wanting to write a full Locale::CLDR module for a while, but my round tuits seem to have gotten lost in the mail. Sorry, I knew I asked the wrong question after sending. I realize my knowledge in this area is lacking... We use Locale::Maketext in a web application (with language classes like MyApp::I18N::en_us) and when a user selects a language a Locale::Maketext handle is created for the request. We also call DateTime-DefaultLocale( $tag ) to localize formatted dates. What happened was our translators added a new language file that didn't use the correct language code, so that's when we saw the Invalid locale name or id error. That was fixed by just renaming the language file so the correct code was used. At least it made DateTime not throw an error. But that made me wonder if there was anything additional required to support the new languages on the server -- or if the fact that DateTime didn't complain about the locale was enough. I.e. does our translation team need to notify the team that manages the servers when a new language is added. -- Bill Moseley mose...@hank.org
Is DateTime::TimeZone-all_names complete?
I just got a ticket assigned from support that says: No major cities are listed for India (i.e. Delhi, Bangalore, Chennai, Mumbai, etc.) under the timezone drop down box. Is this the complete list of time zones that can be used with DateTime? $ perl -MDateTime::TimeZone -le 'print scalar @{DateTime::TimeZone-all_names}' 401 Seems pretty close to http://en.wikipedia.org/wiki/List_of_tz_database_time_zones Excuse my ignorance of TZ values for India, but are there timezone names corresponding to those cities? -- Bill Moseley mose...@hank.org
modified2010-02-02T24:02:01Z/modified
I have a small script for fetching new mail from Gmail, and DateTime::Format::ISO8601 (well DateTime) is choking when it gets to this in the Gmail response: modified2010-02-02T24:02:01Z/modified issued2010-02-02T24:02:01Z/issued Those are incorrect dates, right? That is, DateTime is correct in throwing an error? The Date: header for the email in question is: Date: Tue, 02 Feb 2010 00:02:01 + -- Bill Moseley mose...@hank.org
Re: time_zone and DateTime::Format::Strptime
On Tue, Dec 15, 2009 at 5:28 AM, Kevin McGrath kmcgr...@baknet.com wrote: Doing the work in parse_datetime does not work for me. In fact I almost never call parse_datetime directly and when I do it's to get the datetime passed in from a form into UTC. I need/want the time_zone conversion to also happen within the format_datetime function when necessary. Does it have to happen within the formatting? I use something like this: [% user_time( user.expire_date ).strftime( user.time_pattern || '%x %X' ) %] Where user_time is a closure that simply does $dt-clone-set_time_zone( $current_user-time_zone ); A VMethod would be cleaner, but I was lazy. -- Bill Moseley mose...@hank.org
Re: Potential DateTime DOS Attack
On Tue, Dec 15, 2009 at 6:12 PM, Lyle webmas...@cosmicperl.com wrote: Michael G Schwern wrote: Clever watchdogs can prevent this from bringing down a server, but I think we can all agree that a date library should not be the source of DOS attacks. Maybe a warning of this in the POD would be enough? Or a more active built in restriction on future dates that users of DataTime must manually override... Would a global be too ugly for a short-term fix? $DateTime::MaxFutureYears = 20; # no dates more than 20 years from current year. -- Bill Moseley mose...@hank.org
Re: Potential DateTime DOS Attack
On Tue, Dec 15, 2009 at 7:58 PM, J. Shirley jshir...@gmail.com wrote: My vote goes for no changes, as it is in the POD as a warning and has existing for a very long time. The better fix is to write better applications. Wise words. It's about time all those existing organizations and people that earn their livelihood running massive legacy applications got off their butts and rewrote them. Today. ;) -- Bill Moseley mose...@hank.org
Re: Potential DateTime DOS Attack
On Tue, Dec 15, 2009 at 9:21 PM, J. Shirley jshir...@gmail.com wrote: Perhaps I'm cynical, but in my mind the type of people who write bad applications not only wouldn't care about potential DateTime DoS attacks, but they would have many more egregious offenses. That's true, but you are wrong that people with poorly written code don't care about DoS or security issues. The fact is that there are poorly written apps that people use and depend on that don't have central validation. A decade or so of constant development by a dozen or two different programmers doesn't always result in the most idle code. DateTime might be the most central place to put in central validation on year input. The best solution is that Schwern gets a patch in ;) Yes, that would be a good solution, too. ;) -- Bill Moseley mose...@hank.org
Item #1 returned by STORABLE_freeze for DateTime is not a reference
Does Item #1 mean the first list element returned by STORABLE_freeze? return $serialized, $self-{locale}, $self-{tz}, \$self-{formatter}; Because, indeed it isn't a reference, but a scalar. I have some code that is serializing items that have DateTime objects (of course) and I'm seeing that message when running my test suite. I added this line above that line above in DateTime: warn $serialized\n; And running my tests I see: utc_rd_days:733603|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 utc_rd_days:733602|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 ok 6 - Fetched expected key utc_rd_days:733603|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 utc_rd_days:733602|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 utc_rd_days:733603|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 utc_rd_days:733602|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 ok 7 - Fetched data matches utc_rd_days:733603|utc_rd_secs:2927|rd_nanosecs:0|version:0.4401 (in cleanup) Item #1 returned by STORABLE_freeze for DateTime is not a reference at ../../lib/Storable.pm (autosplit into ../../lib/auto/Storable/_freeze.al) line 339 during global destruction, at line 327 Line 327 is my $serialized = nfreeze( $data ); I'm a bit confused why it's only complaining on the last one -- STORABLE_freeze is seemingly returning the same (scalar) data. It's expected that this nfreeze is happening in a DESTROY() (the data gets serialized and stored upon destroy). Is the destroy a red herring? -- Bill Moseley mose...@hank.org
DateTime::Format::DateManip
Ya, I know I should stay away from Date::Manip, but there's this legacy code, see... So, this looks like a result of a timezone change (setting it twice, in this case): $ perl -MDateTime::Format::DateManip -le \ 'print DateTime::Format::DateManip-parse_datetime( 2006-03-11 )' 2006-03-10T23:00:00 In DateTime::Format::DateManip::parse_datetime(): The code gets the timezone from Date::Manip and creates a DateTime object with it: my ($dm_tz, @bits) = UnixDate($dm_date, qw( %Z %Y %m %d %H %M %S %z )); my @args = merge_lists([qw( year month day hour minute second time_zone )], \...@bits); my $dt = DateTime-new(@args); In my case I end up with an OffsetOnly timezone (-0700). And then goes on to to figure out the time zone again from a lookup table: my $dt_tz = $class-get_dt_timezone($dm_tz); if (defined $dt_tz) { $dt-set_time_zone($dt_tz); In my case I now have 'US/Pacific'. If setting the timezone like this shouldn't it be a floating time initially? -- Bill Moseley mose...@hank.org Sent from my iMutt
Last Second of Day for the given date?
Is there a canonical approach, or is it something like: $dt-add( days = 1 )-truncate( to = 'day' )-subtract( seconds = 1 ); Here's the ugly part: The deal is I have a web form where start and end dates are entered, but in the database the column is a timestamp. Typically, the smallest interval is an entire day, but want to retain the ability to use a custom time within the day. So, instead of truncating in the database select (which would prevent using a custom start or end time of day) the plan is to truncate the DateTime objects before storing in the database. So, in this form, the smallest interval possible is one day, so if the same date is entered for both start and end then the interval is the entire day. Yes, a bit convoluted. -- Bill Moseley mose...@hank.org Sent from my iMutt
Re: Last Second of Day for the given date?
On Thu, Mar 12, 2009 at 02:28:34PM -0500, Dave Rolsky wrote: On Thu, 12 Mar 2009, Bill Moseley wrote: Is there a canonical approach, or is it something like: $dt-add( days = 1 )-truncate( to = 'day' )-subtract( seconds = 1 ); That should work fine, _but_ if you're not in the floating timezone that could land you on second 60 every once in a while, and your dbms may not like it. Interesting. It's a valid time, though, correct? If the unit of interval is days, I'd suggest simply defining an internval as from X (inclusive) to Y (non-inclusive). That way both X and Y can be plain old dates. That's probably a safer approach. -- Bill Moseley. mose...@hank.org Sent from my iMutt
iso8601 with timezone
Is there a better approach than this to include the timezone? my $iso_date = $dt-set_time_zone( 'UTC' )-iso8601 . 'Z'; -- Bill Moseley [EMAIL PROTECTED] Sent from my iMutt
DateTime::Format::ICal
I'm not very familiar with icalendar format. http://search.cpan.org/src/DROLSKY/DateTime-Format-ICal-0.08/lib/DateTime/Format/ICal.pm format_datetime() only adds the time if it's not 00:00:00: my $base = ( $dt-hour || $dt-min || $dt-sec ? sprintf( '%04d%02d%02dT%02d%02d%02d', $dt-year, $dt-month, $dt-day, $dt-hour, $dt-minute, $dt-second ) : sprintf( '%04d%02d%02d', $dt-year, $dt-month, $dt-day ) ); return $base if $tz-is_floating; return $base . 'Z' if $tz-is_utc; return 'TZID=' . $tz-name . ':' . $base; I glanced over RFC 2445 and I don't see this as a problem. But this validator at http://severinghaus.org/projects/icv/ reports: Error: Error was: Error at line 181: Unparseable date: 20070424Z Cause: Caused by: Unparseable date: 20070424Z With the problem entry being: DTEND:20070424Z Is this a problem with the validator? -- Bill Moseley [EMAIL PROTECTED]
Re: DateTime::Locale encoding
On Tue, Aug 07, 2007 at 07:51:35PM +0200, Tobias Kremer wrote: Am 07.08.2007 um 18:40 schrieb Bill Moseley: On Tue, Aug 07, 2007 at 06:30:46PM +0200, Tobias Kremer wrote: Yes, that's exactly why I just don't understand the problem. The rest of my templates, which are all utf-8 encoded, are displayed correctly though. What UNICODE option do you mean? I couldn't find it in Template::Manual::Config. Look at the source of Template::Provider. If set it assumes the text of the template is utf8 and decodes it. But if your problem is displaying variables (not templates) that are utf8 then sounds like something else. Exactly. utf8-encoded text in the templates is displayed correctly. Other stuff coming in from the stash that is utf8-encoded works perfectly, too. Ah. So you are failing to decode the templates on input, so failing to encode on output make it look fine. Perhaps. Are you using the Unicode::Encoding plugin in your Catalyst application? No. This happens even with no plugins loaded at all. You can try it out just by adding the following line to one of your controllers and putting [% monthnames %] in the TT template: $c-stash-{'monthnames'} = join ,, @{ DateTime::Locale-load('de')- month_names }; I did, and *without out* Unicode::Encoding I get the broke display (the little question marks in Firefox). I use both the plugin and set TT to decode my templates on input. TT will do that automatically if you have Byte Order Mark on your templates, too, IIRC. -- Bill Moseley [EMAIL PROTECTED]
Re: DateTime::Locale encoding
On Wed, Aug 08, 2007 at 12:36:26AM +0200, Tobias Kremer wrote: Am 08.08.2007 um 00:30 schrieb Tatsuhiko Miyagawa: Using Template::Provider::Encoding + Template::Stash::ForceUTF8 is one way to avoid these annoying utf-8 bytes vs. Unicode string woes. Might be the case. But I really like to understand what is causing this problem instead of just working around it with some plugins. Like I said, I suspect what's happening is you are reading in your utf8 templates and failing to decode them into Perl's internal encoding. Then when you print it out it gets printed as-is. You are not generating utf8 as much as passing it through. But the month names are encoded correctly in perl's internal. So when you print you have a mix of encodings. Actually, I'm kind of wondering why you are not getting wide char in print warnings. So, maybe I'm not correct on that. The plugins don't work around the problem, they handle the input and output correctly for you. If you want to understand it more then hack Template::Provider and see if the utf8 flag is set on the fetched templates. Then do the same with the month names. I would not use Template::Stash::ForceUTF8. My opinion is you should be more careful about your input and correctly decode it where it enters your application. Template::Provider::Encoding is cool, but you don't really need it if all your templates are utf8 you can just tell TT that fact and let it decode everything the same. The saying goes that if you keep everything utf8-encoded you don't have to worry much about encoding. In this case apparently everything _IS_ utf8 encoded but nevertheless it breaks for certain parts. You know your templates are utf8, but have you anywhere actually told perl that fact? Anyway, this isn't really DateTime related. -- Bill Moseley [EMAIL PROTECTED]
Re: DateTime::Locale encoding
On Tue, Aug 07, 2007 at 06:30:46PM +0200, Tobias Kremer wrote: Yes, that's exactly why I just don't understand the problem. The rest of my templates, which are all utf-8 encoded, are displayed correctly though. What UNICODE option do you mean? I couldn't find it in Template::Manual::Config. Look at the source of Template::Provider. If set it assumes the text of the template is utf8 and decodes it. But if your problem is displaying variables (not templates) that are utf8 then sounds like something else. Are you using the Unicode::Encoding plugin in your Catalyst application? -- Bill Moseley [EMAIL PROTECTED]
User preferences for I18N
$VERSION = '0.37'; I have a few general I18N questions. Perhaps you have some suggestions for best practices. I currently have a timezone table in my database and my users table references the timezone table via a timezone column. I populate the timezone table with DateTime::TimeZone-all_names. When a user sets their timezone they must pick from what's available in the timezone table. Is the list of timezones reasonably static? I assume it doesn't change very often. My other option is to use a text column type and store the timezone strings in each row of the users table. That way I won't have to update my timezone table if DateTime::TimeZone-all_names returns new zones. Uses a bit more space in each row of the users table. I then use this timezone string in my (TT) templates: [% CALL login_time.set_time_zone( user.timezone ) %] Now, I'm not sure I'm understanding how locales work in DateTime. $ LC_ALL=es_ES date sáb jul 7 07:33:03 PDT 2007 Should these be localized? $ LC_ALL=es_ES perl -MDateTime -le 'print DateTime-now-strftime(%A %c)' Saturday Jul 7, 2007 2:34:09 PM $ LC_ALL=es_ES perl -MDateTime -le 'DateTime::DefaultLocale(es_ES); print DateTime-now-strftime(%A %c)' Saturday Jul 7, 2007 2:40:43 PM $ LC_ALL=es_ES perl -MDateTime -le 'DateTime::DefaultLocale(es_ES); print DateTime-now-subtract( months = 2 )-strftime(%A %c)' Monday May 7, 2007 2:44:25 PM I'm wondering how to localize dates. In my web application's templates I have a number of virtual methods, so I can write: [% login_time.timestamp_full; # Monday May 7, 2007 2:44:25 PM PST login_time.timestamp_compact; # 2007-05-07 14:44 login_time.date_compact# 2007-05-07 # and so on. %] Where those are just preset strftime strings. This seems like a sane approach? Or do you have a different method? Thanks, -- Bill Moseley [EMAIL PROTECTED]
Re: Can't locate object method era_abbreviation
On Sat, Jan 06, 2007 at 11:13:34AM -0600, Dave Rolsky wrote: On Sat, 6 Jan 2007, Bill Moseley wrote: I just grabbed latest from CPAN and get: [EMAIL PROTECTED]:~/build/DateTime-0.35$ prove -b t/03components.t t/03componentsok 52/135Can't locate object method era_abbreviation via package DateTime::Locale::en_US at blib/lib/DateTime.pm line 606. I'm assuming I can ignore this. You need a more recent DateTime::Locale, probably. Indeed. Thanks. So should require .32. PREREQ_PM= { 'DateTime::Locale' = 0.31, -- Bill Moseley [EMAIL PROTECTED]
Re: Format::DateManip and Daylight Saving change
On Tue, Oct 03, 2006 at 01:57:29PM -0700, Bill Moseley wrote: $ perl -l dt.pl 'Dec 3, 2006 9am' Sun, Dec 3 2006 8:00 AM PST What time is: Dec 3, 2006 9am PDT ? (noting that it's PST in December) Using Manip is nice because it allows a wide range of input values ('first Tuesday in December'). But, it's some scary code and seems to be a bit broken with regard to DST. Any other options for somewhat free-form date parsing other that Date::Manip? BTW: DateTime::Format::DateManip does this: return undef unless @bits; my @args = merge_lists([qw( year month day hour minute second time_zone )], [EMAIL PROTECTED]); # Construct the DateTime object and use the offset timezone my $dt = DateTime-new(@args); # See if there is a better timezone to use my $dt_tz = $class-get_dt_timezone($dm_tz); # Apply the final time zone if (defined $dt_tz) { $dt-set_time_zone($dt_tz); } return $dt; First, since a timezone is used to create the DateTime object, it's not applying the final time zone, it's *changing* the final time zone. But, that seems a bit moot because of Seems to assume the current timezone: $ perl -MDate::Manip -le 'print UnixDate(Oct 3, 2006 9am, %Z %Y %m %d %H %M %S %z )' PDT 2006 10 03 09 00 00 -0700 But, push the date over the DST change and: 'print UnixDate(Dec 3, 2006 9am, %Z %Y %m %d %H %M %S %z )' PDT 2006 12 03 09 00 00 -0700 That sure looks wrong. Can't use that time zone when creating the DateTime object -- although could use US/Pacific and it would work. But 'print UnixDate(Dec 3, 2006 9am PST, %Z %Y %m %d %H %M %S %z )' PDT 2006 12 03 10 00 00 -0700 Crap. -- Bill Moseley [EMAIL PROTECTED]
Format::DateManip and Daylight Saving change
$ cat dt.pl use strict; use warnings; use DateTime::Format::DateManip; my $dt = DateTime::Format::DateManip-parse_datetime( shift || die ); print $dt-strftime( '%a, %b %e %Y %l:%M %p %Z' ); $ perl -l dt.pl 'Oct 3, 2006 9am' Tue, Oct 3 2006 9:00 AM PDT $ perl -l dt.pl 'Dec 3, 2006 9am' Sun, Dec 3 2006 8:00 AM PST It guessing my timezone is ok, but it's not exactly what outcome I'd like. Is that a problem with that module or the way I'm using it? -- Bill Moseley [EMAIL PROTECTED]
Re: Error messages
On Mon, Aug 07, 2006 at 04:47:56AM -0500, Dave Rolsky wrote: On Sun, 6 Aug 2006, Bill Moseley wrote: In general, instead of: Carp::croak( Cannot compare a datetime to a regular scalar ) unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' ) DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ); How about: Carp::croak( Cannot compare a datetime to a regular scalar [$dt1] [$dt2 ) unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' ) DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ); Something along these lines will be in the next release, which should come out some time this week. Cool. I'm all for verbose error messages. BTW should DateTime die if both items are not a DateTime objects? Why I ask is the backtrace led me to this in Template::Stash: sub _dotop { my ($self, $root, $item, $args, $lvalue) = @_; my $rootref = ref $root; my $atroot = ($root eq $self); my ($value, @result); where the test for ($root eq $self) was causing the exception in DateTime because one object was not a DateTime object. If they are not both DateTime objects can we state that they are not equal? -- Bill Moseley [EMAIL PROTECTED]
Error messages
In general, instead of: Carp::croak( Cannot compare a datetime to a regular scalar ) unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' ) DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ); How about: Carp::croak( Cannot compare a datetime to a regular scalar [$dt1] [$dt2 ) unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' ) DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ); Makes it more fun when I do this in my template: my $vars = { now = DateTime-now }; $t-process( \*DATA, $vars) || die $t-error; __END__ This is the template Formatted mdy = [% now.mdy %] Then when I get this: undef error - Cannot compare a datetime to a regular scalar [2006-08-06T15:09:52] [Template::Stash=HASH(0x860fabc)] at /usr/lib/perl5/DateTime.pm line 1395, DATA line 1. I can then wander off in a different direction wondering why _compare is being called in the first place and why the stash is being passed. My guess is because of overloading. -- Bill Moseley [EMAIL PROTECTED]
Re: Daylight Saving
On Fri, Jan 20, 2006 at 07:26:16AM -0800, Bill Moseley wrote: I have a zipcode table that lists the city, state, timezone offset (eg -5) and a flag indicating if the location uses daylight saving time for U.S. zipcodes. I don't have the Olson name in the table. How do I set the timezone in this case -- taking into account the dst settings? I kind of left this hanging. Is it possible to set a timezone on a DateTime object based on only the above information? Seems like one would need to know more (such as when Daylight Saving is in effect for that location. But, if so, could I see an example? Thanks, -- Bill Moseley [EMAIL PROTECTED]
Daylight Saving
I have a zipcode table that lists the city, state, timezone offset (eg -5) and a flag indicating if the location uses daylight saving time for U.S. zipcodes. I don't have the Olson name in the table. How do I set the timezone in this case -- taking into account the dst settings? Thanks, -- Bill Moseley [EMAIL PROTECTED]
Re: Daylight Saving
On Fri, Jan 20, 2006 at 10:03:44AM -0600, Dave Rolsky wrote: However, what should be possible is to make a new timezone based on a base offset, a dst offset, and a ruleset for changes (possibly expressed as two recurrence-based DateTime::SpanSet objects). I need to know if DST is in effect, right? Maybe I'm way off, but could I set the timezone to some place where I know DST exists, then check $dt-is_dst and use that? Something like (assuming US time zones): $dt-set_time_zone( 'America/Los_Angeles' ); my $offset = $zipcode-offset; $offset-- if $zipcode-observes_dst; Then reset the timezone based on the offset? That's ugly. DST doesn't have to happen everywhere at the same time, I suppose. -- Bill Moseley [EMAIL PROTECTED]
DT::F::DateManip
Anyone know how to set the timzone in Date::Manip differently every time DateTime::Format::DateManip-parse_datetime is called? I get dizzy reading the Date::Manip code, but it look like the timezone gets set once and sticks: local $ENV{TZ} = 'America/Chicago'; print Date::Manip::Date_TimeZone,\n; my $dt = DateTime::Format::DateManip-parse_datetime('10am EST'); print DateTime = $dt\n; print $dt-strftime('%a, %b %e %Y %l:%M %p %Z'), \n\n; local $ENV{TZ} = 'America/Boise'; print Date::Manip::Date_TimeZone,\n; my $dt = DateTime::Format::DateManip-parse_datetime('10am EST'); print DateTime = $dt\n; print $dt-strftim CST DateTime = 2005-11-15T09:00:00 Tue, Nov 15 2005 9:00 AM CST CST DateTime = 2005-11-15T09:00:00 Tue, Nov 15 2005 9:00 AM CST -- Bill Moseley [EMAIL PROTECTED]
Re: DT::F::DateManip
On Tue, Nov 15, 2005 at 10:23:56AM -0800, Bill Moseley wrote: Anyone know how to set the timzone in Date::Manip differently every time DateTime::Format::DateManip-parse_datetime is called? Here's one ugly way: Date::Manip::Date_Init(TZ=); local $ENV{TZ} = $new_zone; my $z = Date::Manip::Date_TimeZone(); Date::Manip::Date_Init(TZ=$z); I get dizzy reading the Date::Manip code Time to look at other parsers. -- Bill Moseley [EMAIL PROTECTED]
Re: DT::F::DateManip
By the way, as much as I don't like Date::Manip, it sure is good at parsing dates. Are there any other native DateTime parsers that are good at parsing dates that might be typed in by humans? $ perl -MDateTime::Format::HTTP -le 'print DateTime::Format::HTTP-parse_datetime(Feb 4 2004)' 2004-02-04T00:00:00 $ perl -MDateTime::Format::HTTP -le 'print DateTime::Format::HTTP-parse_datetime(Feb 4, 2004)' Could not parse date [Feb 4, 2004] DateTime::Format::Baby comes close. $ perl -MDateTime::Format::DateManip -le 'print DateTime::Format::DateManip-parse_datetime(Feb 4, 2004)' 2004-02-04T00:00:00 $ perl -MDateTime::Format::DateManip -le 'print DateTime::Format::DateManip-parse_datetime(next tuesday)' 2005-11-22T00:00:00 $ perl -MDateTime::Format::DateManip -le 'print DateTime::Format::DateManip-parse_datetime(last monday in december)' 2005-12-26T00:00:00 $ perl -MDateTime::Format::DateManip -le 'print DateTime::Format::DateManip-parse_datetime(third tuesday in november)' 2005-11-15T00:00:00 -- Bill Moseley [EMAIL PROTECTED]
Re: DateTime::Format and time zones
On Thu, Nov 03, 2005 at 01:52:39PM -0800, Mike Schilli wrote: Shouldn't parse_datetime() create a DateTime object with a floating time zone in this case? I agree. I ran up against a similar issue yesterday using DateTime::Format::DateManip because it sets to the local timezone (as determined by Date::Manip). For example, I have a web form where events are created. A time and location (where the event is located) need to be entered. When the event date is entered it's assumed to be a time local to the location of the event. So I want to accept a floating time and then set its timezone based on the timezone of the location. So if my server is in US/Pacific: use DateTime::Format::DateManip; my $event_time = 'Monday at 9am'; my $event_location = 'America/Chicago'; my $dt = DateTime::Format::DateManip-parse_datetime($event_time); print Time = $dt\n; $dt-set_time_zone( $event_location ); print Time = $dt\n; returns: Time = 2005-10-31T09:00:00 Time = 2005-10-31T11:00:00 which might make some people in Chicago a bit upset when they show up late to the event. My solution was to set a floating time first, but seems like by default the parsers should set a floating time zone. my $dt = DateTime::Format::DateManip-parse_datetime($event_time); $dt-set_time_zone( 'floating' ); By the way, I'm open to suggestion on better ways to parse free-form time entries. -- Bill Moseley [EMAIL PROTECTED]
should set_time_zone always return $dt?
set_time_zone returns undef if the new time zone is the same as the old. Is that by design? I got caught doing this: return $self-class_time-set_time_zone( $tz ); in the cases when $tz was not changing. -- Bill Moseley [EMAIL PROTECTED]
Install problems: Can't call method set_time_zone on an undefined value
This is on Debian sid and some DateTime packages are installed via the deibian package system: [EMAIL PROTECTED]:~$ COLUMNS=180 dpkg -l | grep libdatetime ii libdatetime-format-pg-perl 0.07-1 ii libdatetime-format-strptime-perl1.04-1 ii libdatetime-locale-perl 0.09-2 ii libdatetime-perl0.22-1 ii libdatetime-timezone-perl 0.28-1 (well, strptime and pg I build a .deb with dh-make-perl) But some are not packaged and I'm trying to install via CPAN or manually. I'm getting stuck with DateTime::Event::Recurrence (a requirement for ::ICal): bumby:~/.cpan/build/DateTime-Event-Recurrence-0.13# perl -Iblib/lib -Iblib/arch t/05set.t 1..9 ok 1 - next union ok 2 - next union ok 3 - next union ok 4 - next union ok 5 - next intersection Can't call method set_time_zone on an undefined value at /usr/local/share/perl/5.8.4/DateTime/Set.pm line 55. # Looks like you planned 9 tests but only ran 5. # Looks like your test died just after 5. bumby:~/.cpan/build/DateTime-Event-Recurrence-0.13# fgrep 'VERSION =' /usr/local/share/perl/5.8.4/DateTime/Set.pm $VERSION = '0.1603'; Anyone seen this? Suggestions for debugging? -- Bill Moseley [EMAIL PROTECTED]