Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Wed, 16 Jul 2003, Iain Truskett wrote:

 What do people think parsers should return if they can't
 parse? And what if they do parse, but DateTime doesn't want
 to create an object of the appropriate specification?

 Should we wrap our methods in evals and return undef?

 Should we just throw errors?

I'm a big fan of throwing errors, since it forces the callers to actually
handle them.  Just returning undef leads to this:

 my $dt = $parser-parse('this is not a date');

 do_something_with_date($dt);

and then mysterious failures later on.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Rick Measham
At 3:42 PM +1000 16/7/03, Iain Truskett wrote:
What do people think parsers should return if they can't
parse? And what if they do parse, but DateTime doesn't want
to create an object of the appropriate specification?
DateTime::Undef :)

If all modules return DateTime::Undef and all modules handle it when 
passed it, then everything flows.

If we return undef, then we need to make sure all methods can handle 
undef parameters cleanly. Of course, we really can't do this because:
	undef-set( day=$day )
is an error .. no matter what!

However:
$undef = new DateTime::Undef;
$undef-set( day=$day );
just returns DateTime::Undef;
Cheers!
Rick
--

There are 10 kinds of people:
  those that understand binary, and those that don't.

  The day Microsoft makes something that doesn't suck
is the day they start selling vacuum cleaners

Write a wise proverb and your name will live forever.
   -- Anonymous



Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Wed, 16 Jul 2003, Rick Measham wrote:

 At 3:42 PM +1000 16/7/03, Iain Truskett wrote:
 What do people think parsers should return if they can't
 parse? And what if they do parse, but DateTime doesn't want
 to create an object of the appropriate specification?

 DateTime::Undef :)

 If all modules return DateTime::Undef and all modules handle it when
 passed it, then everything flows.

Flows is one word for it.

 If we return undef, then we need to make sure all methods can handle
 undef parameters cleanly. Of course, we really can't do this because:
   undef-set( day=$day )
 is an error .. no matter what!

 However:
   $undef = new DateTime::Undef;
   $undef-set( day=$day );
 just returns DateTime::Undef;

And this is a good thing because it will induce incredibly mysterious
errors in the end user's code?

Fatal errors are a _good_ thing.  Forging ahead with bad data and _not_
getting errors is a very, very, very bad thing.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Iain Truskett
* Dave Rolsky ([EMAIL PROTECTED]) [16 Jul 2003 16:11]:

[...]
 Fatal errors are a _good_ thing. Forging ahead with bad
 data and _not_ getting errors is a very, very, very bad
 thing.

autarch++

Despite most of the _innards_ of Builder returning undef
when they hit problems, all the external methods throw
errors, since until that point whether it's actually bad
data is not known.


cheers,
-- 
Iain.


Re: DateTime parse(), parser()

2003-07-16 Thread Rick Measham
On Wed, 16 Jul 2003, Iain Truskett wrote:
 What do people think parsers should return if they can't
 parse? And what if they do parse, but DateTime doesn't want
 to create an object of the appropriate specification?
 Should we wrap our methods in evals and return undef?

 Should we just throw errors?
At 1:06 AM -0500 16/7/03, Dave Rolsky replied:
I'm a big fan of throwing errors, since it forces the callers to actually
handle them.  Just returning undef leads to this:
 my $dt = $parser-parse('this is not a date');

 do_something_with_date($dt);

and then mysterious failures later on.
I'm an anti-fan of die. Die requires wrapping in eval or parsing the 
user's input before passing to -parse_datetime, which is just crazy.

We should only throw errors on programmer error. For example:
$dt-set( weekday = 'Friday' );
should error because there's no 'weekday' parameter for set().
However, we should return DateTime::Undef on user error:
	$dt-set( day = 'Twenty-two' );
because it means that we can now test for DateTime::Undef, letting 
set() do the parsing of the user's input.

Just another $0.02

Cheers!
Rick
--

There are 10 kinds of people:
  those that understand binary, and those that don't.

  The day Microsoft makes something that doesn't suck
is the day they start selling vacuum cleaners

Write a wise proverb and your name will live forever.
   -- Anonymous



Re: DateTime parse(), parser()

2003-07-16 Thread Claus Färber
Dave Rolsky [EMAIL PROTECTED] schrieb/wrote:
 Fatal errors are a _good_ thing.  Forging ahead with bad data and _not_
 getting errors is a very, very, very bad thing.

DBI has an option RaiseError. We could:

