Re: DateTime::Span, enddate and common-sense vs computers

2006-01-11 Thread John Siracusa
On 1/11/06 3:43 PM, Dave Rolsky wrote:
 What might be useful would be date-only objects, maybe as DateTime::Date or
 something like that.

Speaking of this, anyone know of any nice *time*-only CPAN modules?  If not,
how about a DateTime::Time?  Maybe DateTime could just aggregate
DateTime::Date and DateTime::Time? :)

-John




Re: API changes for date math (UTC vs local)

2005-08-16 Thread John Siracusa
On 8/16/05, Dave Rolsky [EMAIL PROTECTED] wrote:
 So it turns out that DT.pm has basically been buggy with regards to date
 math for any timezone with a DST change basically forever.
 
 The problem is that sometimes people want to do math in terms of the local
 time (the clock display time) and sometimes in terms of UTC time (the
 actual passing of time based on the atomic clock).
 [...]
 Ok, that's my summary of the proposed API changes.  Feedback is very
 welcome.

Any chance of the great dates without times vs. datetimes split happening
in DateTime for Perl 5?  That'd solve a lot of problems too.  Maybe some of
the DateTime::Incomplete stuff could help here?

As for the particular proposed changes, I think the methods names don't
clearly describe what's going on.  When I see subtract_datetime_utc() I
wonder if I have to pass a DateTime object with its timezone set to UTC or
something.

As I understand it, the distinction is actual (i.e., atomic) time that has
passed versus local calendar/clock time that has passed.  I do agree that
local calendar/clock math should be the default, so that covers add(),
subtract(), etc.  But as for the other methods, I think the _utc suffix is
confusing. UTC doesn't bring to (my) mind the actual time that has
passed concept, even if that's how it's done internally.

So, how about making add() and alias for add_calendar() or add_local(), and
then have add_absolute() or maybe add_temporal() or something for the other
style?

I know that absolute is already used elsewhere in the API.  If it doesn't
mean the same thing here, then maybe a different word should be used.
Temporal kind of stinks though.  Ideas?

-John




Re: API changes for date math (UTC vs local)

2005-08-16 Thread John Siracusa
On 8/16/05 8:01 PM, Rick Measham wrote:
 add_calendar() (aliased to add()) sounds like a good name for the old
 behaviour (local for ymd, UTC for hmsn) as we're adding according the
 the calender.

I was thinking add_calendar() would be local for ymd and hmsn...but maybe
I'm confused.  Basically, as far as add_calendar() is concerned, add one
day means point to the next box on the wall calendar, and add one hour
means what time will it be one hour from now?  This is all from the
perspective of a local person.  When we fall back in DST, for example,
one hour from now will be, well, now (if we just consider the time).

-John




Re: Simplifying DateTime

2005-08-16 Thread John Siracusa
On 8/16/05 8:14 PM, Rick Measham wrote:
 I'd like to hear comment on stripping out lots of the methods currently
 in DateTime and have them moved to decorator modules -- as this will
 allow users to load what they want and only what they want in the way of
 functionality.

Fine with me, as long as the memory and execution time isn't worse than the
current code.

-John




Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread John Siracusa
On 8/8/05, Dave Rolsky [EMAIL PROTECTED] wrote:
 Does anyone object to adding Math::BigFloat as a
 prereq?

What are the performance/memory implications?  I don't object to the prereq,
but I would like to know if we're in for any new speed/bloat issues.  (I
only really care about per-object overhead, not the cost of loading
Math::BigFloat itself.)

-John




Re: [Announce] DateTime::LazyInit 0.10

2005-07-23 Thread John Siracusa
On 7/23/05 3:35 AM, Rick Measham wrote:
 If you read the code, you'll notice that I have a utc_rd_values method
 as the math overload needs to be passed an object that 'can' call this
 method.

Why not just override can() and delegate to DateTime proper?

-John




Re: DateTime.pm on a Diet

2005-07-07 Thread John Siracusa
On 7/7/05 12:12 AM, Rick Measham wrote:
 Dave Rolsky wrote:
   DateTime::Shim
   DateTime::Trampoline
   DateTime::ThinShim
   DateTime::Proxy
   DateTime::Diet - not awful but a little cute, methinks ;)
 
 Of the above, I still like DT:Diet.
 
 If you want something less cute/more serious how about:
 DateTime::FastConstructor
 
 The others listed above don't seems to convey the purpose of the module.

I'll throw a few names out:

DateTime::Delayed
DateTime::AutoLoaded
DateTime::LazyInit

-John




Re: DateTime.pm on a Diet

2005-07-05 Thread John Siracusa
On 7/5/05 7:04 AM, Eric Cholet wrote:
 A while ago we did some profiling of an app that uses DateTime
 extensively and found out that most of the time is spent in
 Params::Validate. I understand this is somewhat of a religious issue,
 but in this case it's a net loss for us: the params have been
 validated zillions of times, and we lose performance in production. I
 would love a DateTime sans param validation.

Have you tried turning off the validation by setting the PERL_NO_VALIDATION
environment variable?

I agree with Dave that moving big/numerous data structures from Perl to C
will have the most bang for the buck:

On 7/4/05 1:47 PM, Dave Rolsky wrote:
 Implementing time zones in XS as native C data structures would almost
 certainly be a huge win.

Beyond that, the biggest culprits will probably be what they always are in
non-compute-intensive Perl: function/method call overhead and memory
management overhead.  Reduce the number of subs that are called and reduce
the size and number of allocations/deallocations and then you might start to
get closer to the point where actual calculations start to become visible
in the profile.

-John




Re: Rethinking date math, time zones, etc for Perl 6 (and maybe DateTime2?)

2005-06-15 Thread John Siracusa
On 6/15/05, Dave Rolsky [EMAIL PROTECTED] wrote:
 Also, I think we may need to consider serious backwards incompatibility in
 the future of DateTime.pm (possibly via a new namespace like DateTime2) to
 really clean this up, but that'll wait til I'm less tired ;)

Just break it.  DateTime's nowhere near version 1.0.  Anyone who was relying
on its API stability was not doing so based on any official advice, AFAIK.

-John




Re: [repost] two small fixes for DateTime::Format::Pg

2005-03-17 Thread John Siracusa
On 3/17/05 2:39 AM, Daisuke Maki wrote:
 If there's nobody else, I don't mind being the maintainer, except I
 doubt that I'll be doing much more than maintenance (as opposed to
 active development). I should be able to respond in time in cases like
 these, though.
 
 Claus, the module is pretty much stable nowadays, right?

Claus has apparently reappeared! :)

http://rt.cpan.org/NoAuth/Bug.html?id=8516

-John




Re: [repost] two small fixes for DateTime::Format::Pg

2005-03-16 Thread John Siracusa
On 3/15/05 11:54 PM, Cees Hek wrote:
 I sent a bug report and patch to this list back in January [1]
 regarding DateTime::Format::Pg, and I never received a response.  Just
 wondering if this slipped through the cracks.  In the meantime, I have
 logged this as a bug in rt.cpan.org [2].

I think the DateTime::Format::Pg is officially MIA.  I filed a bug 4 months
ago and have tried to contact the author many times.  No luck.  Does someone
want to take over DateTime::Format::Pg?

-John




Re: DateTime objects are necessarily huge?

2005-02-28 Thread John Siracusa
On 2/28/05 9:42 AM, Geoffrey Young wrote:
 DateTime objects are _huge_ for non-UTC timezones.  consider:
 [...]
   print Dumper $dt;

I always just assumed that those giant structures exist once in memory and
are simply referenced by each DT object.  I never bothered to actually
check, but c'mon, how could it be otherwise? :)

-John




Re: DateTime objects are necessarily huge?

2005-02-28 Thread John Siracusa
On 2/28/05 1:26 PM, Dave Rolsky wrote:
 On Mon, 28 Feb 2005, Geoffrey Young wrote:
 The hugeness is the DateTime::TimeZone object, not DateTime itself.
 Those are all singletons, so you only pay the price once per time zone.
 
 ok, but how does that affect storable-style serializations?  I noticed that
 you have some storable hooks, but I didn't see exactly how it worked.
 
 Unfortunately, it's not possible to retain singleton-ness after a
 freeze/thaw with Storable.  This is because of the way Storable's
 internals work.  I _think_ this could be changed, and I tried doing so,
 but couldn't quite figure it out.  I brought it up on P5P a while back
 (maybe a year) but nobody responded.

