Retro68 icon indicating copy to clipboard operation
Retro68 copied to clipboard

time(NULL) still off by the TZ offset

Open gpetersson opened this issue 3 years ago • 2 comments

I waited a while to see if the original closed issue would have additional comments, but maybe you did not see it.

Please check my own comments after issue #141 was closed.

gpetersson avatar Oct 17 '21 23:10 gpetersson

Sorry, been a bit busy, and it's easy to forget coming back to comments on a closed issue. And of course "time calculations are off by 24 hours" and "time zones are not supported" really are two entirely different issues.

Better, but it's still off by the TZ offset. So in my case it is 4 hours slow... I think GetDateTime() must not be returning GMT seconds.

EDIT: I also confirmed under a plain OSX toolchain (gcc 4.0.1 / Xcode 3.0 on 10.5.1) that GetDateTime() does indeed add> the timezone offset to the result.

GetDateTime() indeed returns local time; not because it adds the timezone offset to the result, but precisely because it does not add anything to the result. In pre-Internet times, computer clocks were set to local time and operating systems had no knowledge about time zones.

For reference I was able to get the right value within my own program by just writing my own function:

static unsigned long myTime(void) {
  unsigned long secs = 0;
  long gmtDelta = 0;
  MachineLocation loc = {0};
  const int epochDifferenceInYears = 1970 - 1904;
  const int epochDifferenceInDays =
      365 * epochDifferenceInYears
      + (epochDifferenceInYears + 3)/ 4; /* round up for leap years */

  /* this adds the TZ offset to the result so we must subtract it afterwards */
  GetDateTime(&secs);

  secs -= 86400 * epochDifferenceInDays;

  ReadLocation(&loc);

  gmtDelta = loc.u.gmtDelta & 0xFFFFFF;

  if(BitTst(&gmtDelta, 23)) /* test sign extend bit */
    gmtDelta |= 0xFF000000;

  return secs - gmtDelta;
}

I see two problems here: (a) the BitTst is wrong. BItTst is a strange function that numbers bits from the left, so we need bit 8, not bit 23. Yes, someone at Apple was confused as well, the sample code is plain wrong. Better to write a C-style bit check such as if (gmtDelta & 0x800000) or if ((gmtDelta >> 23) & 1) or if (gmtDelta & (1 << 23)).

(b) ReadLocation starts appearing in Apple docs in the mid-90s. I have not found any information yet on how it behaves on older systems or on when exactly it was introduced.

For most old Macs, we'll have to live with getting local time and not knowing our current tine zone.

autc04 avatar Oct 18 '21 07:10 autc04

It appears to be first introduced in System 7, just judging from the Inside Macintosh books... volume 6 (1991, System 7) is the first time either ReadLocation or time zones in general are mentioned.

My insistance on knowing the time zone stems from my application doing some time-based crypto functions that must match up with data transferred over a network, but such an application would not be very useful on anything earlier than System 7 anyways.

gpetersson avatar Oct 21 '21 00:10 gpetersson