. have a variable $DateTime::AutoRaise (which should be overridden using
  local)
. have a class factory (in DT::Format) that does the correct
  thing given input from parsers, i.e.:

  . returns a DateTime object if everything is correct.
  . returns a DateTime::Partial object if some data is missing.
  . returns a DateTime::Undef or throws an exception if there's
incorrect data, depending on the setting of $DateTime::AutoRaise.

Parsers should only parse; all of the above is common code that should
not be re-implemented in all parsers.

Claus
-- 
http://www.faerber.muc.de



Re: DateTime parse(), parser()

2003-07-16 Thread Joshua Hoblitt
 Actually, DT::Undef is just a special case of the proposed DT::Partial
 object.

Not really - it's totally different state.  Any partial time can already be expressed 
with the current DT class.  We just need a means to specify the precision.

-J

--



Re: DateTime parse(), parser()

2003-07-16 Thread Claus Färber
Rick Measham [EMAIL PROTECTED] schrieb/wrote:
 Right, they won't bother using the eval (at first) and so will be forced
 to deal with data problems.  Why is that bad?

 Same with not using $dt-is_undef.

At least the programme fails and prints an error message instead of  
silently using wrong data.

Claus
-- 
http://www.faerber.muc.de



Re: DateTime parse(), parser()

2003-07-16 Thread Ben Bennett
On Wed, Jul 16, 2003 at 10:15:46AM -0400, John Siracusa wrote:
[snip]
 IMO.  Also, I don't think DT::Infinite is in the same boat, because
 that is a legitimate date (that DT::F::Simple must parse, BTW:
 /^([-+])?inf(?:inity)?$/i).  Returning DT::Infinite is not an error!

Is infinity really a simple date?  I think no.  Anyone else want to
weigh in?

   -ben


Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Wed, 16 Jul 2003, John Siracusa wrote:

 Here's my take on handling parse errors, and error handling in general.

 1. I don't like to (unconditionally) die from within libraries except for
 conditions that are totally avoidable.  For example, I die if you forget to
 send a required argument.  But I would not die in a parse() function that is
 expected to handle user-created input!  That would force everyone to use an
 exception-handling style of error checking just to use your modules, which
 is not nice.

Yeah, I can buy this, since parsing is inherently something that can fail,
and it often need not be fatal, because it doesn't indicate a usage error,
as opposed to bad parameters.

 2. I use plain old undef as my error return value, but I sometimes document
 the methods saying that any false value is an indication that there was an
 error.  This works in all methods that return objects (which is most of the
 ones I write, and any parsing method in DT).

This also makes sense.

 3. I make sure I store some sort of sensible error message or code somewhere
 convenient, letting the user of the library know why something failed.  Even
 if it's only Invalid date: 'foobar', it goes a long way towards making
 debugging easier.

 I think this system gives the most flexibility to the user of a library.
 Examples:

 # Use fatal errors
 $dt = DateTime-parse(...) or die DateTime-error;
 $dt-parse(...) or die $dt-error;

 # Use non-fatal errors
 if($dt = DateTime-parse(...)) { ... }
 else { warn DateTime-error }

 if($dt-parse(...)) { ... }
 else { warn $dt-error }

 # Use exception handling
 eval
 {
   $dt = DateTime-parse(...) or die DateTime-error;
   $dt-parse(...) or die $dt-error;
   ...
 };

 if(@$) { ... }

 Finally, I want to immediately help anyone who does this:

 $dt = DateTime-parse(...);
 $dt-set(...);

 By puking all over them right then and there.  While a DT::Undef object
 might be useful for some, it should not be used as a return value in the
 case of an error.  People who want to use it can just do this:

 $dt = DateTime-parse(...) || DateTime::Undef-new;

I agree.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Tue, 15 Jul 2003, Joshua Hoblitt wrote:

   2. My option:
 $day_of_month = STDIN;
 $dt-set( day = $day_of_month )-truncate( to = 'day' );
 print Your day must be a number in the current month if
   $dt-is_undef;
 
  See, most people won't _bother_ with the 3rd line in option 2!  They'll
  just go ahead and use the data.

 How many check to see if it is DT::Infinite?

None of the parsing modules currently return that, and I'm not sure that
they should.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Tue, 15 Jul 2003, Joshua Hoblitt wrote:

 We were talking about returning DT::Undef objects from parsers.  So, for
 example, if the _format_ being parsed _defines_ an unknown or undefined
 date/time an object can be returned that reflects this.  Simply
 returning undef when an object is expected is, IMHO, not a correct
 behavior.