Can't you just nuke the giant DT:TZ ref before freezing and have it
auto-re-vivify when first used after it's thawed?  IOW, save the TZ string
(floating, local, America/Chicago) and then re-grab a ref to the
DT::TZ singleton as needed.  That way, you don't have to freeze the DT::TZ
at all.

Of course, I don't know how flexible the Storable hooks are...

-John




Paging Claus Färber - DT::F::Pg bug #8516

2004-12-21 Thread John Siracusa
I filed this bug on DateTime::Format::Pg about a month ago but I'm not sure
Claus saw it.

http://rt.cpan.org/NoAuth/Bug.html?id=8516

Basically, it looks like the internal subroutine _fix_second() is missing
from the module.  When it gets called as part of the public parse_time()
method, kablooey!  I'd supply a patch, but I'm at a loss as to what it was
supposed to do.

So Claus, are you out there somewhere?  If not, can anyone tell me what
_fix_second() was probably supposed to do?

-John




Re: How can I add a duration object to a DateTime Set max object?

2004-12-02 Thread John Siracusa
On Thu, 2 Dec 2004 13:02:16 GMT, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote:
 Ron Hill wrote:
 Actually I run the reports on the first of the month for the previous
 month so I had to do this
 my $month = DateTime-today-truncate(to = 'month')-subtract(months=1);
 [...]
 This one behaves better - it doesn't change $month value:
 
   my $this_month =
   DateTime-today-truncate(to = 'month');

I think you both might have forgotten to include time zone information...

-John




Re: Small mistakes in DateTime advent writeup

2004-12-01 Thread John Siracusa
On Wed, 1 Dec 2004 12:28:35, Dave Rolsky [EMAIL PROTECTED] wrote:
 I strongly dislike combined get/set methods, and they won't appear in
 DateTime.

I recall that discussion from a while back but I don't remember your
reasons.  Can you briefly reiterate them?

-John




Re: Good press for DateTime

2004-12-01 Thread John Siracusa
On Wed, 1 Dec 2004 13:23:24, Dave Rolsky [EMAIL PROTECTED] wrote:
 If someone gets local to work on Win32, it might be considerable.  Until
 then, it's not.

Ooo, a glimmer of hope! :)  Too bad I don't do any Perl on Win32hrm.

-John




Re: [cpan #6980] $d-day(1); == $d-set(day = 1);

2004-07-16 Thread John Siracusa
On 7/16/04 5:01 PM, Dave Rolsky wrote:
 On Thu, 15 Jul 2004, David Wheeler wrote:
 Has a different naming convention for the two types of methods. I kind
 of like it, but only in environments where attributes are virtually
 always READ, and rarely WRITTEN. So maybe it should be:
 
# Perl-style
$d-day; # accessor
$d-day(1); # mutator
 
 Let me cut off this line of discussion, because I really, really, really
 hate this style of dual-purpose methods.  The reason I dislike it so much
 is that it's impossible to distinguish between a mutator and an accessor
 that accepts arguments to affect what it returns.

It's not impossible, since you can always make up some rule to distinguish
the two (e.g. a single argument means set, name/value pairs mean define what
to return).

Anyway, what percentage of accessors take arguments to affect what they
return?  If you want to return different kinds of things, you should make
different accessors, IMO.

-John




Re: [cpan #6980] $d-day(1); == $d-set(day = 1);

2004-07-16 Thread John Siracusa
On 7/16/04 5:38 PM, David Wheeler wrote:
 I've been fond of this argument myself, Dave. And I like having
 separate mutators. But it's extremely common among Perl modules, and
 really no different than the idea of true attributes. Using lvalue
 subs, for example, one could:
 
$d-day; # Accessor
$d-day = 1; # Mutator
 
 ...and this is how Perl 6 will behave, FWIW.

...provided you are resigned to never upgrade the day() to be a
full-fledged method--even in a subclass--unless you are willing to jump
through some hoops to retain the $d-day = X functionality.  I find this
annoying, but the P6 Cabal was not persuaded.  Anyway... :)

 But if you must have self-documenting methods, then maybe the Java
 approach will be more meaningful and consistent for people:
 
$d-get_day;
$d-set_day(1);
 
 After all, it's unlikely that anyone would then ever try:
 
$d-get_day(1);

They will if they, like Dave, are inclined to think it's an accessor that
accepts arguments to affect what it returns ;)

IMO, the get_/set_ prefixing leads to an ugly API where everything is
prefix namespaced according to a very broad distinction of limited
usefulness: getter or setter.

And I cringe at APIs with 50 methods that begin with set_ and 50 more that
begin with get_.  I have to mentally filter out the prefix noise when trying
to look up methods based on the part that is the most relevant to the API
(e.g. day)  It's like Hungarian notation for APIs, and Hungarian notation
and Perl are an extremely poor fit for each other.  (I Know, I have worked
on much too much Perl code with variables like $rarhTurnips.)

Anyway, Dave hates it, so I guess I should just be glad that there's a day()
method at all rather than a set_day() method... ;)

-John




Re: [cpan #6980] $d-day(1); == $d-set(day = 1);

2004-07-16 Thread John Siracusa
On 7/16/04 5:58 PM, David Wheeler wrote:
 On Jul 16, 2004, at 2:52 PM, John Siracusa wrote:
 And I cringe at APIs with 50 methods that begin with set_ and 50 more that
 begin with get_.  I have to mentally filter out the prefix noise when trying
 to look up methods based on the part that is the most relevant to the API
 (e.g. day)  It's like Hungarian notation for APIs, and Hungarian notation
 and Perl are an extremely poor fit for each other.  (I Know, I have worked on
 much too much Perl code with variables like $rarhTurnips.)
 
 That's a documentation problem.

I was also referring to the function pop-up menu in my editor, which I
arrange alphabetically (am I the only one who sometimes uses code as
documentation? :), but these are all secondary effects of the primary
offense of Hungaran-ism in the API (apologies to any Hungarians...blame your
countryman at MS ;)

 Anyway, Dave hates it, so I guess I should just be glad that there's a day()
 method at all rather than a set_day() method... ;)
 
 True enough...except for set_time_zone(), this is true, as near as I
 can see.

I meant to type get_day() instead of set_day().  Anyway, that was your cue
to reply, Oh no, I'm still open to suggestions.  Tell me more.  Ah well ;)

-John




