Convert number into date

Hello all,
I have a file containing numbers, for example: -987276595 (it is a negative number), which happens to be the date and time in seconds since Friday, 1 January 1904 12:00:0) AM, which I understand is the Mac epoch (or at least was for pre OS X, not sure if this is true for OS X as that’d probably use the unix epoch).

What I want to be able to do is to convert this number back into a date, and I’m looking for some pointers on how to do this.

I know the number -987276595 equates to Friday, 24 October 2008 11:58:21 AM if that is any help.

set D to (date "Friday, January 1, 1904 12:00:00 AM") + 9.87276595E+8
--> date "Sunday, April 14, 1935 7:29:55 PM"

I saw something like this many years ago. The numbers are 32-bit Mac clock register values. 0 represents 1 January 1904 00:00:00 and (2 ^ 32 - 1) is 6 February 2040 06:28:15. One second up from that, the value becomes 33-bit, which means that all the bits in the clock register go to 0 again. The values are unsigned (ie. all positive) as far as the clock’s concerned, but whatever produced Marcus’s numbers has interpreted the hi bit as a sign bit, rendering numbers above (2 ^ 31 - 1) as negatives counting up to 0.

(date "Friday 1 January 1904 00:00:00") + 2 ^ 32 - 9.87276595E+8
--> date "Friday 24 October 2008 10:58:21"

Positive numbers in the file have to be added to date “Friday 1 January 1904 00:00:00”, while negatives must be added (as negatives, or subtracted as positives ;)) to date “Monday 6 February 2040 06:28:16”.

Mind you, I’ve assumed here that the “numbers” in the file are text. If in fact they happen to be 64-bit integer data, the dates might be got more directly something like this:

read myFile from x for 8 as date

Ni Nigel,

What can I say? I am impressed!

Best regards,

Martin

Or perhaps more simply:

on numToDate(n)
	return (date "Friday 1 January 1904 00:00:00") + (4.294967296E+9 + n) mod 4.294967296E+9 -- 4.294967296E+9 is 2 ^ 32.
end numToDate

set n to -9.87276595E+8
numToDate(n)
--> date "Friday 24 October 2008 10:58:21"

There’s an hour’s difference between this result and the result you wanted, which is attributable to daylight-saving time being in force on that date. If we assume ” with no more justification than it seems a good idea ” that Mac clocks run in GMT, we might get the local date/time like this:

on numToDate(n, timezone)
	set Mac2Unix to 2.0828448E+9 -- (date "Thursday 1 January 1970 00:00:00") - (date "Friday 1 January 1904 00:00:00")
	set clockRange to 4.294967296E+9 -- 2^32
	
	-- Convert the (assumed GMT) number from Mac to Unix.
	set UnixNumber to (n + clockRange) mod clockRange - Mac2Unix
	-- Get the date in the required timezone as "yyyymmddhhmmss" and coerce that to a number.
	set UnixHi to UnixNumber div 100000000
	if (UnixNumber < 0) then
		if (UnixHi is 0) then set UnixHi to "-"
		set UnixLo to text -8 thru -1 of (-100000000 + UnixNumber mod 100000000 div 1 as text)
	else
		set UnixLo to text -8 thru -1 of (100000000 + UnixNumber mod 100000000 div 1 as text)
	end if
	set dateNum to (do shell script "TZ=" & timezone & " date -r " & UnixHi & UnixLo & " +%Y%m%d%H%M%S") as number
	-- Analyse that number to build an AppleScript version of the date.
	set theDate to date "Monday 1 December 1000 00:00:00"
	tell theDate to set {its year, its day, its day, its time} to {dateNum div 1.0E+10 - 1, dateNum mod 1.0E+10 div 100000000 * 32, dateNum mod 100000000 div 1000000, dateNum mod 1000000 div 10000 * hours + dateNum mod 10000 div 100 * minutes + dateNum mod 100}
	
	return theDate
end numToDate

set n to -9.87276595E+8
set timezone to "Europe/London"
numToDate(n, timezone)
--> date "Friday 24 October 2008 11:58:21"

This script’s based purely on wishful thinking about Mac clocks running in GMT, but it might contain some useful ideas. Good luck. :rolleyes:

Edit: Some debugging in the second script.

< stands with mouth agape >

Thank you for all your replies! Very much appreciated.