Sure, if the format has something for unknown, I can see the usefulness of
such an object, although since undef also indicates unknown, I'm not sure
that's so bad.

 My fear is that people will start returning DT objects set to something
 like -01-01T00:00:00 to indicate this case.

Yeah, that'd be ugly.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Ben Bennett
Well, I don't think that the simple is supposed to indicate simple to
parse (at the moment the parser is all but simple... but I am trying
to clean it up).  I read it as simple formats, i.e. common formats
that define the date and time in fairly straightforward ways (month names
and numbers for things are fine, next week third thursday in the
next month with a blue moon are not).

The other problem I see is that your regexp only covers English
speaking locales...  I am currently using the DateTime::Locale date to
get locale sensitive information for parsing month and day names.
(Although AM/PM and BC/AD are a bit of a problem, I may need to add
extra information somewhere).

-ben

On Wed, Jul 16, 2003 at 11:30:33AM -0400, John Siracusa wrote:
 On 7/16/03 11:21 AM, Ben Bennett wrote:
  On Wed, Jul 16, 2003 at 10:15:46AM -0400, John Siracusa wrote:
  [snip]
  IMO.  Also, I don't think DT::Infinite is in the same boat, because
  that is a legitimate date (that DT::F::Simple must parse, BTW:
  /^([-+])?inf(?:inity)?$/i).  Returning DT::Infinite is not an error!
  
  Is infinity really a simple date?  I think no.  Anyone else want to
  weigh in?
 
 Either way, I'll weigh in again! :)  Of course it's simple because, in the
 context of DT::F::Simple, simple means simple to parse.  And this is
 pretty darned simple, IMO:
 
   if(/^([-+])?inf(?:inity)?$/i)
   {
 if($1 eq '-')
 {
   return DateTime::Infinite::Past-new;
 }
 
 return DateTime::Infinite::Future-new;
   }
 
 -John


Re: DateTime parse(), parser()

2003-07-16 Thread David Wheeler
On Tuesday, July 15, 2003, at 11:11  PM, Rick Measham wrote:

I'm an anti-fan of die. Die requires wrapping in eval or parsing the 
user's input before passing to -parse_datetime, which is just crazy.

We should only throw errors on programmer error. For example:
$dt-set( weekday = 'Friday' );
should error because there's no 'weekday' parameter for set().
However, we should return DateTime::Undef on user error:
	$dt-set( day = 'Twenty-two' );
because it means that we can now test for DateTime::Undef, letting 
set() do the parsing of the user's input.
This is why you use exception objects, and throw different exceptions 
for user errors vs. programmer error.

David

--
David Wheeler AIM: dwTheory
[EMAIL PROTECTED]  ICQ: 15726394
http://kineticode.com/ Yahoo!: dew7e
   Jabber: [EMAIL PROTECTED]
Kineticode. Setting knowledge in motion.[sm]


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 Joshua Hoblitt
 Infinite dates do not exist. (And neither do undefined ones.)

If you accept that as dates or not, they are both valid pieces of information that 
need to be expressed.

-J

--



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 Eugene van der Pijll
Joshua Hoblitt schreef:
  Infinite dates do not exist. (And neither do undefined ones.)
 
 If you accept that as dates or not, they are both valid pieces of
 information that need to be expressed.

Sure. If the programmer chooses to, by choosing modules that return
them.

But no part of DateTime, the base module, should return these non-dates.
They should only be a result of some action where it makes sense that
something else than a date is returned.

Specifically, the default parser should not return these things, and
other parsers (the DBI ones, for example) should document that they can
return DT::Undef or DT::Inf.

IMHO, as always.

Eugene


Re: DateTime parse(), parser()

2003-07-16 Thread Dave Rolsky
On Wed, 16 Jul 2003, Eugene van der Pijll wrote:

 But no part of DateTime, the base module, should return these non-dates.
 They should only be a result of some action where it makes sense that
 something else than a date is returned.

 Specifically, the default parser should not return these things, and
 other parsers (the DBI ones, for example) should document that they can
 return DT::Undef or DT::Inf.

I'm inclined to agree with you here.

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.  This can be done by using a specific
formatting module, for example for a database which can store infinite
datetime values.  Or by using the set math code, which definitely opens up
the possibility of infinity.