Re: [cpan #6980] $d-day(1); == $d-set(day = 1);

2004-07-16 Thread John Siracusa
On 7/16/04 9:15 PM, Dave Rolsky wrote:
 (Anyway, ymd() isn't a get/set method at all, is it?)
 
 It's a _get_ method.  You're retrieving information from the object,
 right?  It's just not getting a single attribute.

When I questioned the prevalence of accessors that take arguments to affect
what they return, what I meant were the typical get/set methods we were
discussing earlier.  My point was that ymd()'s not really relevant because
it only gets, so there's no ambiguity when args are passed.

-John




Re: [cpan #6980] $d-day(1); == $d-set(day = 1);

2004-07-15 Thread John Siracusa
On 7/15/04 5:55 PM, David Wheeler wrote:
 I kind of like it, but only in environments where attributes are virtually
 always READ, and rarely WRITTEN. So maybe it should be:
 
# Perl-style
$d-day; # accessor
$d-day(1); # mutator
 
 Or:
 
# Java-style
$d-get_day; # accessor
$d-set_day(1); # mutator
 
 Thoughts?

The first one, definitely.  The get_/set_ style always strikes me as a poor
fit for a dynamic language like Perl.  Plus, think of the Perl 6 version
of DateTime.  MMD will give you thee best of both worlds: separate methods,
both named the same thing :)

-John




Re: DateTime::Stringify ...

2004-02-21 Thread John Siracusa
On 2/21/04 3:49 PM, Ben Bennett wrote:
 If I remember correctly the argument against auto stringification was
 that it made debugging harder.

Speaking of difficult debugging and DT, every time I feed something to
Data::Dumper that contains a DT object (or several) I cringe at the giant
output.  I don't suppose there's any way to avoid that...

-John



Re: DateTime::Stringify ...

2004-02-21 Thread John Siracusa
On 2/21/04 4:33 PM, Dave Rolsky wrote:
 On Sat, 21 Feb 2004, John Siracusa wrote:
 Speaking of difficult debugging and DT, every time I feed something to
 Data::Dumper that contains a DT object (or several) I cringe at the giant
 output.  I don't suppose there's any way to avoid that...
 
 Nothing springs to mind, other than adding hooks to Data::Dumper ala
 Storable.  But that would somewhat defeat the purpose of Data::Dumper,
 wouldn't it?

For eval-ing purposes, sure.  But if you're using it for debugging to look
inside objects and whatnot, you don't need to see all that stuff.  Yeah,
Storable-like hooks would be nice.  Maybe Perl 5.10's Data::Dumper will
support them :)

-John



Re: DateTime::Duration Problem...Possible Bug?

2004-02-12 Thread John Siracusa
On 2/12/04 1:36 PM, Dave Rolsky wrote:
 On Tue, 10 Feb 2004, John Siracusa wrote:
 On 2/10/04 12:17 PM, Dave Rolsky wrote:
 I should add a section to the docs on this so that people know what to
 expect.
 
 Yes, please do, because I am eternally confused by this :)
 
 There are some docs already, in DateTime.pm, under the header How Date
 Math is Done
 
 Are those insufficient?  There's a pointer to that section in
 DateTime::Duration's DESCRIPTION header.

I was thinking more along the lines of an explanation of why the example
below doesn't work as expected, and how to do a few things that you might
be trying to do.

On 2/10/04 12:09 PM, Mark Fowler wrote:
 use DateTime::Duration;
 my $dur = DateTime::Duration-new(hours = 2);
 print $dur-hours . : .
   $dur-minutes . : .
   $dur-seconds . \n;
 
 print $dur-delta_minutes . : .
   $dur-delta_seconds . \n;
 
 Prints:
 
 2:0:0
 120:0
 
 Shouldn't that print
 
 2:0:0
 120:7200
 
 Or am I being really stupid?

Basically, something like your reply to the list, but in POD form :)  I'm
not saying turn the docs into a cookbook, but this area really is
non-obvious to people who haven't spent a long time thinking about date
math (i.e. most people :)

Yeah, you can derive the answers by reading the existing docs (or the code
;), but some hand-holding is nice once in a while.

-John



Re: DateTime::Duration Problem...Possible Bug?

2004-02-10 Thread John Siracusa
On 2/10/04 12:17 PM, Dave Rolsky wrote:
 I should add a section to the docs on this so that people know what to
 expect.

Yes, please do, because I am eternally confused by this :)

-John



Re: ANNOUNCE: DateTime 0.1704

2003-10-07 Thread John Siracusa
On 10/7/03 12:42 PM, Dave Rolsky wrote:
 On Tue, 7 Oct 2003, Bill McCormick wrote:
 Where is it? I checked a few mirrors and can't seem to find it.
 
 Patience, young jedi.  It takes a few hours, at least, for new uploads to
 propogate to all the mirrors.

For the code it is time to propagate as well, hmmm?

(sorry...but not really :)
-John



Re: [OT] Article idea for The Perl review 'Introduction to DateTime'

2003-08-26 Thread John Siracusa
On 8/26/03 2:10 PM, Eugene van der Pijll wrote:
 * You might want to show some date math:
 
   $dt1 = DateTime-now();
 
   # One week ago:
   $dt2 = $dt1-clone-subtract( weeks = 1);
 
   print $dt2-datetime, \n;

...except you almost certainly want to do this:

$dt1 = DateTime-now(time_zone = 'local');

unless you're really trying to print the date and time one week ago
somewhere in England...

-John



Re: DateTime-localtime()

2003-08-14 Thread John Siracusa
On Sunday, August 10, 2003, at 08:59 PM, Joshua Hoblitt wrote:
If you only have a year and day of year, then having a 
from_day_of_year
constructor saves a _lot_ of calculation that end users have to do.  
OTOH,
having to do 'DateTime-now(time_zone = local)' isn't very onerous 
at
all.
If you need an example DT::F::ISO8601 makes heavy use of 
from_day_of_year().
I was thinking of end-user code more than DT-related library code.  But 
I'm not really arguing against having from_day_of_year() anyway.  I'm 
arguing for a simpler way to get the current local time because, IME 
with DT and other date libraries, this is a *very* common task.

Heck, if the API Stability Gods of the 0.1x Phase of Development could 
somehow be appeased, I'd argue that now() should actually default to 
time_zone = 'local' because that's what users will expect--and what 
now() sounds like to me.  But I suspect the Gods will not be 
appeased, thus the localtime() compromise.

C'mon, it's one innocent little line... :)

	sub localtime { shift-now(time_zone = 'local', @_) }

Is this the horrid face of code bloat, or an honest effort to address a 
common usage scenario?

Besides, I thought the whole point of not having a single new() 
constructor that understands many kinds of args was that creating 
specialized constructors was a cleaner way to add such functionality. 
And now we're balking at actually using this mechanism to add a 
constructor whose usage, IMO, will be second only to new() in end-user 
code?

-John



Re: DT::TZ test failure

2003-08-14 Thread John Siracusa
On Sunday, August 10, 2003, at 01:34 PM, Dave Rolsky wrote:
On Sun, 10 Aug 2003, John Siracusa wrote:
...speaking of which, is there any chance DateTime-now() can be 
changed to
default to the local time zone?  It seems to me that now probably 
means
now, here most of the time.  I don't have a single call to now() 
that
doesn't include time_zone = 'local'.
This doesn't seem like a good idea, since it's not backwards compatible
and since 'local' may not work on every single platform.
Well, it is version 0.1x after all... ;)

Okay, so maybe a new constructor then?  DateTime-localtime()?  Getting 
the current local time seems more common than, say, constructing a 
DateTime object from a day of the year, IMO :)

-John



Re: DateTime-localtime() (was Re: DT::TZ test failure)

2003-08-14 Thread John Siracusa
On Sunday, August 10, 2003, at 09:40 PM, Dave Rolsky wrote:
...unless that's the only way you will *ever* call now()! :)
Seriously, who is calling now() *without* time_zone = 'local'
arguments?  I haven't done so yet, and would like to hear some 
examples
of this usage.
Me, because I know that 'local' won't always work ;)  I'd be more 
likely
to call it with an explicit time zone than with 'local'.
Yeah, but as the module's author, you're not exactly the typical user 
;)

Here's example of what I expect to be common usage.  Let's say someone
want the default date range in the text fields on a web form to be 
the
past 30 hours.  Joe Perl Programmer is going to glance at the DT docs
and then write:

$start = DateTime-now-subtract(hours = 30)-strftime(...);
$end   = DateTime-now-strftime(...);
Joe Perl Programmer is going to be very surprised, IMO, and the fix is
not to add warnings to the docs... ;)
Like I said, I think there are very good reasons not to default to 
local,
especially since that it won't necessarily work at all.
Okay, fine, then don't default now() to 'local' to avoid that problem.  
But what's the argument against a localtime() that, say, croaks if it 
can't figure out what local is?  I think that's a reasonable thing 
for a function named localtime() to do.

Do you not agree that getting the current local time will be a common 
task, and that Joe Programmer is not likely to be too keen on typing 
either time_zone = 'local' or time_zone = 'Asia/Taipei' (or whatever) 
everywhere?

-John



Re: DateTime-localtime() (was Re: DT::TZ test failure)

2003-08-11 Thread John Siracusa
On Sunday, August 10, 2003, at 10:24 PM, David Wheeler wrote:
On Sunday, August 10, 2003, at 07:17  PM, John Siracusa wrote:
Obviously, you need currying. See Perl 6. Or create  your own 
subclass with its own now() method that passes the argument for you. 
Or create a function that calls it for you, passing your default 
arguments, and returning the result. In fact, make it a code 
reference, and you will for all practical purposes have a curried 
version of the constructor!
Easy things should be easy^H^Hier than that ;)
I think it might have been easier than writing all the email you've 
sent to the list the last few days. ;-)
Like everyone else on this list, I'm sacrificing for all the other Joe 
Programmers out there ;)

