Re: Strptime issues

2003-11-06 Thread Flavio S. Glock
[EMAIL PROTECTED] wrote:
> 
> Sounds good .. and it's as simple as using
> DateTime->today as the base, which may well be a
> good default behaviour for ->to_datetime when no
> base is in the object or none is passed in the call.

So this is what we've got so far:

0.0102  2003-11-06
- to_datetime() uses "today" as a base date, if none was given.
  The following methods are affected by this change:
  epoch, hires_epoch, is_dst, utc_rd_values, utc_rd_as_seconds,
sprintf("%s")
- can_be_datetime()
- has_date(), has_time()
- defined_fields() method, contributed by Rick Measham
- to_datetime() sets fields in a known order,
  instead of hash-order.  Based on a patch by Rick Measham
- Included has() method, contributed by Rick Measham


0.0101  2003-11-03
- runs in Perl 5.00503.
  Dave Rolsky & Flavio S. Glock, creating a cvs conflict :)
- there is no set_locale() in DateTime.
  Modified from a patch by Rick Measham
- fixed an infinite loop in _format_nanoseconds.
  Patch by Rick Measham


This is a sample of the new API:

   $dti = $dti->to_datetime;

   if ( $dti->can_be_datetime ) 
   {
  $dti = $dti->to_datetime
   }
   else
   {
  print "only @{[ $dti->defined_fields ]} are set"
   }

   if ( $dti->can_be_datetime && $dti->has_date ) ...

   if ( $dti->has_date && $dti->has_time ) ...

   if ( $dti->has_year ) ...

   if ( $dti->has( qw( year month day hour ) ) ) ...


- Flavio S. Glock


Re: Re: Strptime issues

2003-11-06 Thread rickmeasham
> Flavio S. Glock <[EMAIL PROTECTED]> wrote: 
>  
> How about to extend the 'to_datetime' method, 
instead of creating a 
> new 
> one: 
>  
>if ($dti->can_be_datetime) { 
>   $dti = $dti->to_datetime 
>} 
>  
 
Sounds good .. and it's as simple as using 
DateTime->today as the base, which may well be a 
good default behaviour for ->to_datetime when no 
base is in the object or none is passed in the call. 
 
Cheers! 
Rick 


Re: Strptime issues

2003-11-06 Thread Flavio S. Glock
Rick Measham wrote:
> 
>if ($dti->can_be_datetime) {
>   $dti->become_datetime
>}

implemented as:

   if ($dti->can_be_datetime) {
  $dti = $dti->become_datetime
   }

because changing the class of '$dti' is a bit hard.


How about to extend the 'to_datetime' method, instead of creating a new
one:

   if ($dti->can_be_datetime) {
  $dti = $dti->to_datetime
   }


- Flavio S. Glock


Re: Re: Strptime issues

