Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1243 (closed defect: fixed)

Opened 11 years ago

Last modified 11 years ago

time.Date.doy is not set correctly by time.(Wall)Clock.toDate

Reported by: Deewiant Assigned to: schveiguy
Priority: major Milestone: 1.0
Component: Core Functionality Version: 0.99.4 Frank
Keywords: Cc:

Description

Both time.Clock.toDate and time.WallClock.toDate set the doy (day of year) field of time.Date to 0 instead of the correct value.

I encountered this back in 0.99.4, worked around it, and promply forgot about it...

Change History

08/13/08 21:01:07 changed by schveiguy

  • status changed from new to closed.
  • resolution set to wontfix.

The Clock.toDate and WallClock?.toDate use OS functions to retrieve the date, so if the OS doesn't support getting doy, Clock and WallClock? cannot support it.

You should use an appropriate calendar class' toDate instead.

08/14/08 05:51:49 changed by Deewiant

Then I think it should be explicitly documented that it is not even guaranteed that all the fields have a valid value.

08/14/08 16:25:44 changed by schveiguy

I can do that

09/07/08 00:03:54 changed by BenjiSmith

  • status changed from closed to reopened.
  • resolution deleted.

I just encountered the same thing.

And I read the comment: "All values must fall within the domain supported by the OS" but I just thought it meant that the month field would be bounded between 1 - 12 (and so on). I didn't understand it to mean that certain fields would be returned with incorrect values.

Anyhow, I've written a very simple little patch to the Clock.toDate() function so that it calculates the day-of-year (correctly handling leap-years):

 static DateTime toDate (Time time)
 {
         DateTime dt = void;
         auto timeval = convert (time);
         dt.time.millis = timeval.tv_usec / 1000;

         tm t = void;
         gmtime_r (&timeval.tv_sec, &t);

         dt.date.year    = t.tm_year + 1900;
         dt.date.month   = t.tm_mon + 1;
         dt.date.day     = t.tm_mday;
         dt.date.dow     = t.tm_wday;
         dt.date.era     = 0;
         dt.time.hours   = t.tm_hour;
         dt.time.minutes = t.tm_min;
         dt.time.seconds = t.tm_sec;
         
         // Calculate the day-of-year
         dt.date.doy = dt.date.day;
         switch (dt.date.month) {
             case 1: break;
             case 2: dt.date.doy += 31; break;
             case 3: dt.date.doy += 59; break;
             case 4: dt.date.doy += 90; break;
             case 5: dt.date.doy += 120; break;
             case 6: dt.date.doy += 151; break;
             case 7: dt.date.doy += 181; break;
             case 8: dt.date.doy += 212; break;
             case 9: dt.date.doy += 243; break;
             case 10: dt.date.doy += 273; break;
             case 11: dt.date.doy += 304; break;
             case 12: dt.date.doy += 334; break;
         }
      
         if (dt.date.year % 4 == 0 && dt.date.year % 100 != 0 && dt.date.month > 2)
             dt.date.doy++;
         
         return dt;
 }

I know the rest of the code is purely based on the values provided by the OS, but as a library consumer, I was completely mystified about the missing "doy" field, even after reading the documentation. It wasn't until reading the code, and searching for this bug, that I realized the omission was deliberate.

Would there be anything *wrong* with patching the code?

09/07/08 22:46:05 changed by kris

I wasn't aware that the doy was not set :(

Which O/S ?

09/07/08 22:56:08 changed by kris

  • milestone changed from 0.99.8 to 1.0.

Thanks for the patch, Benji - I think we should add it.

Some background: both the toDate() and fromDate() functions are O/S dependent, though we keep them for now in order to take advantage of DST calculations. When we get a capable and efficient DST implementation, then we'll probably rewrite those functions to be O/S independent and drop the limitations they currently have.

Anyone volunteering for the super-efficient DST implementation? :)

09/11/08 08:05:30 changed by BenjiSmith

I'm on WinXP SP3.

With respect to DST, I haven't the foggiest idea how it's even supposed to work, especially since the rules changed last year in the US (didn't they?)

09/11/08 08:34:42 changed by larsivi

Yea, you moved the sun for a part of the year over there ;) Actually, the rules didn't change afaik, at least not in an international perspective - either times where just moved, or DST enabled - nothing complicated in the big scheme of things.

If this is something that interests you enough to do something about, you may find a lot of documentation/implementation details in the joda time library (although the the API is a bit too big/Java to take much inspiration from).

Typically it means that a local time has these components : UTC + TZ + DST (where DST normally is 0, 30 minutes or 1 hour and TZ can be negative). Problem here and there is that different OS's gives you this information at different points in the API, and needing different parameters to get. You may see if it isn't discussed in some old ticket if you search in the Tango trac.

10/05/08 06:17:01 changed by kris

  • owner changed from sean to schveiguy.
  • status changed from reopened to new.

10/05/08 14:50:06 changed by schveiguy

  • status changed from new to assigned.

Yes, until we get full TimeZone functionality without relying on the os, it's probably a good idea to add doy as a kludge.

12/01/08 18:44:39 changed by schveiguy

  • status changed from assigned to closed.
  • resolution set to fixed.

(In [4142]) Added doy calculation to Clock/WallClock's toDate Fixes #1243