-John



DateTime-localtime() (was Re: DT::TZ test failure)

2003-08-10 Thread John Siracusa
On Sunday, August 10, 2003, at 08:08 PM, Dave Rolsky wrote:
On Sun, 10 Aug 2003, John Siracusa wrote:
We have enough constructors as it is.
Well that's not my fault :)  If, for whatever reason, you're going to
limit DateTime to N constructors, they should be the N most likely to
be used.  Do you really think from_day_of_year() is going to be called
more often than now(time_zone = 'local')?
If you only have a year and day of year, then having a from_day_of_year
constructor saves a _lot_ of calculation that end users have to do.  
OTOH,
having to do 'DateTime-now(time_zone = local)' isn't very onerous 
at
all.
...unless that's the only way you will *ever* call now()! :)  
Seriously, who is calling now() *without* time_zone = 'local' 
arguments?  I haven't done so yet, and would like to hear some examples 
of this usage.

Here's example of what I expect to be common usage.  Let's say someone 
want the default date range in the text fields on a web form to be the 
past 30 hours.  Joe Perl Programmer is going to glance at the DT docs 
and then write:

$start = DateTime-now-subtract(hours = 30)-strftime(...);
$end   = DateTime-now-strftime(...);
Joe Perl Programmer is going to be very surprised, IMO, and the fix is 
not to add warnings to the docs... ;)

-John



Re: DT::Wrapper API/semantics

2003-08-08 Thread John Siracusa
On Friday, August 8, 2003, at 10:21 PM, Joshua Hoblitt wrote:
This is the 'decorator infrastructure' that I've been whining for.  
It's kind of a melting pot for 'add-ons' or 'plug-ins'.  The idea is 
to throw DT, DT::Cache, DT::Foo, DT::Validator, etc. into the 'pot' 
and end up with a factory that creates object with features from all 
of the input classes.
I'm with you, except that I wonder if DT::Cache won't be weighed down 
by the overhead of the decorator chaining implementation.  Dave's post 
was somewhat scary... :)

-John



Re: DateTime Performance

2003-08-04 Thread John Siracusa
On 8/4/03 12:26 AM, Dave Rolsky wrote:
 # ... includes args: year, month, day, hour, minute, second
 DateTime-new(...): 16 wallclock secs @ 687.29/s
(14.48 usr +  0.07 sys = 14.55 CPU)
 
 This does a lot of work, including calculating both UTC  local times,
 which involves calculating leap seconds, etc.

Does it need to do that?  I mean, sure, eventually it might have to do that
if I want to do some sort of date manipulation, or even just fetch or print
the date.  But does it have to really do anything at all during object
construction other than stash the args somewhere?

 DateTime-now(): 21 wallclock secs @ 547.95/s
(18.13 usr +  0.12 sys = 18.25 CPU)
 
 Ditto.

I'm assuming now() is slower than new() due to the system call overhead of
getting the current time...?

 Total Elapsed Time = 19.91729 Seconds
User+System Time = 14.60729 Seconds
 Exclusive Times
 %Time ExclSec CumulS #Calls sec/call Csec/c  Name
   27.6   4.035  4.685  20274   0.0002 0.0002  Params::Validate::_validate
   24.0   3.510 17.549  1   0.0004 0.0018  DateTime::new
   18.9   2.770  3.809  10001   0.0003 0.0004
 DateTime::Locale::_load_class_from_id
 
 This seems quite odd.  It really doesn't do much.
 
   8.96   1.309  2.647  10020   0.0001 0.0003  DateTime::TimeZone::BEGIN
 
 And this is completely mystifying.  Can you show us your code?

Sure, here it is:

for(1 .. 1)
{
  my $d = DateTime-new(year = 200, month = 1, day = 1, hour = 2, minute
= 3, second = 4);
}

Those stats were produced on a G3/400 running a development release of OS X
that uses some build of Perl 5.8.1, which could explain some oddness.  Here
is the same code run on a G4/800 using Perl 5.8.0 on the latest released
version of OS X 10.2:

Total Elapsed Time = 8.817281 Seconds
  User+System Time = 5.352659 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 60.4   3.236 10.844  1   0.0003 0.0011  DateTime::new
 44.7   2.395  3.305  10001   0.0002 0.0003
DateTime::Locale::_load_class_from_id
 43.3   2.318  2.127  20274   0.0001 0.0001  Params::Validate::_validate
 22.5   1.207  1.095  10001   0.0001 0.0001  DateTime::Locale::Base::new
 18.4   0.987  1.223  10020   0.0001 0.0001  DateTime::TimeZone::BEGIN
 17.5   0.939  0.465  5   0. 0.  DateTime::__ANON__
 15.2   0.818  0.645  10002   0.0001 0.0001
DateTime::_calc_local_components
 12.8   0.687  1.025  10002   0.0001 0.0001  DateTime::_calc_local_rd
 10.6   0.568  0.525  10002   0.0001 0.0001  DateTime::_calc_utc_rd
 8.20   0.439  0.225  10002   0. 0.  DateTime::_normalize_seconds
 7.83   0.419  0.275  1   0. 0.  DateTime::_last_day_of_month
 7.47   0.400  0.115  30006   0. 0.
DateTime::TimeZone::Floating::is_floating
 7.27   0.389  3.505  10001   0. 0.0004  DateTime::Locale::load
 5.79   0.310  0.214  10006   0. 0.
DateTime::TimeZone::Floating::BEGIN
 4.86   0.260  0.070  20004   0. 0.
DateTime::TimeZone::OffsetOnly::is_utc

Maybe that looks more sane to you?
 
 So, what does everyone else think of the object creation performance
 situation?  Is it simply good enough to be 3x faster that
 Date::Manip::ParseDate()?  Are there any obvious areas that I should
 consider before I start mucking around with DateTime::new()?
 
 Considering that up til now my concern has been primarily on getting
 things correct, I wouldn't worry about it.  There are definitely some big
 performance improvements possible.  One possibility is to move the leap
 second bits into the DateTime XS code, which should help a lot.  The
 timezone stuff can also benefit from being rewritten as XS, but that won't
 help the particular cases you benchmarked, since the UTC and floating time
 zones are quite fast already.

What about what I mentioned earlier: lazy (or lazier) evaluation in the
constructor?  Basically, I want construction with known values to be as fast
as possible since there's a chance I may not even look at the date fields of
my objects.  But it's a hassle to have special-case code that either doesn't
fetch or doesn't set the date fields of my objects, just so I can avoid the
relatively expansive calls to DateTime-new()

-John



Re: DateTime Performance

2003-08-04 Thread John Siracusa
On 8/4/03 10:10 AM, John Siracusa wrote:
 On 8/4/03 12:26 AM, Dave Rolsky wrote:
 # ... includes args: year, month, day, hour, minute, second
 DateTime-new(...): 16 wallclock secs @ 687.29/s
(14.48 usr +  0.07 sys = 14.55 CPU)
 
 This does a lot of work, including calculating both UTC  local times,
 which involves calculating leap seconds, etc.
 
 Does it need to do that?  I mean, sure, eventually it might have to do that
 if I want to do some sort of date manipulation, or even just fetch or print
 the date.  But does it have to really do anything at all during object
 construction other than stash the args somewhere?

I played around with DateTime::new() and found that the biggest culprit is
this line:

$self-{locale} = DateTime::Locale-load( $p{locale} );

The removal of which more than doubles the performance of calling
DateTime::new(...) with ymdhms args.  The only way to get a comparable
speedup is to remove every line below that one except for these two:

bless $self, $class;
return $self;

And even that only gives a ~90% speedup vs. the 100%+ gained by ditching
DateTime::Locale-load().  (Obviously all of this will hose DateTime's
actual functionality, but bear with me :)

Profiling showed that DateTime::Locale::_load_class_from_id() was being
called N+1 times during N calls to DateTime-new(...), and that it was #3 in
the dprofpp list (2000 iterations shown):

