new fan has questions/comments/suggestions

2004-08-05 Thread Ofer Nave

Hello!

I just recently found the DateTime project after spending a good week
studying international standards, chapters in various perl books, and the
various existing modules in CPAN.  I was disastisfied with all existing
solutions, and was just about to start coding my own date object when I
finally stumbled on Rolsky's perl.com article, which then let me to
datetime.perl.org.

I'm reading through the FAQ now, and I swear, my eyes are tearing up from
the beauty of it all.  I'm thrilled to see that someone is finally
developing a well-thought-out, well-designed, comprehensive solution to the
problem of working with dates and times in software.

Of course, I can never leave well-enough alone, so here are a few questions
that occurred to me while reading the FAQ.  I tried looking up some of this
stuff on the mailing list archive without much luck, so I apologize if this
has already been discussed before.


1) Why have different 'new' and 'from_epoch' constructors?  Couldn't one
always use 'new' and have the module figure out what information to
initiatlize itself with by seeing if either the 'year' or 'epoch' name
parameter was passed?  I think it would provide a cleaner and more
consistent interface.

Instead of:

my $date1 = DateTime-new( year  = 2003
   month = 1,
   day   = 1,
  );
my $date2 = DateTime-from_epoch( epoch = time() );

You could do this:

my $date1 = DateTime-new( year  = 2003
   month = 1,
   day   = 1,
  );
my $date2 = DateTime-new( epoch = time() );


2) However, if you continue to provide different constructors, then when
using from_epoch, why require the 'epoch' named paramter?  Why not assume a
single argument is an epoch value?

Instead of:

my $date = DateTime-from_epoch( epoch = time() );

You could do this:

my $date = DateTime-from_epoch( time() );


3) I copied the following code from the Strptime example in Section 2.7 of
the FAQ:

Instead of:

# prints '2003-05-04 12:55:10';
print $dt-ymd . ' ' . $dt-hms;

You could offer one or more of these:

# prints '2003-05-04 12:55:10';
print $dt-ymd_hms;
print $dt-ymdhms;
# prints '2003-05-04 12:55:10.123456789';
print $dt-ymdhmsn;


4) From section 6.13: How do I find yesterday's Date?

Instead of:

my $dt = DateTime-now()-subtract( days = 1 );

Why not add the two most popular uses as convenience functions:

my $dt = DateTime-yesterday();
my $dt = DateTime-tomorrow();

This would be especially useful in business environments where half of the
code that runs daily runs to process the previous day's data (like web
logs), and so yesterday's date is often the first thing calculated in a
script.


Anyway, great job, guys!

Also, is anyone working on Sybase support for DateTime::Format::DBI?

-ofer



Leap seconds / time zone bug in DateTime.pm

2004-08-05 Thread Eugene van der Pijll
There's a bug somewhere in the interaction between leap seconds and time
zones.

In timezones with a positive offset, datetimes after local midnight but
before UTC midnight already are affected by the leap second:

$dt = DateTime-new( year = 1997, month = 7, day = 1,
 hour = 0, minute = 59, second = 59,
 time_zone = '+0100' );
print $dt-iso8601, \n;

# prints 1997-07-01T00:59:60

In timezones with a negative offset it works the other way for datetimes
between UTC midnight and local midnight.

And there's something funny going on with time zones with an offset that
is not an integer number of minutes... e.g.

$dt = DateTime-new( year = 1997, month = 7, day = 1,
 hour = 0, minute = 0, second = 29,
 time_zone = '+00:00:30' );
print $dt-iso8601, \n;

# prints 1997-07-01T23:59:90 !

I've attached a patch for the test files. I haven't looked into the
DateTime.pm code, because both leap second and the time zone handling
code are just too scary!

Eugene


--
Index: t/19leap_second.t
===
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/19leap_second.t,v
retrieving revision 1.22
diff -u -r1.22 19leap_second.t
--- t/19leap_second.t   20 Jul 2004 19:22:26 -  1.22
+++ t/19leap_second.t   6 Aug 2004 01:51:18 -
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests = 74;
+use Test::More tests = 78;
 
 use DateTime;
 
@@ -106,7 +106,7 @@
 is( $t-{utc_rd_secs} , 86400, rd_sec );
 }
 
-# test that we can set second to 60
+# test that we can set second to 60 (negative offset)
 {
 my $t = DateTime-new( year = 1972, month = 6, day = 30,
hour = 20, minute = 59, second = 60,
@@ -118,6 +118,43 @@
 
 {
 my $t = DateTime-new( year = 1972, month = 6, day = 30,
+   hour = 21, minute = 0, second = 0,
+   time_zone = 'America/Sao_Paulo',
+ );
+
+is( $t-second, 0, 'datetime just after leap second' );
+}
+
+# test that we can set second to 60 (positive offset)
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 59, second = 60,
+   time_zone = '+0100',
+ );
+
+is( $t-second, 60, 'second set to 60 in constructor' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 59, second = 59,
+   time_zone = '+0100',
+ );
+
+is( $t-second, 59, 'datetime just before leap second' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 7, day = 1,
+   hour = 0, minute = 0, second = 29,
+   time_zone = '+00:00:30',
+ );
+
+is( $t-second, 29, 'time zone +00:00:30' );
+}
+
+{
+my $t = DateTime-new( year = 1972, month = 6, day = 30,
hour = 20, minute = 59, second = 60,
time_zone = 'America/Sao_Paulo',
  );


Re: new fan has questions/comments/suggestions

2004-08-05 Thread Dave Rolsky
On Thu, 5 Aug 2004, Ofer Nave wrote:

 1) Why have different 'new' and 'from_epoch' constructors?  Couldn't one
 always use 'new' and have the module figure out what information to
 initiatlize itself with by seeing if either the 'year' or 'epoch' name
 parameter was passed?  I think it would provide a cleaner and more
 consistent interface.

 Instead of:

 my $date1 = DateTime-new( year  = 2003
month = 1,
day   = 1,
   );
 my $date2 = DateTime-from_epoch( epoch = time() );

 You could do this:

 my $date1 = DateTime-new( year  = 2003
month = 1,
day   = 1,
   );
 my $date2 = DateTime-new( epoch = time() );