But otherwise, I'd prefer that the user not even have to know that
DT::Infinite exists, because for _many_ people, they won't understand what
it is for.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-16 Thread Eugene van der Pijll
John Siracusa schreef:
 On 7/16/03 3:39 PM, Eugene van der Pijll wrote:
  Infinite dates do not exist.
 
 Infinite DateTime objects do, which was my point.

The Loch Ness monster exists. That doesn't mean that
DateTime::Format::Roman should accept it.

  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.

I must admit that at this point my analogy with the Loch Ness monster
may be said to break down.

 I never suggested that ambiguous forms should be parsed by DT::F::Simple.

Not even 04/05/2003?

  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...

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

Eugene


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 parse(), parser()

2003-07-16 Thread Flavio S. Glock
Eugene van der Pijll wrote:
 Oh, I forgot one: if now is parsed, never should be as well
 (returning DT::Undef). (That one is somewhat sensible to include, even.)

 now is a DT, or a DT function

 never is DT::Set-new_empty

 forever is DT::Set( -inf, inf )

 undef is DT::Undef


- Flavio S. Glock


Re: DateTime parse(), parser()

2003-07-16 Thread Joshua Hoblitt
 The Loch Ness monster exists. That doesn't mean that
 DateTime::Format::Roman should accept it.

Yes it does.  It should accepts Dave's organic cucumbers too.

-J

--



Re: DateTime parse(), parser()

2003-07-15 Thread Iain Truskett
* Bruce Van Allen ([EMAIL PROTECTED]) [15 Jul 2003 04:55]:

[...]
 6. All parsers fail (return undef) if they can't parse a
string, both for good programming practice and to allow
falling through to the next specified/available parser
module;

I'm yet to see a consistent method of handling errors in
Perl modules. Whether an error is thrown or undef is
returned, fall through is quite possible (eval).

What do people think parsers should return if they can't
parse? And what if they do parse, but DateTime doesn't want
to create an object of the appropriate specification?

Should we wrap our methods in evals and return undef?

Should we just throw errors?


[...]

cheers,
-- 
Iain.


RE: DateTime parse(), parser()

2003-07-14 Thread Hill, Ronald
Hi John  Iain

 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 recognizes the sorts of dates you come across. I mostly

I think an example of this type of thing needs to go into the
FAQ. Do you have an example of doing this?


  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)  

I agree with you on this. I feel that there should be a default
simple parser within datetime.

 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 regex 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:
 
[snipped]

 
 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.

[much snippage]

John,

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? 

What do you think?


Ron Hill


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 Dave Rolsky
On Mon, 14 Jul 2003, Hill, Ronald wrote:

  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 recognizes the sorts of dates you come across. I mostly

 I think an example of this type of thing needs to go into the
 FAQ. Do you have an example of doing this?

Actually, it probably belongs directly in the Builder docs.

 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?

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 ;)

I know Graham Barr will be happy to see this, because at OSCON he asked me
when the DateTime project will make his TimeDate stuff obsolete ;)


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


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 Dave Rolsky
On Mon, 14 Jul 2003, John Siracusa wrote:

 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? :)

Maybe.  It would introduce another dependency for DateTime.pm, but OTOH
it's a dependency that most folks would probably end up downloading
anyway.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DateTime parse(), parser()

2003-07-14 Thread John Peacock
John Siracusa wrote:

Great, but the $64K question is: do we then get parse() and parser() methods
in DateTime, which default to use DT::F::Simple? :)
A while ago, when this discussion last reared its [ugly] head, I suggested that 
the base class contain methods which would call an array of potentially more 
expensive parsers, until one returned a value other than undef.  The default 
install would only include the smallest, fastest parser and the user could add 
other to the list.

Thinking about it now, it would make the most sense to me to make 
DateTime::Format be an actual class which would dispatch to the DT::F::something 
modules.  That way, nothing needs to be added to the DateTime class itself, if 
you never need parsing.

John

--
John Peacock
Director of Information Research and Technology
Rowman  Littlefield Publishing Group
4501 Forbes Boulevard
Suite H
Lanham, MD  20706
301-459-3366 x.5010
fax 301-429-5748


Re: DateTime parse(), parser()

2003-07-14 Thread Joshua Hoblitt
 Thinking about it now, it would make the most sense to me to make
 DateTime::Format be an actual class which would dispatch to the DT::F::something
 modules.  That way, nothing needs to be added to the DateTime class itself, if
 you never need parsing.

Not all of the format modules will deal with ambiguous cases in the same way.  This 
sounds dangerous and error prone.

-J

--



Re: DateTime parse(), parser()

