Re: DateTime::Span, enddate and common-sense vs computers
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)
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)
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
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
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
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
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
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?)
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
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
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?
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?
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
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?
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
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
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);
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);
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);
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);
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);
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 ...
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 ...
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?
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?
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
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'
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()
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
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)
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)
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)
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
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
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
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
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
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
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
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
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()
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()
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()
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...
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()
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()
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()
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()
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()
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...
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()
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()
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
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
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
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
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