%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 47.8   0.663  2.135   2000   0.0003 0.0011  DateTime::new
 35.2   0.488  0.399   4274   0.0001 0.0001  Params::Validate::_validate
 31.6   0.439  0.517   2001   0.0002 0.0003
DateTime::Locale::_load_class_from_id
 15.8   0.219  0.313   2020   0.0001 0.0002  DateTime::TimeZone::BEGIN

I found that _load_class_from_id() unconditionally executes this code:

eval require $real_class;

Skipping that line was good for a 30%+ speed boost, but that got me
thinking...aren't the Locale objects loaded/created by _load_class_from_id()
singletons?  Replacing calls to _load_class_from_id() within
DateTime::Locale::load() with some dumb caching like this:

$Cache_By_Id{$id} ||= $class-_load_from_id($id)

Resulted in an easy 50% speed-up for DateTime-new(...), and
_load_class_from_id() dropped completely off the dprofpp output:

Total Elapsed Time = 0.841889 Seconds
  User+System Time = 0.501889 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 116.   0.584  1.290   2000   0.0003 0.0006  DateTime::new
 79.3   0.398  0.287   4274   0.0001 0.0001  Params::Validate::_validate
 41.6   0.209  0.220   2002   0.0001 0.0001  DateTime::_calc_local_rd
 37.6   0.189  0.238   2020   0.0001 0.0001  DateTime::TimeZone::BEGIN
 31.6   0.159  0.150   2002   0.0001 0.0001  DateTime::_calc_utc_rd
 27.8   0.140  0.070   2002   0.0001 0.
DateTime::_calc_local_components
 25.9   0.130  0.030  1   0. 0.  DateTime::__ANON__
 17.9   0.090  0.070   2001   0. 0.  DateTime::DefaultLocale
 15.9   0.080  0.040   4004   0. 0.
DateTime::TimeZone::OffsetOnly::is_utc
 15.9   0.080  0.030   2000   0. 0.  DateTime::_last_day_of_month
 15.9   0.080  0.040   2002   0. 0.  DateTime::_normalize_seconds
 13.9   0.070  0.010   6006   0. 0.
DateTime::TimeZone::Floating::is_floating
 13.9   0.070  0.069   2006   0. 0.
DateTime::TimeZone::Floating::BEGIN
 11.3   0.057  0.115  1   0.0573 0.1145  DateTime::Locale::register
 7.97   0.040  0.154  6   0.0067 0.0257  DateTime::Locale::BEGIN

(An aside: why is DateTime::DefaultLocale on this list at all?)

To test my theory that this kind of dumb caching is valid, I ran all of
DateTime::Locale's tests, and then ran DateTime's tests while using the
modified DateTime::Locale.  Everything passed.

So, assuming I'm not missing a finer point here, I'm thinking that one easy
speed-up for DateTime object creation would be to make the various
DateTime::Locale::* classes into singletons (using whatever the proper
method is for this in the DT project) and avoid repeated string evals and
repeated calls to _load_class_from_id().

Going further, if calls to DateTime::Locale-load(...) could be memoized
safely, that'd be great too :)

-John



Re: DateTime Performance

2003-08-04 Thread John Siracusa
On 8/4/03 1:25 PM, Ben Bennett wrote:
 Why not make your module be lazy about whether or not it creates a
 DateTime?

I thought of that, but I also use the act of creating a DateTime object to
check the validity of date attributes.  Anyway, I think there's room for
DateTime-new() optimization even without adding lazy evaluation (see
earlier posts).

-John



DateTime Performance

2003-08-03 Thread John Siracusa
I was profiling a database-backed mod_perl application recently.  A 
particular request was taking several seconds to complete.  At first I 
thought the database was the bottleneck, but the request included only 
one database query, and that query completed in about 300msec when run 
from a command-line script. Something Perl-ish was the culprit, so I 
set out to find it.

This task was made more difficult by my inability to get Devel::DProf 
working in Mac OS X (see my posts to the mod_perl and [EMAIL PROTECTED] 
lists), so I had to resort to the use of Time::HiRes and a smattering 
of calls to my own simple timer routines.  I eventually narrowed the 
time-suck down to a loop that looked something like this:

	# bind columns to %row here

while($sth-fetch)
{
  push(@widgets, Widget-new(%row));
}
Now I suspected some sort of DBI issue, so I replaced the loop body 
with a no-op.  Suddenly, the request completed in one second or less.  
Now I suspected my Widget class, and benchmarked its constructor 
offline.  (The constructor just calls $self-$key($value) for each k/v 
pair in %row.)  This eventually led me to find that setting the date 
fields in the Widget object was the culprit.

I use DateTime objects for my internal date representation, but I have 
a set of wrapper functions that hide this fact.  Now I suspected that 
my date parsing wrapper code was the problem, so I replaced my parse 
function's body with a simple call to DateTime-now.  The request 
became slow again, taking several seconds to complete.

There was no avoiding it: the bottleneck for my web app was not the 
database, not HTML::Mason, not my object classes, not even my date 
parsing code, but DateTime object creation!  (Perl 5.8, latest DateTime 
from CPAN.)

My quick fix was to make sure that %row only contains a single date 
field, rather than the four that each object has when completely 
filled out.  This produced a noticeable (~2x) speed increase for the 
whole request.

Sorry to provide so many gory details, but I wanted to try to establish 
exactly how I'm using DateTime, and how its performance came to my 
attention in the first place.  I benchmarked DateTime's object creation 
speed against a few random classes, just to get a feel for where it 
stands:

CGI-new(''):  5 wallclock secs @ 1869.16/s
  (5.25 usr +  0.10 sys =  5.35 CPU)
Date::Manip::ParseDate('now'): 49 wallclock secs @ 223.81/s
  (44.44 usr  0.24 sys +  0.01 cusr  0.01 csys = 44.70 CPU)
Date::Simple-new('2003-01-01'):  2 wallclock secs @ 4273.50/s
  (2.31 usr +  0.03 sys =  2.34 CPU)
# ... includes args: year, month, day, hour, minute, second
DateTime-new(...): 16 wallclock secs @ 687.29/s
  (14.48 usr +  0.07 sys = 14.55 CPU)
DateTime-now(): 21 wallclock secs @ 547.95/s
  (18.13 usr +  0.12 sys = 18.25 CPU)
DateTime does well against Date::Manip, but not so well against even a 
big module like CGI.  But for object creation alone, should it really 
be ~5x as slow as Date::Simple?

My final step was to profile 10,000 calls to DateTime-new(...) using 
Devel::DProf (which works from the command line in OS X).  dprofpp had 
this to say:

Total Elapsed Time = 19.91729 Seconds
  User+System Time = 14.60729 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 27.6   4.035  4.685  20274   0.0002 0.0002  Params::Validate::_validate
 24.0   3.510 17.549  1   0.0004 0.0018  DateTime::new
 18.9   2.770  3.809  10001   0.0003 0.0004  
DateTime::Locale::_load_class_from
 _id
 8.96   1.309  2.647  10020   0.0001 0.0003  DateTime::TimeZone::BEGIN
 6.44   0.940  1.030  10001   0.0001 0.0001  DateTime::Locale::Base::new
 6.23   0.910  1.190  10002   0.0001 0.0001  
DateTime::_calc_local_components
 4.45   0.650  0.650  5   0. 0.  DateTime::__ANON__
 3.90   0.570  1.009  10002   0.0001 0.0001  DateTime::_calc_utc_rd
 2.88   0.420  0.490  1   0. 0.  
DateTime::_last_day_of_month
 2.67   0.390  0.399  10006   0. 0.  
DateTime::TimeZone::Floating::BEGI
 N
 2.40   0.350  1.619  10002   0. 0.0002  DateTime::_calc_local_rd
 1.92   0.280  0.299  10001   0. 0.  DateTime::DefaultLocale
 1.64   0.240  0.240  30006   0. 0.  
DateTime::TimeZone::Floating::is_f
 loating
 1.51   0.220  0.220  1   0. 0.  DateTime::_rd2ymd
 1.37   0.200  4.009  10001   0. 0.0004  DateTime::Locale::load