2003-07-14 Thread Bruce Van Allen
On Monday, July 14, 2003 John Peacock wrote:
John Siracusa wrote:
 Great, but the $64K question is: do we then get parse() and parser() methods
 in DateTime, which default to use DT::F::Simple? :)
 
A while ago, when this discussion last reared its [ugly] head, I suggested that 
the base class contain methods which would call an array of potentially more 
expensive parsers, until one returned a value other than undef.  The default 
install would only include the smallest, fastest parser and the user could add 
other to the list.

Thinking about it now, it would make the most sense to me to make 
DateTime::Format be an actual class which would dispatch to the DT::F::something 
modules.  That way, nothing needs to be added to the DateTime class itself, if 
you never need parsing.

Some good ideas are converging here. Couldn't the following all be possible:

1. DT::Format as an actual class, per John S;
2. DT::Format has parse() and parser() methods;
3. DT::Format dispatches to DT::F::XXX modules, using DT::F::Simple unless the user 
has called parser().
4. DateTime also has methods parse() and parser(), per John P, which simply invoke 
DT::Format and hand off their params to DT::F's own parse() and parser() methods;
5. If the user doesn't call parse() or parser() from DT, then DT::F and DT::F::XXX are 
never invoked by DT;
6. All parsers fail (return undef) if they can't parse a string, both for good 
programming practice and to allow falling through to the next specified/available 
parser module;
7. parser() -- or parsers()? -- would let the user specify which of the available 
DT::F::XXX modules to use, and the order with which they are tried.



  - Bruce

__bruce__van_allen__santa_cruz__ca__


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 Dave Rolsky
On Mon, 14 Jul 2003, John Siracusa wrote:

  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? :)

No, but it might kill me ;)

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.

 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 ...


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


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 parse(), parser()

2003-07-13 Thread Eugene van der Pijll
John Siracusa schreef:
 All the various DateTime::Format::* modules are nice, but I've been 
 thinking that it would be even nicer if DateTime had some sort of 
 rudimentary parsing built in.

I agree with this; the DateTime constructor tends to get a little
verbose. However, I don't quite agree with your implementation ideas.

   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.

 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.

 I know I'm already 
 tired of picking and loading DateTime::Format::* classes

The answer to this would be to have a Format class which can do
everything, not to have it included in DateTime. You can't have a parser
that magically parses everything, without heavy configuration for
amiguous cases.


IMHO, the reason a parser is needed in DateTime is the verbosity of the
constructor. To define a date I always need 2 lines, which screws up the
formatting/indenting of the program. A shorter contructor would be nice.

My suggestion would be to have a small, very restrictive parse_datetime
method, which is more-or-less the reverse of the datetime() method.

I suggest:

sub parse_datetime {
my ($self, $date) = @_;

if ($date ~= /^(-?\d{4})# year
   (\D?)# optional date separator
   (\d\d)   # month
   \2   # date sep again
   (\d\d)   # day
   [T ]?
   (\d\d)   # hour
   (\D?)# optional time separator
   (\d\d)   # minute
   \6   # time sep again
   (\d\d)   # second
  $/x) {
my ($y, $m, $d, $h, $min, $s) = ($1, $3, $4, $5, $7, $8);
return DateTime-new(year = $y, month = $m, day = $d,
 hour = $d, minute = $min, second = $s);
}
return;
}

This would make it possible to create dates in a compact but
understandable way:

$dt = DateTime-parse_datetime( 2003-07-13T12:38:00 );

I wouldn't use this method for user input, but only to create fixed
dates in my programs.

Eugene


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 Rick Measham
John Siracusa schreef:
 All the various DateTime::Format::* modules are nice, but I've been 
 thinking that it would be even nicer if DateTime had some sort of 
 rudimentary parsing built in.

On Sun, 2003-07-13 at 20:47, Eugene van der Pijll wrote:
 I agree with this; the DateTime constructor tends to get a little
 verbose. However, I don't quite agree with your implementation ideas.
[snip]
 My suggestion would be to have a small, very restrictive parse_datetime
 method, which is more-or-less the reverse of the datetime() method.
[snip]
 $dt = DateTime-parse_datetime( 2003-07-13T12:38:00 );
 
 I wouldn't use this method for user input, but only to create fixed
 dates in my programs.

Yup, this all looks excellent. Unless your input comes from a user or
from a file or some other source this contructor would be great. I often
enter a date by hand that is a static date, with this I can do it
quickly.

Cheers!
Rick



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