I don't like APIs which can lead to someone confusing themself.  With what
you suggest, I guarantee someone'd do this:

 DateTime-new( epoch = time(), year = 2001 )

and either ask why it doesn't work, or get annoyed at the resulting error.
Plus then we'd have docs saying you can pass _either_ X and Y, or Y and
Z, or X and Z.  ETOOCONFUSING!

 2) However, if you continue to provide different constructors, then when
 using from_epoch, why require the 'epoch' named paramter?  Why not assume a
 single argument is an epoch value?

 Instead of:

 my $date = DateTime-from_epoch( epoch = time() );

 You could do this:

 my $date = DateTime-from_epoch( time() );

Because you can still pass time_zone and locale parameters to this method.

 3) I copied the following code from the Strptime example in Section 2.7 of
 the FAQ:

 Instead of:

 # prints '2003-05-04 12:55:10';
 print $dt-ymd . ' ' . $dt-hms;

 You could offer one or more of these:

 # prints '2003-05-04 12:55:10';
 print $dt-ymd_hms;
 print $dt-ymdhms;
 # prints '2003-05-04 12:55:10.123456789';
 print $dt-ymdhmsn;

There is a datetime method that returns the ISO8601 formatted date.  The
problem with what you suggest is that we then need to allow up to four
separators (date components, date from time, time components, time from
nanoseconds), which starts getting a bit hairy.  I think $dt-ymd('/')
relatively obvious, but $dt-ymdhmsn('/', 'T', ':', ',') is not so clear
;)

 4) From section 6.13: How do I find yesterday's Date?

 Instead of:

 my $dt = DateTime-now()-subtract( days = 1 );

 Why not add the two most popular uses as convenience functions:

 my $dt = DateTime-yesterday();
 my $dt = DateTime-tomorrow();

 This would be especially useful in business environments where half of the
 code that runs daily runs to process the previous day's data (like web
 logs), and so yesterday's date is often the first thing calculated in a
 script.

That's a possibility, although there are _so_ many methods right now I'm
leary of adding more.  OTOH, these are super easy to document.


-dave

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


Re: new fan has questions/comments/suggestions

2004-08-05 Thread Dave Rolsky
On Fri, 6 Aug 2004, Rick Measham wrote:

 All parameters are named in DateTime. It's a convention we use and

s/All/Almost all/

There are some that take positional params.  Those are usually cases where
I expect it to never need more than one parameter, _or_ where it takes a
list of similar parameters (strftime).

But any time it takes more than one dissimilar parameter, it'll be named,
and it's also named in cases where it takes one parameter now, but I
thought that might change in the future.

 HOWEVER, that said, I'd like to see some sort of a default format
 method:
   $dt-set_default_format($strftime_format);
   print $dt-default_format;
   print Stringified with default: $dt;

Someone came up to me at OSCON and asked about whether I wanted a patch
for this and I said yes.  I think it might've been Michael Schwern.

 again. Maybe these should be in DateTime::Format::Business.

 $biz = new DateTime::Format::Business(
   %monday_to_friday_nine_to_five
 )
 $dt2 = $biz-tomorrow( DateTime-now );
 Then when you're open M-F and you ask for tomorrow() on a Friday, you
 get Monday.

This is orthogonal to whether or not those constructor end up in
DateTime.pm, I think.  That said, the functionalityy you're proposing
would no doubt be useful for many people.  I think it'd belong in
DateTime::Fiscal, though.  It's not really a format, so much as a way of
handling complex sets and doing date math on elements of the set (eerr,
does that make sense?).


-dave

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


RE: new fan has questions/comments/suggestions

2004-08-05 Thread Dave Rolsky
On Thu, 5 Aug 2004, Ofer Nave wrote:

 run in epoch mode, and not even pay attention to hour.  Just like it
 wouldn't pay attention to billybob if I passed it ( epoch = time(), billbob
 = 'thornton' ).

Uh, have you tried that?  It'll throw an exception.  I'm a big believer in
dying on bad input, since if the user passes a billybob parameter they
probably expect that to have some effect.

  If you start assuming a single argument is a particular parameter,
  which do you go with in other cases. If you change one
  method, you have
  to be consistent.
  $dt = DateTime-new( 34 );
  Is that 00:00:34 or 00:34:00 or 0034-00-00?

 Well, since year is the only required argument, you'd probably assume it was
 year, and therefore the date would be 0034-00-00 00:00:00.0!  :)  But that's
 probably a habit to encourage/allow.

Nor is it even particularly useful, I'd think.

 Yes, I know, but the idea is to make it convenient to do the most common
 things (which is why ymd() and hms() are, in fact, available), and it seems
 to be like a combined ymd_hms would qualify that list.  Especially being the
 ISO8601 standard time format, and that you often want to print both date and
 time.

Thus the datetime/iso8601 methods (they're the same method internally).


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