These numbers confuse me a bit, because I'm only creating about 30 
Widget objects in my mod_perl request, not 10,000.  But I see a very 
significant speed hit, even if I replace my entire Widget-new() call 
with a simple call to DateTime-new().  Maybe it's some sort of 
mod_perl/DateTime interaction?

Anyway, I don't want to get sidetracked into mod_perl stuff.  I'm not 
sure what (else) to make of the results above, other than a possible 
wish that I could 

Re: Very rough DateTime::Format::Simple

2003-07-18 Thread John Siracusa
Looks good so far! :)

 - Suggestions of additional formats to parse would be greatly
   appreciated
...or so you'd think!  +/-infinity...pretty please? :)

-John



Re: Very rough DateTime::Format::Simple

2003-07-18 Thread John Siracusa
On Friday, July 18, 2003, at 11:17 PM, Ben Bennett wrote:
 - Suggestions of additional formats to parse would be greatly
   appreciated
Ooo, and didn't you also forget now?

-John



Re: Name for DateTime::Format::Simple

2003-07-18 Thread John Siracusa
On Friday, July 18, 2003, at 11:20 PM, Ben Bennett wrote:
I am not a big fan of DateTime::Format::Simple either.  My best
suggestions are:
DateTime::Format::Basic
  Common
  Generic
  Localized
I'd say it's between Basic and Common.  A more accurate name is 
probably Casual, but CPAN wanderers will read too much into that.  
Ditto for Human.  Common is probably the best, I guess, since people 
differ on what is Basic.

-John



Re: DateTime parse(), parser()

2003-07-16 Thread John Siracusa
On 7/16/03 2:16 PM, Eugene van der Pijll wrote:
 Most of the formatting modules don't know what to do with infinite dates.

That's a bug/feature in the formatting modules, IMO, not a reason to pretend
that infinite dates don't exist.

 Similarly, most of the programs using DT won't use infinite dates. It is a
 pain to check for infinity everywhere.

...and yet you must do so anyway if you write subroutines that accept
DateTime objects, but that want to reject infinite dates.

 I don't think infinity needs to be locale aware.  Inf will not be locale
 aware in Perl 6, AFAIK, for example.
 
 Perl 6 is for programmers. I thought you needed the DT::F::Simple module
 for user input.

Programmers are users too :)  In this situation, you can think of it as a
shorter constructor for brief/simple scripts (since the arguments to
DateTime-new() are very verbose).  This was another one of the motivators
for DT::F::Simple, if you look back at the thread.

 If English users try to submit the string infinite in a web form (I doubt
 it, but hypothetically...), Dutch users would certainly type oneindig.

I'm not really against localization in this case.  I think natural
language is outside the scope of DT::F::Simple.  Simple things like now
and today should get parsed, but not right now or the day after
yesterday :)  I'm just not sure how cleanly infinity will localize.

And since it is a mathematical concept as well as a regular word (and
probably used in the former context more often), I don't think it would be
the end of the world if it wasn't localized.  That's all I'm saying.

-John



Re: DateTime parse(), parser()

2003-07-16 Thread John Siracusa
On 7/16/03 3:39 PM, Eugene van der Pijll wrote:
 John Siracusa schreef:
 On 7/16/03 2:16 PM, Eugene van der Pijll wrote:
 Most of the formatting modules don't know what to do with infinite dates.
 
 That's a bug/feature in the formatting modules, IMO, not a reason to pretend
 that infinite dates don't exist.
 
 Infinite dates do not exist.

Infinite DateTime objects do, which was my point.

 A Format object does not have to accept every deranged monstrosity that
 is subclassed from DateTime. For example, my Format modules are
 documented to accept DateTime objects.

DateTime::Infinite is a deranged monstrosity now!?  Yeesh :)  Regardless
of your opinion of it, DateTime::Infinite is very useful to many people.

 this means that DT::F::Simple would try to be two things:
 
 1) it wants to parse all common datetime strings that a (naive?) user
 would pass to the program. To do this, it has to be as lenient as
 possible, whilst being aware of locale issues, and if possible, it
 should be able to interpret the most likely meaning of defective input
 like 01/02/03. It should be able to parse such simple phrases as 'now',
 but not unintuitive mathematical concepts.
 
 2) it wants to provide a shorter constructor. To do this, it should be
 exactly defined how formats are interpreted. Special phrases are
 provided to construct some special DT constructs (aka deranged
 monstrosities), like '+inf' and '-inf'. It is not necessary to duplicate
 other methods, so e.g. 'now' is not needed; DateTime::now() is perfectly
 adequate.
 
 Combining these two aims is perhaps possible.

I never suggested that ambiguous forms should be parsed by DT::F::Simple.
The two-digit years thread was started by someone else :)  I think it should
parse common, unambiguous, easy to parse date strings.

 Calling the result Simple is a chutzpah.

Like I said earlier, maybe ::Basic is better.  But ::Simple is how we've
been discussing it so far, so I'm trying to avoid confusion :)

 Making it the default for DT parsing...

...is the key feature of the whole system!  (That's what you were going to
say, right? ;)

 If today is parsed, people expect tomorrow to be parsed as well

Well, you could just set a policy to avoid anything that requires date math.
But if you do want to accept tomorrow, DT makes it pretty easy with
$dt-add(days = 1), unless I'm missing something... :)

-John



Re: DateTime parse(), parser()

2003-07-16 Thread John Siracusa
On 7/16/03 4:17 PM, Eugene van der Pijll wrote:
 I never suggested that ambiguous forms should be parsed by DT::F::Simple.
 
 Not even 04/05/2003?

That's not ambiguous, thanks to the handy setting in DT::F::Simple that
tells it exactly how to interpret that :)

 If today is parsed, people expect tomorrow to be parsed as well
 
 Well, you could just set a policy to avoid anything that requires date math.
 
 Is DT::truncate date math? If so, this disqualifies today...

You don't necessarily need to use truncate to handle today (e.g. It could
just be documented to mean 00:00:00), but no, I wouldn't consider truncation
to be date math.

 Oh, I forgot one: if now is parsed, never should be as well
 (returning DT::Undef). (That one is somewhat sensible to include, even.)

...unless you consider all such things to be deranged monstrosities! :)

On 7/16/03 4:16 PM, Dave Rolsky wrote:
 End users should not be getting back DT::Inf or DT::Undef (if the latter
 eventually exists) unless they explicitly declare that they are working
 in a domain where such things exist.

Like I said earlier, if your code accepts DateTime objects, but doesn't want
to deal with infinite dates, then you've got to explicitly check for
finite-ness anyway.  I don't think you can just *assume*, based on a choice
(default or otherwise) of DT::F:: modules, whether or not infinite dates
will ever cross their (code) path.

If you want to put the onus on the user to read the particular DT::F::
module's documentation to see what kinds of DateTime objects could possibly
be returned, then users will have to do the same for DT::F::Simple.  And in
that case, DT::F::Simple just has to document what it can return.

Finally, if you're just trying to go for the principle of least surprise,
then I don't think a programmer would be surprised that

DateTime-parse('infinity');

returns an infinite date!  It's not like infinite dates are going to just
start spewing fourth from DateTime-parse() randomly :)

-John



Re: DateTime::Format::Simple and Indication of month/day/year or d/m/y in Locales...

2003-07-15 Thread John Siracusa
On 7/15/03 8:05 AM, Ben Bennett wrote:
 On Tue, Jul 15, 2003 at 12:14:00AM -0400, John Siracusa wrote:
 I'm sure you're already doing this, but just in case, make sure to allow for
 single-digit numbers where there is no ambiguity. [...]
 
 Yes.

(Also stuff like 10/25/2003 5 p.m.  Just checking :)

 Actually I wasn't accepting the form 200210130102
 either (I will accept 20021013T0102).  Should I?

Yes, definitely for the 200210130102 (or 20021013010259 or
20021013010259.12345) versions.  Those aren't ambiguous at all, as far as
I can see.  I can take or leave the T :)

 I can add an optional additional parameter dmy_mode (defaults to your
 locale if undef) but I really think inferring it from the locale is
 fine.

