From gene at paragonam.com Fri Feb 29 11:51:54 2008 From: gene at paragonam.com (Eugene Chow) Date: Fri Feb 29 20:52:01 2008 Subject: [egenix-users] date display behavior in mxdatetime 3 Message-ID: <7FFFEAD5-9F2B-4D08-9F8A-249166602579@paragonam.com> I've noticed that date display behavior has changed in version 3 of mxdatetime in an undesirable way: Python 2.4.3 (#1, Apr 7 2006, 10:54:33) [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import mx.DateTime >>> mx.DateTime.__version__ '3.0.0' >>> d=mx.DateTime.Date(2008,1,-1) >>> d >>> d.strftime() 'Thu Jan -1 00:00:00 2008' >>> d==mx.DateTime.Date(2008,1,31) True >>> In version 2, the day is displayed as the actual last day of the month and not "-1". Was this change intentional? Thanks, Gene Chow From mal at egenix.com Fri Feb 29 20:58:17 2008 From: mal at egenix.com (M.-A. Lemburg) Date: Fri Feb 29 20:58:22 2008 Subject: [egenix-users] date display behavior in mxdatetime 3 In-Reply-To: <7FFFEAD5-9F2B-4D08-9F8A-249166602579@paragonam.com> References: <7FFFEAD5-9F2B-4D08-9F8A-249166602579@paragonam.com> Message-ID: <47C863D9.9090401@egenix.com> On 2008-02-29 20:51, Eugene Chow wrote: > I've noticed that date display behavior has changed in version 3 of > mxdatetime in an undesirable way: > > Python 2.4.3 (#1, Apr 7 2006, 10:54:33) > [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin > Type "help", "copyright", "credits" or "license" for more information. >>>> import mx.DateTime >>>> mx.DateTime.__version__ > '3.0.0' >>>> d=mx.DateTime.Date(2008,1,-1) >>>> d > >>>> d.strftime() > 'Thu Jan -1 00:00:00 2008' >>>> d==mx.DateTime.Date(2008,1,31) > True >>>> > > In version 2, the day is displayed as the actual last day of the month > and not "-1". > > Was this change intentional? No, that's a bug. Thanks for reporting it. We'll fix it in 3.0.1. Thanks, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 29 2008) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 From mal at egenix.com Fri Feb 29 21:15:15 2008 From: mal at egenix.com (M.-A. Lemburg) Date: Fri Feb 29 21:15:20 2008 Subject: [egenix-users] date display behavior in mxdatetime 3 In-Reply-To: <47C863D9.9090401@egenix.com> References: <7FFFEAD5-9F2B-4D08-9F8A-249166602579@paragonam.com> <47C863D9.9090401@egenix.com> Message-ID: <47C867D3.1040904@egenix.com> On 2008-02-29 20:58, M.-A. Lemburg wrote: > On 2008-02-29 20:51, Eugene Chow wrote: >> I've noticed that date display behavior has changed in version 3 of >> mxdatetime in an undesirable way: >> >> Python 2.4.3 (#1, Apr 7 2006, 10:54:33) >> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin >> Type "help", "copyright", "credits" or "license" for more information. >>>>> import mx.DateTime >>>>> mx.DateTime.__version__ >> '3.0.0' >>>>> d=mx.DateTime.Date(2008,1,-1) >>>>> d >> >>>>> d.strftime() >> 'Thu Jan -1 00:00:00 2008' >>>>> d==mx.DateTime.Date(2008,1,31) >> True >> In version 2, the day is displayed as the actual last day of the month >> and not "-1". >> >> Was this change intentional? > > No, that's a bug. Thanks for reporting it. We'll fix it in 3.0.1. That appears to be a GCC compiler optimizer - the normalization seems to have been "optimized" away. By adding this patch (which does really do anything): Index: mxDateTime.c =================================================================== --- mxDateTime.c (revision 22888) +++ mxDateTime.c (working copy) @@ -1022,6 +1022,9 @@ DPRINTF("mxDateTime_SetFromDateAndTime: " "yearoffset=%ld absdate=%ld\n", yearoffset,absdate); + DPRINTF("mxDateTime_SetFromDateAndTime: using normalized values:" + "year=%i month=%i day=%i\n", + year,month,day); datetime->absdate = absdate; the correct result gets used: >>> import mx.DateTime >>> mx.DateTime.Date(2008,1,-1).day 31 We'll have to see how we can make GCC do the right thing in all cases and add a test case for this. Thanks, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 29 2008) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 From mal at egenix.com Fri Feb 29 21:43:20 2008 From: mal at egenix.com (M.-A. Lemburg) Date: Fri Feb 29 21:43:26 2008 Subject: [egenix-users] date display behavior in mxdatetime 3 In-Reply-To: <47C867D3.1040904@egenix.com> References: <7FFFEAD5-9F2B-4D08-9F8A-249166602579@paragonam.com> <47C863D9.9090401@egenix.com> <47C867D3.1040904@egenix.com> Message-ID: <47C86E68.1000002@egenix.com> On 2008-02-29 21:15, M.-A. Lemburg wrote: > On 2008-02-29 20:58, M.-A. Lemburg wrote: >> On 2008-02-29 20:51, Eugene Chow wrote: >>> I've noticed that date display behavior has changed in version 3 of >>> mxdatetime in an undesirable way: >>> >>> Python 2.4.3 (#1, Apr 7 2006, 10:54:33) >>> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin >>> Type "help", "copyright", "credits" or "license" for more information. >>>>>> import mx.DateTime >>>>>> mx.DateTime.__version__ >>> '3.0.0' >>>>>> d=mx.DateTime.Date(2008,1,-1) >>>>>> d >>> >>>>>> d.strftime() >>> 'Thu Jan -1 00:00:00 2008' >>>>>> d==mx.DateTime.Date(2008,1,31) >>> True >>> In version 2, the day is displayed as the actual last day of the month >>> and not "-1". >>> >>> Was this change intentional? >> No, that's a bug. Thanks for reporting it. We'll fix it in 3.0.1. Sorry, false alarm on my part: this was already fixed in our repo. That's why my recompile made the problem go away :-) Here's the patch: Index: mxDateTime.c =================================================================== --- mxDateTime.c (revision 22704) +++ mxDateTime.c (working copy) @@ -12,7 +12,7 @@ */ /* Version number: Major.Minor.Patchlevel */ -#define MXDATETIME_VERSION "3.0.0" +#define MXDATETIME_VERSION "3.0.1" /* Define this to aid in finding memory leaks */ /*#define MAL_MEM_DEBUG*/ @@ -766,21 +766,25 @@ return -1; } -/* Calculate the absolute date, year offset and whether the year is a - leap year or not. +/* Normalize the data and calculate the absolute date, year offset and + whether the year is a leap year or not. + Returns -1 in case of an error, 0 otherwise. */ static -int mxDateTime_CalculateAbsDate(int year, - int month, - int day, - int calendar, - long *absdate_output, - long *yearoffset_output, - int *leap_output) +int mxDateTime_NormalizedDate(int year, + int month, + int day, + int calendar, + long *absdate_output, + long *yearoffset_output, + int *leap_output, + int *normalized_year, + int *normalized_month, + int *normalized_day) { int leap; long yearoffset, absdate; @@ -792,7 +796,7 @@ year); /* Is it a leap year ? */ - leap = mxDateTime_Leapyear(year,calendar); + leap = mxDateTime_Leapyear(year, calendar); /* Negative month values indicate months relative to the years end */ if (month < 0) @@ -816,9 +820,9 @@ absdate = day + month_offset[leap][month - 1] + yearoffset; - DPRINTF("mxDateTime_SetFromDateAndTime: " - "yearoffset=%ld leap=%i absdate=%ld\n", - yearoffset,leap,absdate); + DPRINTF("mxDateTime_NormalizedDate: " + "year=%i month=%i day=%i yearoffset=%ld leap=%i absdate=%ld\n", + year, month, day, yearoffset, leap, absdate); if (absdate_output) *absdate_output = absdate; @@ -826,12 +830,39 @@ *yearoffset_output = yearoffset; if (leap_output) *leap_output = leap; + if (normalized_year) + *normalized_year = year; + if (normalized_month) + *normalized_month = month; + if (normalized_day) + *normalized_day = day; return 0; onError: return -1; } + +/* Return the absolute date of the given date in absdate. + + Returns -1 in case of an error, 0 otherwise. + +*/ + +static +int mxDateTime_AbsDate(register int year, + register int month, + register int day, + int calendar, + long *absdate) +{ + return mxDateTime_NormalizedDate(year, month, day, + calendar, + absdate, NULL, NULL, + NULL, NULL, NULL); +} + + /* Sets the date part of the DateTime object using the indicated calendar. @@ -983,12 +1014,16 @@ { long yearoffset,absdate; - if (mxDateTime_CalculateAbsDate(year, month, day, calendar, - &absdate, &yearoffset, NULL)) + if (mxDateTime_NormalizedDate(year, month, day, + calendar, + &absdate, &yearoffset, NULL, + &year, &month, &day)) goto onError; DPRINTF("mxDateTime_SetFromDateAndTime: " - "yearoffset=%ld absdate=%ld\n", - yearoffset,absdate); + "yearoffset=%ld absdate=%ld ", + "year=%i month=%i day=%i (normalized)\n", + yearoffset,absdate, + year,month,day); datetime->absdate = absdate; @@ -3125,14 +3160,12 @@ else if (mx_PyDate_Check(other->argument)) { /* DateTime - PyDate */ long absdate; - mxDateTime_CalculateAbsDate( - PyDateTime_GET_YEAR(other->argument), - PyDateTime_GET_MONTH(other->argument), - PyDateTime_GET_DAY(other->argument), - MXDATETIME_GREGORIAN_CALENDAR, - &absdate, - NULL, - NULL); + if (mxDateTime_AbsDate(PyDateTime_GET_YEAR(other->argument), + PyDateTime_GET_MONTH(other->argument), + PyDateTime_GET_DAY(other->argument), + MXDATETIME_GREGORIAN_CALENDAR, + &absdate)) + goto onError; return mxDateTimeDelta_FromDaysEx( self->absdate - absdate, self->abstime); @@ -3146,14 +3179,12 @@ + (double)PyDateTime_DATE_GET_SECOND(other->argument) + (double)PyDateTime_DATE_GET_MICROSECOND(other->argument) * 1e-6); long absdate; - mxDateTime_CalculateAbsDate( - PyDateTime_GET_YEAR(other->argument), - PyDateTime_GET_MONTH(other->argument), - PyDateTime_GET_DAY(other->argument), - MXDATETIME_GREGORIAN_CALENDAR, - &absdate, - NULL, - NULL); + if (mxDateTime_AbsDate(PyDateTime_GET_YEAR(other->argument), + PyDateTime_GET_MONTH(other->argument), + PyDateTime_GET_DAY(other->argument), + MXDATETIME_GREGORIAN_CALENDAR, + &absdate)) + goto onError; return mxDateTimeDelta_FromDaysEx( self->absdate - absdate, self->abstime - abstime); -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 29 2008) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611