2003-11-04 Thread rickmeasham
> Flavio S. Glock <[EMAIL PROTECTED]> wrote: 
> > sub has { 
>  
> I implemented this in CVS with tests, but I believe it  
> should be 2 separate methods instead. What do 
you think? 
 
I'm cool with two different methods ... it really is two 
different things. Maybe there's also a need for 
has_any('hour', 'minute') which returns true if it has 
either of hours or minutes. 
 
> > >   * can_be_datetime / become_datetime 
> > sub can_be_datetime { 
> I think any dti that has_year can become a 
datetime. 
> For example, DT::I->new( year=>2003 
)->become_datetime->datetime 
>   2003-01-01T00:00:00 
 
Hmmm ... I think this is OK, but I'd like some way then 
to control what is required.  
 
$dti->become_datetime if 
$dti->can_be_datetime('minutes')  
 
requires: 
   -MM-DD HH:MM 
   -MM-DD HH:MM:SS 
   -MM-DD HH:MM:SS.N 
and not 
   -MM-DD HH:MM:xx.N 
 
That is, it must have years to minutes and no holes. 
 
 


Re: Strptime issues

2003-11-04 Thread Flavio S. Glock
[EMAIL PROTECTED] wrote:
> 
> > Flavio S. Glock <[EMAIL PROTECTED]> wrote:
> >
> >   * keys or defined_fields
> > returns the list of names of "defined" fields
> 
> sub has {
># called with parameters you get true or false
># called with no params and you get a list of fields

I implemented this in CVS with tests, but I believe it 
should be 2 separate methods instead. What do you think?

> >   * can_be_datetime / become_datetime
> 
> sub can_be_datetime {
># -MM-DD
># -MM-DD HH:MM
># -MM-DD HH:MM:SS
># -MM-DD HH:MM:SS.N

I think any dti that has_year can become a datetime.
For example, DT::I->new( year=>2003 )->become_datetime->datetime
  2003-01-01T00:00:00
Or perhaps, allow any dti without 'holes':
 
 -MM
 -MM-DD
 -MM-DD HH
 -MM-DD HH:MM
 -MM-DD HH:MM:SS
 -MM-DD HH:MM:SS.N
this excludes, for example:
 --DD

- Flavio S. Glock


Re: Re: Re: Strptime issues

2003-11-04 Thread rickmeasham
> [EMAIL PROTECTED] 
<[EMAIL PROTECTED]> wrote: 
> sub has_time { $_[0]->has{'hour', 'minute'} }   
 
Maybe should be: 
sub has_time {  
   return 1 if ($_[0]->has('hour', 'minute') and not 
$_[0]->has('nanosecond')); 
   return 1 if ($_[0]->has('hour', 'minute', 'second'))  
   return 0 
}   
Which only returns true if we have HH:MM or 
HH:MM:SS or HH:MM:SS.N+. The older version 
allowed us to get true for HH:MM:xx.N+ which is not 
really a time. 
 
Same caveat: 
Above code passes all tests on the perl installed in
my head. Havn't tried any of it with the much fussier  
software version.   
   
perl -v   
This is perl, v5.8.0 built for ricks-brain-1.0   
   
   
 


Re: Re: Strptime issues

2003-11-04 Thread rickmeasham
[webmail logged me out, so sorry if you get ++ copies] 
 
> Flavio S. Glock <[EMAIL PROTECTED]> wrote:  
> So this is the current list of proposed  
DT::Incomplete methods that  
> are  
> "waiting for votes":  
>   
>   * epoch  
> $epoch = $dti->epoch  if $dti->can_be_datetime;  
  
Sounds good  
sub epoch {  
   my $self = shift;  
   return undef unless $self->can_be_datetime;  
   return $self->clone->become_datetime->epoch;  
}  
  
>   * has_date / has_time  
  
Sounds good, see below and:  
sub has_time { $_[0]->has{'hour', 'minute'} }  
sub has_date { $_[0]->has{'year', 'month', 'day'} }  
  
  
>   * keys or defined_fields  
> returns the list of names of "defined" fields  
  
sub has {  
   # called with parameters you get true or false  
   # called with no params and you get a list of fields  
   my $self = shift;  
   if (@_) {  
  foreach (@_) {  
 return 0 unless exists $self->{has}{$_}  
  }  
  return 1  
   }  
  return keys %{$self->{has}}  
}  
  
Which gives:  
   print "Got hour" if $dti->has('hour');  
   print "Got time" if $dti->has('hour', 'minute')  
and  
   print "Object has " . join(', ', @{$dti->has} );  
  
  
>   * join( $dti )  
> join the "defined" keys of two DT::Incomplete  
objects  
  
'join' feels like 'append'. 'union' feels better, but relates  
to sets. Maybe 'merge'? Also consider 'overlay'.  
  
dti1 2003-xx-21Txx:18:xx.12345  
dti2 2003-09-22T15:17:xx.x  
  
merge:   2003-09-21T15:18:xx.12345  
overlay: 2003-09-22T15:17:xx.12345  
  
Note that $dti1->overlay($dti2) is the same as  
$dti2->merge($dti1);  
  
  
sub merge { # not 'submerge'!!!  
   my $self = shift;  
   my $dti = shift;  
   die "Argument to merge must be a DateTime or  
DateTime::Incomplete" unless  
ref($dti)=~/^DateTime(::Incomplete)?$/;  
   # There must be a better way to do this:  
   $self->{has}{year} ||= $dti->year;  
   $self->{has}{month} ||= $dti->month;  
   $self->{has}{day} ||= $dti->day;  
   $self->{has}{hour} ||= $dti->hour;  
   $self->{has}{minute} ||= $dti->minute;  
   $self->{has}{second} ||= $dti->second;  
   $self->{has}{nanosecond} ||= $dti->nanosecond;  
  
   $self->{has}{time_zone} ||= $dti->time_zone;  
   $self->{has}{locale} ||= $dti->locale;  
   return $self  
}  
  
sub overlay { $_[0] = $_[1]->clone->merge( $_[0] )  }  
### PROBABLY A VERY UN-KOSHER WAY TO DO  
IT! ###  
  
>   * is_incomplete / is_complete  
  
sub is_complete { $_[0]->has('year', 'month', 'day',  
'hour', 'minute', 'second', 'nanosecond') }  
  
sub is_incomplete { ($_[0]->is_complete) ? 0 : 1 }  
  
  
>   * can_be_datetime / become_datetime  
  
sub can_be_datetime {  
   my $self = shift;  
   # -MM-DD HH:MM:SS  
   # -MM-DD HH:MM:SS.N  
   return 1 if $self->has('year', 'month', 'day', 'hour',  
'minute', 'second');   
  
   # -MM-DD HH:MM  
   # -MM-DD HH:MM::SS, but is already caught  
   return 1 if $self->has('year', 'month', 'day', 'hour',  
'minute') and not $self->has('nanosecond');  
  
   # -MM-DD  
   return 1 if $self->has('year', 'month', 'day')  
  and not ($self->has('hour')  
 or $self->has('minute')  
 or $self->has('second')  
 or $self->has('nanosecond')  
  );  
  return 0;  
}  
  
sub become_datetime {  
   my $self = shift;  
   return undef unless $self->can_be_datetime;   
   my $dt = DateTime->new(  
  year => $self->year,  
  month => $self->month,  
  day => $self->day,  
   );  
   $dt->set_time_zone( $self->time_zone )   
  if $self->has('time_zone');  
   $dt->set( locale => $self->locale )   
  if $self->has('locale');  
   $dt->set( hour => $self->hour, minute => $minute )  
  if $self->has('hour', 'minute');  
   $dt->set( second => $self->second )   
  if $self->has('second');  
   $dt->set( nanosecond => $self->nanosecond )   
  if $self->has('nanosecond');  
   $self = $dt;  DOES THAT DO THE TRICK, OR  
IS IT MORE COMPLEX?   
   return $self;  
}  
  
  
  
Above code passes all tests on the perl installed in  
my head. Havn't tried any of it with the much fussier  
software version.  
  
perl -v  
This is perl, v5.8.0 built for ricks-brain-1.0  
  
  


Re: Strptime issues

2003-11-03 Thread Flavio S. Glock
Rick Measham wrote:
> 
> If so, maybe a method inside Incomplete would be good:
>if ($dti->can_be_datetime) {
>   $dti->become_datetime
>}

I've put this in the TODO.
So this is the current list of proposed DT::Incomplete methods that are
"waiting for votes":

  * epoch
$epoch = $dti->epoch  if $dti->can_be_datetime;

  * has_date / has_time

  * keys or defined_fields
returns the list of names of "defined" fields

  * join( $dti )
join the "defined" keys of two DT::Incomplete objects

  * is_incomplete / is_complete

  * can_be_datetime / become_datetime

- Flavio S. Glock


Re: Strptime issues

2003-11-03 Thread Flavio S. Glock
Rick Measham wrote:
> 
> I'm adapting Strptime to return DateTime::Incomplete objects when it
> gets an incomplete datetime. The old behaviour was to return the lowest
> possible value.
> 
> eg. 'November 2003' used to return 2003-11-01T00:00:00, but will now
> return 2003-11-xxTxx:xx:xx
> 
> I'm currently checking to see if a datetime is possible and only
> returning incomplete if not. Is that a good idea?

How about it to be an option in the Strptime constructor?

  my $Strp = new DateTime::Format::Strptime(
 pattern => '%T',
 locale  => 'en_AU',
 time_zone   => 'Melbourne/Australia',
 incomplete  => 'never' | 'always' | 'maybe'
 );

> If so, maybe a method inside Incomplete would be good:
>if ($dti->can_be_datetime) {
>   $dti->become_datetime
>}
> or else an incomplete could automatically convert itself to a DateTime
> once it had enough information?!?!?
> 
> I figure an Incomplete can become a DateTime if:
> 
> We have a Year, Month and Day, but no time (becomes 00:00:00) -or-
> We have a Year, Month, Day, Hour and Minute -or-
> We have a Year, Month, Day, Hour, Minute and Second -or-
> We have a Year, Month, Day, Hour, Minute, Second and Nanosecond

That's ok to me. Do you already have code to do this?

> 3. Keep the current (shonky) behaviour

That's not too bad, except that DT::Incomplete is a bit slower than
DateTime.

- Flavio S. Glock


Re: Strptime issues

2003-11-03 Thread Flavio S. Glock
Rick Measham wrote:
> 
> I'm adapting Strptime to return DateTime::Incomplete objects when it
> gets an incomplete datetime. The old behaviour was to return the lowest
> possible value.
> 
> eg. 'November 2003' used to return 2003-11-01T00:00:00, but will now
> return 2003-11-xxTxx:xx:xx
> 
> I'm currently checking to see if a datetime is possible and only
> returning incomplete if not. Is that a good idea?
> 
> If so, maybe a method inside Incomplete would be good:
>if ($dti->can_be_datetime) {
>   $dti->become_datetime
>}
> or else an incomplete could automatically convert itself to a DateTime
> once it had enough information?!?!?

I think automatic conversion is not a good thing. I'm thinking about the
other alternatives...

The patches were applied - thanks.

- Flavio S. Glock


Re: Re: Strptime issues

2003-11-03 Thread rickmeasham
> David Hood <[EMAIL PROTECTED]> wrote: 
> Perhaps you should return only the information that 
is given, in an 
> iso 8601 
> compliant format, so for November 2003 you could 
simply return 
> 2003-11. The 
 
Nah, that's not going to happen. The entire point of 
the module is to get a DateTime object. So it's either 
going to be a full DateTime or a 
DateTime::Incomplete. 
 
Also: What's the ISO format for "11pm November"? 


Re: Strptime issues

2003-11-03 Thread David Hood
Perhaps you should return only the information that is given, in an iso 8601
compliant format, so for November 2003 you could simply return 2003-11. The
iso standard is probably useful, especially for things like day of month for
an implied year (--MM-DD) etc. Perhaps format::iso could then be used to
create only an incomplete datetime if there isn't enough information to
create a full datetime object.

Cheers,
David

- Original Message - 
From: "Rick Measham" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, November 03, 2003 5:09 PM
Subject: Strptime issues


> I'm adapting Strptime to return DateTime::Incomplete objects when it
> gets an incomplete datetime. The old behaviour was to return the lowest
> possible value.
>
> eg. 'November 2003' used to return 2003-11-01T00:00:00, but will now
> return 2003-11-xxTxx:xx:xx
>
> I'm currently checking to see if a datetime is possible and only
> returning incomplete if not. Is that a good idea?
>
> If so, maybe a method inside Incomplete would be good:
>if ($dti->can_be_datetime) {
>   $dti->become_datetime
>}
> or else an incomplete could automatically convert itself to a DateTime
> once it had enough information?!?!?
>
> I figure an Incomplete can become a DateTime if:
>
> We have a Year, Month and Day, but no time (becomes 00:00:00) -or-
> We have a Year, Month, Day, Hour and Minute -or-
> We have a Year, Month, Day, Hour, Minute and Second -or-
> We have a Year, Month, Day, Hour, Minute, Second and Nanosecond
>
> But maybe that's just me.
>
>
> My other option with Strptime are:
>
> 1. Always return an Incomplete object, but I doubt that's what people
> would want/expect.
>
> 2. Always return an Incomplete unless we are given a base, in which case
> the base fills in the blanks. This would mean if you have a full
> datetime specifier in some format you still need to pass a DateTime into
> the strptime object in order to receive a DateTime in return:
>
> $strptime = new DateTime::Format::Strptime( base => DateTime->today,
> pattern=$pattern );
> $strptime->parse_datetime("Nov 3, 2003");
> # Returns DateTime: 2003-11-03T00:00:00
>
> $strptime = new DateTime::Format::Strptime( pattern=$pattern );
> $strptime->parse_datetime("Nov 3, 2003");
> # Returns DateTime::Incomplete: 2003-11-03Txx:xx:xx
>
> 3. Keep the current (shonky) behaviour
>
>
> Cheers!
> Rick
>
>
>
>
>
>
>
>