Yeah, that sounds better than trying to come up with names for the setting.

 Speaking of which, what interface do people want?
 
 my $us_parser = DateTime::Format::Simple-new(locale = en_US);
 my $dt = $us_parser-parse_datetime(2/11/74);
 
 Or:
 
 my $dt = DateTime::Format::Simple-parse_datetime(string = 2/11/74,
locale = en_US);

I'd use the first.  (Actually, I'd use DateTime-parse(), which would use
the first for me :)  But I don't see why it can't support both.

-John



Re: DateTime parse(), parser()

2003-07-14 Thread John Siracusa
On 7/14/03 12:36 PM, Hill, Ronald wrote:
 Can I encourage you to put together a Format::Simple module
 and release it? I think we need something out there for
 very basic date parsing. There is the DateTime::Format::HTTP
 that comes very close ( It works great on Ingres dates/times).
 Or maybe the regrex that you provided can be incorporated
 into HTTP? 

I'd gladly release the DateTime::Format::Simple I whipped up, but only if
there is consensus about the scope of the module and the name ::Simple.
Mine is really ::DeadSimple :)  I suspect someone else out there might want
to use the ::Simple namespace for something slightly less simple than the
handful of regexes and constant strings I posted earlier.  Opinions?

Also, I'm slightly confused about the responsibilities of a
DateTime::Format:: module.  Does such a module have to have format_*
methods, or can it get by with just parse_datetime()?  I'm not sure what a
format_* method for ::Simple should produce...

-John



Re: DateTime parse(), parser()

2003-07-14 Thread John Siracusa
On 7/14/03 1:05 PM, Dave Rolsky wrote:
 Anything called DT::F::Simple should parse everything Date::Parse can
 parse, at least, and not _too_ much more, because it should also be
 reasonably fast ;)

Great, but the $64K question is: do we then get parse() and parser() methods
in DateTime, which default to use DT::F::Simple? :)

-John



Re: DateTime parse(), parser()

2003-07-14 Thread John Siracusa
On 7/14/03 2:31 PM, John Peacock wrote:
 Joshua Hoblitt wrote:
 I'm not really excited about this proposed feature.  If it is included the
 loading of DT::F::Simple should be deferred until parse_datetime is called.
 
 
 That is another reason why I suggest not having the parser() and parse()
 methods in DT at all.  For people who never need to parse random date strings,
 they only use DateTime; and they are done; everyone else does use
 DateTime::Format; as well.  The latter use would then take an array of
 additional Format modules to use when parsing (if desired).

Why not have them at all?  Okay, so defer parser class loading until the
last minute.  Then all you have is a dozen or so more lines of code in
DateTime.  Is that going to kill you? :)

I think this is a very important feature.  If DateTime didn't have
strftime() already, then maybe I'd buy the argument that DateTime is just
an object representation of dates and doesn't deal with string input/output
(although that'd make DateTime a lot less useful, I think).  As things
stand, the lack of a parse() method represents a gap in functionality, IMO.

-John



Re: DateTime parse(), parser()

2003-07-14 Thread John Siracusa
On 7/14/03 3:36 PM, Dave Rolsky wrote:
 I'm getting concerned about DateTime bloating, not so much in terms of
 code, but in terms of features.  Every feature requires more docs, and
 more docs means that it becomes harder and harder to figure out how to do
 the one thing _you_ want DT.pm to do.

DT is only as complex as it needs to be, IMO :)  And a good examples or
tutorial section in the docs will go a long way towards letting users
quickly and easily figure out how to do most common tasks.  Of course, one
of those common tasks is probably going to be parsing simple date formats.

As a user, would you rather be told, Go explore the various the DT::F::*
modules until you find what you need.  Then download and install that
module, load it, and use it to parse your dates.  Then come back to these
docs to learn more about those date objectsor...You can probably just
use parse() if your date formats are simple.  Here's an example, and here's
a link to the parse() entry in this document.  If your dates are more
complex, then see the DT::F::* modules and the parser() method.
 
 I think this is a very important feature.  If DateTime didn't have
 strftime() already, then maybe I'd buy the argument that DateTime is just
 an object representation of dates and doesn't deal with string input/output
 (although that'd make DateTime a lot less useful, I think).  As things
 stand, the lack of a parse() method represents a gap in functionality, IMO.
 
 Yeah, maybe ...

Search your feelings, you know it to be true! :)

-John



Re: DateTime parse(), parser()

2003-07-14 Thread John Siracusa
On 7/14/03 7:00 PM, Iain Truskett wrote:
 My only qualm is the default American bias of the second regex.

Right, which is why I mentioned some sort of mode/setting.  But it'd still
default to US, so there ;)  Heh, maybe it'd look at your current time zone
to pick the default, or is that too clever by half? :)

 I'd probably vote for DateTime::Format::HTTP as it copes with a lot of the
 common formats.

Poaching from Date::Parse, as suggested by Dave (I think), is my favorite
idea for DT::F::Simple's scope so far.

-John



Re: DateTime::Format::Simple and Indication of month/day/year or d/m/y in Locales...

2003-07-14 Thread John Siracusa
On 7/14/03 11:10 PM, Ben Bennett wrote:
 I am taking a whack at DT::F::Simple (please speak up now if anyone
 else wants to claim this project) that can parse things that are
 similar to the ones that Date::Parse can do.

Sweet, someone took the bai--...er, picked up the baton ;)

 Namely:
 - Rough ISO8601 strings (only complete datetimes and dates)
 - Dates with '-', '.', or '/' separators (either by month number or
  localized short or long name)
 - Times with ':' or '-' separator and optional localized AM/PM
 - Day names will be used to sanity check the parsed date if present
 - I will use localized BC/AD if present

I'm sure you're already doing this, but just in case, make sure to allow for
single-digit numbers where there is no ambiguity.  This is essential for
handling user-created input.  Examples:

9/3/2002 (e.g. don't require 09/03/2002)
1:02 (e.g. don't require 01:02)

and maybe even:

200210131:02

but that may make some people break out in hives, so whatever :)  Also,
don't forget about the optional . in a.m. and p.m.  I'm not quite sure
how that'd get localized, but the point is that the localized am/pm thingies
must be regexes, not constant strings (or, okay, a regex constructed out of
a list of constant strings, if you want :)

 Which leads to my problem, there appears to be no simple way to get
 the date order to differentiate m/d/y from d/m/y.

Don't.  Make it a setting.  I've been trying to think of what to name this
setting, but have no good ideas.  Here are some bad ones instead:

DT::F::Simple-use_mmdd(1);
DT::F::Simple-use_ddmm(1);

DT::F::Simple-mode('us');
DT::F::Simple-mode('euro');

DT::F::Simple-euro_mode(1);
DT::F::Simple-us_mode(1);

Gah, that's horrible :)  Someone out there must have some sort of
pre-existing vocabulary to describe the date format differences.  Is it just
regional, or are there ISO numbers to reference or what?

-John



Re: DateTime parse(), parser()

2003-07-13 Thread John Siracusa
On 7/13/03 6:47 AM, Eugene van der Pijll wrote:
 1/20/2002 1:02 p.m. (okay, maybe a Euro-mode for dd/mm/ :)
 
 A parser that can parse this format correctly should not be called
 Simple. As you say, it has to have a US and a Euro mode at least; the
 default DateTime parser should be simple enough to need no
 configuration.

I don't think it would be complex at all.  There's only one setting! :)

 IOW, DateTime::Format::Simple should handle at least 90% of the dates a
 user is likely to encounter (or a person is likely to enter).
 
 If you want a parser that can handle 90% of all dates, call it
 DateTime::Format::HideouslyComplex.

See above.  It's like 4 or 5 regexes for DateTime::Format::Simple.  I know,
because I have a DateTime wrapper that parses these formats, it it covers
about *99.9%* of the date strings I encounter, including user input in web
forms and such.

-John



Re: DateTime parse(), parser()

