I believe I have the same daylight savings time as Juergen, provided that the 27.10.2012 or whatever date was the last sunday of october. The subtraction of the two dates fail to take the extra hour into account as you move the time forward again, (You can sleep one hour longer :)).
The smoothest way I can think of when it comes to calculate time intervals between timezones, is to convert to seconds since Epoch, and convert from seconds since Epoch back into date/time.
That is ok, when you are dealing with whole years, since it will even out over a year. If you convert a date/time for a Timezone (TZ) into seconds since Epoch (1970.01.01:00:00 ) I think that calculation should be calculated correctly by the date functions. But you have to use the correct TZ at that given point in time. (Daylight savings or not).
The same thing goes around, when converting from seconds since Epoch to a timezone, you’ll have to know the end result, maybe perform a preflight operation, to see what date you’ll end up with, and then perform the calulcation again, if the date/time is within daylight savings time. (Or just subtract the factor).
This is a hard one to fix in AppleScript. But there are handlers for converting from a date to seconds since Epoch, I can’t remember those functions consider TZ last time I looked, but that shouldn’t be to hard to fix, by setting LC_ALL or LC_TZ in between the calls to the unix date function.
This should at least be as “clean” a solution as it is possible to get. however, some heuristics for dealing with the individual timezones, is needed, you’ll have to know if daylight savings time is active in the timezone for the end-date you are converting to. (And you’ll of course have to use the correct timezone forthe timezone you are converting from.
I edited my post heavily! My conclusion is that applescript date-objects, aren’t practical for anything else, than working with the time and date in your local timezone, if you work with several timezones, then having variables with time to Epoch in seconds, may turn out to be simpler to deal with. ( I believe a date object in Applescript ends up with being in local time anyway.)
on TZtoTZ(TZ1date, TZ1, TZ2)
return (do shell script ("eraTime=$(TZ=" & TZ1 & " date -jf '%Y-%m-%dT%H:%M:%S' '" & (TZ1date as «class isot» as string) & "' '+%s') ; TZ=" & TZ2 & " date -r \"$eraTime\" '+%Y-%m-%dT%H:%M:%S'") as «class isot») as date
end TZtoTZ
set dt1 to date ("26.10.2013 12:00")
set dt2 to date ("27.10.2013 12:00")
(TZtoTZ(dt2, "Europe/Berlin", "GMT") - TZtoTZ(dt1, "Europe/Berlin", "GMT")) / hours --> 25.0
on TZtoTZ(TZ1date, TZ1, TZ2)
return (do shell script ("eraTime=$(TZ=" & TZ1 & " date -jf '%Y-%m-%dT%H:%M:%S' '" & (TZ1date as «class isot» as string) & "' '+%s') ; TZ=" & TZ2 & " date -r \"$eraTime\" '+%Y-%m-%dT%H:%M:%S'") as «class isot») as date
end TZtoTZ
on timeToGMT on dt for TZ
return dt - TZtoTZ(dt, TZ, "GMT")
end timeToGMT
set dt1 to date ("26.10.2013 12:00")
set localTZ to (do shell script ("readlink '/etc/localtime' | sed 's|/usr/share/zoneinfo/||'"))
timeToGMT on dt1 for localTZ
on TZtoTZ(TZ1date, TZ1, TZ2)
return (do shell script ("eraTime=$(TZ=" & TZ1 & " date -jf '%Y-%m-%dT%H:%M:%S' '" & (TZ1date as «class isot» as string) & "' '+%s') ; TZ=" & TZ2 & " date -r \"$eraTime\" '+%Y-%m-%dT%H:%M:%S'") as «class isot») as date
end TZtoTZ
set dt1 to date ("10/26/2013 12:00")
set dt2 to date ("10/27/2013 12:00")
(TZtoTZ(dt2, "Europe/Berlin", "GMT") - TZtoTZ(dt1, "Europe/Berlin", "GMT")) / hours --> 25.0
Setting System Preferences to 24 hour clock didn’t make it work, but adding PM to the times did work.
on TZtoTZ(TZ1date, TZ1, TZ2)
return (do shell script ("eraTime=$(TZ=" & TZ1 & " date -jf '%Y-%m-%dT%H:%M:%S' '" & (TZ1date as «class isot» as string) & "' '+%s') ; TZ=" & TZ2 & " date -r \"$eraTime\" '+%Y-%m-%dT%H:%M:%S'") as «class isot») as date
end TZtoTZ
set dt1 to date ("10/26/2013 12:00 PM")
set dt2 to date ("10/27/2013 12:00 PM")
(TZtoTZ(dt2, "Europe/Berlin", "GMT") - TZtoTZ(dt1, "Europe/Berlin", "GMT")) / hours --> 25.0
Where do you get the locations from like “Europe/Berlin”?
In this particular case, I just used “Europe/Berlin” because that’s what juergen said was his time zone in post #6. One way to get the time zone on the local computer is, as in post #16, to parse the POSIX path pointed to by the symbolic link “/etc/localtime”:
set localTZ to (do shell script ("readlink '/etc/localtime' | sed 's|/usr/share/zoneinfo/||'"))
This was interesting, I started to dig a little into the zoneinfo files that lies below /usr/share.
When I use the command zdump zoneinfo/US/Hawaii I get the current time back, according to the manual, in utc. So, they don’t do much useful, the commands to read tzone files from the shell. I think you’ll have to set the LC_TZ to something for their usefullness to kick in.
I was hoping to get the offset or something, instead I ended up with the knowledge that leap seconds aren’t included in posix time (seconds since epoch.) (man time2posix)
What you’re seeing is correct; you’re just not looking at the full picture. Change your script to this:
set dt1 to date ("26.10.2013 12:00")
set dt2 to date ("27.10.2013 12:00")
log dt1
log dt2
(dt2 - dt1) / hours
Now go to System Preferences, Language & Text, and change the Medium format for time display so that it also includes the timezone. Run the script and look at the logged values. You might now agree with AppleScript
If you want to do much with AS dates, the key is to ignore the string value, and just deal with the underlying components.
It’s better to use the same list as the mac does, that is the IANA Time Zone Database. Here you can download the plain text versions of the files that are serialized in /usr/share/zoneinfo. When downloading these plain text files you can look into these files and see the history of time settings.
I’ll just add to what is written above: I believe there is a way to decompile the zoneinfo files. but zdump gives you some output, zdump -v exactly what DJ Bazzie Wazzie said. You should get further pointers by looking at man zdump.
As a user, the most usage you have of the zone-info database is the timezone names really, and you’ll use those to set the TZ variable with them, then use the date to see the new time. Perfect for making a world clock with AppleScript. Berlin London Paris New York Tokoyo.
It’s equivalent to the “yyyy-mm-dd” part. The time part can be obtained with “%T”. So in my TZtoTZ handler, “%Y-%m-%dT%H:%M:%S” can be reduced to “%FT%T”. Thanks for the heads-up!
The formatting is actually done by strftime.
on TZtoTZ(TZ1date, TZ1, TZ2)
return (do shell script ("eraTime=$(TZ=" & TZ1 & " date -jf '%FT%T' '" & (TZ1date as «class isot» as string) & "' '+%s') ; TZ=" & TZ2 & " date -r \"$eraTime\" '+%FT%T'") as «class isot») as date
end TZtoTZ