Re: How to check if a DateTime is invalid (again - but this time without using eval)?

2017-07-05 Thread Bill Moseley
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

2016-10-22 Thread Bill Moseley
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?

2016-04-25 Thread Bill Moseley
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?

2016-04-23 Thread Bill Moseley
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?

2016-04-22 Thread Bill Moseley
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?

2016-04-22 Thread Bill Moseley
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

2015-04-22 Thread Bill Moseley
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

2014-01-26 Thread Bill Moseley
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

2014-01-26 Thread Bill Moseley
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

2014-01-16 Thread Bill Moseley
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

2014-01-08 Thread Bill Moseley
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

2014-01-06 Thread Bill Moseley
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

2014-01-06 Thread Bill Moseley
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

2013-09-15 Thread Bill Moseley
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.

2013-03-14 Thread Bill Moseley
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.

2013-03-12 Thread Bill Moseley
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?

2013-03-10 Thread Bill Moseley
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?

2013-03-09 Thread Bill Moseley
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?

2013-03-08 Thread Bill Moseley
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?

2013-03-08 Thread Bill Moseley
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?

2013-03-07 Thread Bill Moseley
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

2012-11-13 Thread Bill Moseley
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

2012-10-23 Thread Bill Moseley
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.

2011-09-20 Thread Bill Moseley
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.

2011-09-20 Thread Bill Moseley
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

2010-11-21 Thread Bill Moseley
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

2010-11-20 Thread Bill Moseley
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

2010-11-20 Thread Bill Moseley
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?

2010-11-02 Thread Bill Moseley
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

2010-02-02 Thread Bill Moseley
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

2009-12-15 Thread Bill Moseley
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

2009-12-15 Thread Bill Moseley
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

2009-12-15 Thread Bill Moseley
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

2009-12-15 Thread Bill Moseley
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

2009-07-13 Thread Bill Moseley
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

2009-03-31 Thread Bill Moseley
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?

2009-03-12 Thread Bill Moseley
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?

2009-03-12 Thread Bill Moseley
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

2008-06-07 Thread Bill Moseley
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

2008-03-04 Thread Bill Moseley
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

2007-08-08 Thread Bill Moseley
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

2007-08-08 Thread Bill Moseley
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

2007-08-07 Thread 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.

Are you using the Unicode::Encoding plugin in your Catalyst
application?

-- 
Bill Moseley
[EMAIL PROTECTED]



User preferences for I18N

2007-07-07 Thread Bill Moseley
$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

2007-01-06 Thread Bill Moseley
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

2006-10-04 Thread Bill Moseley
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

2006-10-03 Thread Bill Moseley


$ 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

2006-08-07 Thread Bill Moseley
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

2006-08-06 Thread Bill Moseley
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

2006-02-09 Thread Bill Moseley
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

2006-01-20 Thread Bill Moseley
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

2006-01-20 Thread Bill Moseley
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

2005-11-15 Thread Bill Moseley
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

2005-11-15 Thread Bill Moseley
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

2005-11-15 Thread Bill Moseley
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

2005-11-04 Thread Bill Moseley
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?

2005-09-13 Thread Bill Moseley
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

2004-08-17 Thread Bill Moseley
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]