2003-07-13 Thread John Siracusa
On Sunday, July 13, 2003, at 08:11 PM, Iain Truskett wrote:
Remember: part of the point of having the various format
modules is that you can pick'n'mix. You could conceivably
wrap a number of them in Builder to make your own parser
that recognises the sorts of dates you come across. I mostly
come across HTTP, W3CDTF and RFC2822 dates so I'm all set =)
Sure, but my main point is that I don't want to have to manually load  
and use parsers.  I want DateTime (the class and/or individual objects)  
have a catch-all parse() method that uses the parser class of my  
choosing.  And I want the default to be something than can handle most  
normal date formats, ignoring as much complexity as it takes to get  
into the core (even though DateTime::Format::Simple would still be  
its own module, and might not even be loaded until the first call to  
parse())

However, I'm interested in seeing your regexen to see if you
parse anything that might be of use to me. Would you like to
share?
They're super boring.  Heck, these two cover almost everything I'm  
interested in:

#  mm dd [hh:mm[:ss[.nnn]]] [am/pm]($year, $month, $mday, $hours,  
$mins, $secs, $fsecs, $ampm) =
/^(\d{4})\s*-?\s*(\d{2})\s*-?\s*(\d{2})\s*(?:- 
?\s*(\d{1,2}):?(\d{2})(?::?(\d{2}))?)?(?:\.(\d+))?(?:\s*([aApP]\.?[mM]\. 
?))?$/

# mm/dd/, mm-dd-, [hh:mm[:ss[.nnn]]] [am/pm]
($month, $mday, $year, $hours, $mins, $secs, $fsecs, $ampm) =
m#^(\d{1,2})[-/](\d{1,2})[-/ 
](\d{4})(?:\s+(\d{1,2}):(\d{2})(?::(\d{2}))?)?(?:\.(\d+))?(?:\s*([aApP]\ 
.?[mM]\.?))?$#))

(Post-processing to handle am/pm and fsecs correctly omitted)

To this I just add now, today (meaning 00:00:00), +/-infinity, and  
a no-op for things that are already DateTime objects.  This, believe it  
or not, covers almost everything I expect a user to enter in a form  
(ignoring excess whitespace stripping and such, which happens earlier),  
as well as everything I expect to read from a file or whatever.

Really, I'm not asking for the moon.  The key features are the  
built-in/used by default nature and the I can handle whatever  
parse() method (instead of parse_date(), parse_datetime(),  
parse_year_and_day_but_not_month(), etc.)  Since this is all so simple,  
I think it should be built in via the creation and default use of a  
DateTime::Format::Simple module and a generalized parse() class/object  
method for DateTime.

For kicks, I just threw this into DateTime.pm

use vars qw($VERSION $PARSER);
...
use DateTime::Format::Simple(); # pre-loading in this case
use constant DEFAULT_PARSER_CLASS = 'DateTime::Format::Simple';
...

sub parser
{
  my $self = shift;
  if(ref $self)
  {
return $self-{'parser'} = shift  if(@_);
return $self-{'parser'} ||= $PARSER ||= DEFAULT_PARSER_CLASS;
  }
  return $PARSER = shift  if(@_);
  return $PARSER ||= DEFAULT_PARSER_CLASS;
}
sub parse
{
  my $dt;
  eval { $dt = $_[0]-parser-parse_datetime($_[1]) };
  return undef  if($@);
  return $_[0] = $dt  if(ref $_[0]);
  return $dt;
}
and then spent 5 minutes writing a bare bones implementation of  
DateTime::Format::Simple using the regexes above.  And behold, simple  
things are easy:

	$dt = DateTime-parse('5/29/1945');

	$dt-parse('2002-03-05 1:02 a.m.');

and hard things are possible:

	DateTime-parser('DateTime::Format::ReallyComplex');

	$dt = DateTime-parse('the 20th of september, nineteen seventy-five,  
midnight');
	$dt-parse('the day after tomorrow');
	$dt-parse('my birthday'); # ;)

-John




DateTime::TimeZone::Local uses File::Spec without use

2003-06-18 Thread John Siracusa
DateTime::TimeZone::Local (from CPAN) is missing:

use File::Spec;

But later calls File::Spec-splitpath(...), resulting in the error:

Can't locate object method splitpath via package File::Spec at
/Library/Perl/DateTime/TimeZone/Local.pm line 44.

-John



Re: Quick question: fractional seconds

2003-03-26 Thread John Siracusa
On 3/26/03 12:33 AM, Dave Rolsky wrote:
 On Tue, 25 Mar 2003, John Siracusa wrote:
 Hrm, well, I'd actually be happy (for my purposes) with simply storing
 fractional seconds as an integer somewhere.  I don't care if fractional
 durations are allowed, or if fractional seconds are used in date
 calculations at all.  I just want fractional seconds to be preserved:
 
 See, some people think it should be another attribute, other think that
 seconds should be floating point.  Personally, I don't know.

If you mean that seconds should be stored as an actual float, I think that's
obviously the wrong choice due to rounding errors during floating point
math.  Better to actually store the numbers before and after the decimal
point as separate integers (or use a single BigFloat-type value that
avoids rounding errors).  But that's just the storage method.  Making a
float_seconds attribute that join('.', ...)s them is fine, whatever :)

 But if it's another attribute it needs a precision.  I don't want to call
 it fractional seconds and let each user decide, because that kills
 inter-operability.

Fractional seconds can simply be the most general form of the attribute.
You can then truncate/pad (or round) that value to produce all
fixed-precision derived attributes: milliseconds, nanoseconds, etc.  But
fractional seconds should simply be an integer (or BigInt, if necessary)
value that comes after the decimal point.  That's the most general
implementation, and doesn't close any doors for the future, as far as I can
tell.  You may also think it's the most useless implementation, but it'd
help me, at least :)

I've already got at least two different precisions for fractional seconds,
and I'm perfectly happy to sprintf() or round() for myself as necessary to
help interoperability while I wait for further standardization.  I just need
a place to store fractional seconds.

-John



Re: Parsing/Formatting API

2003-01-19 Thread John Siracusa
On 1/18/03 7:21 PM, Dave Rolsky wrote:
 On Sat, 18 Jan 2003, John Siracusa wrote:
 Just as an aside (or maybe not?) I've always wanted DB-specific date parsing
 and formatting functionality to hang off of the $dbh, just like quoting
 does.  It's much easier to keep code database-neutral this way.
 
 Now each DBD could in turn use DateTime::Formatter::MySQL,
 DateTime::Parser::MySQL, and so on internally, but I don't want to see any
 of those class names in my code! :)
 
 That's a nice idea, but people may want to use these modules without using
 DBI

And so they can.  What's stopping them?

 and I have no control over the DBI/DBD modules.

No, but if you ask nicely... :)

 Once the DateTime suite is more advanced, I'd be happy to work with Tim Bunce
 and DBD module authors on integrating DateTime support into the DBI, if
 there's interest from that group of folks.

I'm thinking that asking sooner is better than asking later...

 Also remember that, for the purposes of databases, you'll have to deal with
 odd things like -infinity and -00-00 00:00:00 which make most
 (all?) current date modules choke badly.
 
 Ah, SQL DBMS's are all so broken, ain't it just great?

Indeed :)

-John




Re: Parsing/Formatting API

2003-01-19 Thread John Siracusa
On 1/19/03 12:26 PM, Dave Rolsky wrote:
 On Sun, 19 Jan 2003, John Siracusa wrote:
 That's a nice idea, but people may want to use these modules without using
 DBI
 
 And so they can.  What's stopping them?
 
 Nothing.  I'm just saying that the API needs to work both for standalone
 use and for use by the DBI modules.

Okay, but my point was that standalone use of db-specific date formatting
and parsing (i.e. in the absence of a $dbh) will be very rare (assuming we
do get it hooked into DBI as proposed).  So while it should still certainly
be possible, don't spend too much time sweating over interface sugar for
db-specific parsing/formatting.

Just make the db-specific APIs and class hierarchy simple and orthogonal:
straight-forward to use, and without any real concern about one or two extra
required arguments or lines of code to do common tasks (since it'll be done
in one place inside a DBD, and then rarely used directly outside of that
context).

 Actually, we have one DBD maintainer on the list, David Wheeler (DBD::Pg).
 He might be a better person than I to start a discussion about this on
 dbi-dev.  I'm on that list, so I'll chime in as needed.

Okay, I'll pursue that.

-John