time to gmt

NP about staying warm.

Firing with wood keeps you warm three times; when you chop it, clew it, and burn it. :slight_smile:

Iā€™ll trade scenerys any day. :slight_smile: To be truthful, where my ass is parked is of less significanse, sometimes, I realize, I could have been in jail, without that mattering much, (providet single cell, with internet connection and food brought to the door! :D)

PhysicalTimeToGMT

The handler which I present here, turns your longitudinal position, int the hour angle of your local meredian offset from GMT.
The routine is supposed to be used for finding, the physical position of the earth, at a given time, so that you in turn can find the right ascension of some stellar object, or at least some similiar operation like: If the sun is at zenith at noon in GMT, when can I suspect the sun to be at zenith in my time. The reason I have made, it, is partly to find the right ascension of an object, partly, to figure out how many times the earth as rotated, since Vernal Equinox. The offset the hour angle of your local meredian being the center-piece, in such calculations.

It canā€™t be done without coordinates, (but the coordinates may not be as far away as you think they are, Iā€™ll address this in a post below this.) Obviously, you canā€™t rely on the timezone given by your locale, nor time to GMT for this, since some of us have daylight savings, and some countrieā€™s timezones are politicially chosen, because of trade, or other purposes. So, your timezone, and physical location, with regards to GMT may diverge.

I will now present a handler, that given a longitudinal coordinate as a decimal number, will return the offset of your local meredian to the Prime Meridan, the Greenwhich Meridian.

Since there are at least another, almost totally unrelated quantity named Hour angle, which is the hour angle of the sun, I call the hour angle we obtain here for ā€œoffsetOfhourAngleOfLocalToGMTMeredian by decimalAngleā€.

We donā€™t care about if we are fed geodetic, or geocentric coordinates here at this time, since I honestly havenā€™t thought through that problem, but the two types of coordinates, shouldnā€™t differ by much, and you should be safe if you use map coordinates (geodetic), which you are most likely to get your hands on, (from a book, or the net.

The handler is really supposed to get coordinates in the form [-180ā€¦-1 or [0ā€¦179] but it will convert it if it is in the regular 360Ƌā„¢ form, and shovel off any multiples of 360!

The handler, could of course have been written more compactly, but I donā€™t see any point in turning parts of it into a (flip/flop) function. It doesnā€™t enhance readability, and an if test, must be faster than a modulus operation.

The hour angles of a local meridan (hereafter hour angles) are divided into 24 from 0 up to and including 23, said differently from and including 0, up to but not including 24. This principle just used that we are including the first term, but not the second, permeats the whole founcation from the calulation here.

Example:

Every meredian of a local timezone has a width of 15 degrees, the Greenwhich Meredian starts at -7.5Ƌā„¢ and continues up to, but doesnā€™t include 7.5 degrees, where the Meredian of the timezone with an offset of 1 hour angle to the Greenwhich Meredian starts. If we had included 7.5Ƌā„¢ in the Greenwhich Meredian, then it would have consisted of 16 degrees, and 16 times 24 = 384, clearly not what we are after.

The rest of the handler should be fairly evident, I all just state a last relation, a position, to the east of Greenwhich is Greenwhich + something, since the earth rotates westwards (hence sun gets up in the east, it reaches Greenwhich, before the position east of it. And a last fact, at noon, when you face the sun, the sun is directly south of your position.


to offsetOfhourAngleOfLocalToGMTMeredian by decimalAngle
	
	# we remove any superfluos degrees first.
	set decimalAngle to decimalAngle mod 360
	
	# we make angles Ć¢ā€°Ā„ 180 into negatives
	if decimalAngle Ć¢ā€°Ā„ 180 then
		set decimalAngle to decimalAngle - 360
	end if
	local hourAngle
	if decimalAngle < 0 then
		set decimalAngle to (decimalAngle * -1) - 0.1
		# we have to skew the numbers by -0.1 to keep
		# boundary conditions
		set hourAngle to (24 - ((decimalAngle + 7.5) div 15)) mod 24
	else
		set hourAngle to (decimalAngle + 7.5) div 15
	end if
	return hourAngle
end offsetOfhourAngleOfLocalToGMTMeredian


set res to offsetOfhourAngleOfLocalToGMTMeredian by -8.6
# or whatever

Edit

I should have mentioned, that youā€™ll find a handler for converting from deg,h,m,s to a decimal angle here, and the handler as well.

Addendum

Sometimes it may be convenient to have an hour angle given in Ā±12 hours.
Therefore the handler below.


# Converts an hour angle given in the interval 0 - 23 
# to intervals -1..-12 and  0..11  offset to before or after
# the Greenwhich Meredian.
# set semiH to semiCircHourAngle from 1
to semiCircHourAngle from CircularHourAngle
	if CircularHourAngle > 11 then
		return ((12 - (CircularHourAngle mod 12)) * -1)
	else
		return CircularHourAngle
	end if
end semiCircHourAngle

Hello.

This script, retrieves, your coordinates with respect to physical location, as defined in the Date and Time System Preferences pane. I for no other purpose, it provides data to your physical location, with respect to the number of hours offset from GMT. The handler for doing that, can be found in the post above. Let me say that the handler above returns an hour angle of the format 0-23, should you whish to have it return the offset in +/12 hours, then see the addendum to the post above.

FI had never figured this out, hadnā€™t it been for Adam Bellā€™s post nr 2 in This Thread. This put me on the right trace, when it came to looking for coordinates, for the ā€œnearby townā€, which I of course found on the last attempt.

Please read post #43 for related handlers and further pointers.


	to longitudeAsInTimePreferences()
		local LocalRegion, decimalDegree, theMinutes, theSeconds
		try
			tell (do shell script "ls -al /etc/localtime") to set LocalRegion to word -2 & "." & word -1
		on error
			error "longitudeAsInTimePreferences: something is wrong, do you have a position specified in Time Preferences?" number 5000
		end try
		tell (do shell script "sed -ne '/" & LocalRegion & "/ s/.*\\([-+][[:digit:]]*\\).*/\\1/p' </usr/share/zoneinfo/zone.tab")
			try
				if length of it is 6 then
					set {decimalDegree, theMinutes} to {(text 1 thru 4 of it as number), (text 5 thru -1 of it as number)}
					if theMinutes Ć¢ā€°  0 then
						set decimalDegree to decimalDegree + theMinutes / 60
					end if
				else # length of it is 8 Thanks to kel1 fo showing me. 
					set {decimalDegree, theMinutes, theSeconds} to {(text 1 thru 4 of it as number), (text 5 thru 6 of it as number), (text 7 thru -1 of it as number)}
					if theMinutes Ć¢ā€°  0 then
						set theMinutes to theMinutes / 60
					end if
					if theSeconds Ć¢ā€°  0 then
						set theSeconds to theSeconds / 3600
					end if
					set decimalDegree to decimalDegree + theMinutes + theSeconds
				end if
			on error
				error "longitudeAsInTimePreferences: something is wrong, do you have a /usr/share/zoneinfo/zone.tab file on your system?" number 5000
			end try
		end tell
		return decimalDegree
	end longitudeAsInTimePreferences

Hi McUsr,

Iā€™ve wanted a script to calculate the latitude and longitude in decimal degrees. On the internet they usually give it in hours, minutes and seconds. When I run your script I get -71.5. So this should be the degree offset west from the prime meridian?

Edited: I found this at wikipedia to get decimal degrees from degrees, minutes and seconds:
DD = D + M/60 + S/3600
Iā€™ll look over your script to find out whatā€™s going on.

Thanks,
kel

Hi McUsr,

When I run the following:

tell (do shell script "ls -al /etc/localtime") to set LocalRegion to word -2 & "." & word -1

set micro_secs to (do shell script "sed -ne '/" & LocalRegion & "/ s/.*\\([-+][[:digit:]]*\\).*/\\1/p' </usr/share/zoneinfo/zone.tab")

I get:
ā€œ-1575130ā€
It looks like -157 degrees, 51 min., 30 secā€¦ Or is it decimal -157.5130 degrees.

Iā€™ll try to find somewhere with the decimal degrees.

Edited: They show about 51ā€™ 30"". so it should be in decimal:

-(157 + 51/60 + 30/3600) = -157.858333333333 decimal degrees.

Thanks for finding Adamā€™s post and your script.

Edited: on Google I get:
21.3000Ā° N, 157.8167Ā° W
Honolulu, Coordinates
So itā€™s close about .04 off from Honolulu. Wonder why the discrepancy. I wonder what the distance difference is for .04.

Edited: it has been a while reading this post, but just found and remember that Nigel already found the minutes and seconds.

gl,
kel

Hello.

I have now updated it to find seconds as well, soon in the post above, but in the CoordDegLib you should find a link to in post #43 you should really see that post in context.

In the CoordDegLib, there is a handler that converts a decimal-angle to minutes of arc, and multiply with a Nautical Mile in metres, as 1852 metres, approximates one minute of arc of longitude at Equator.

Edit

I have now updated the post #44 to reference post #43, and thanks for finding the bug kel!

As for the deviation, it may be just that it is the deviation of the magnetic pole, that is correlated for in Googleā€™s system, or it may be usage of Geodetic/Geocentric coordinates (not sure about that), since that would only have effect for latitude, or so I guess.

In the posts above, you should find all the handlers you need. (everything of this is in CoordDegLib, found here. Back to sleepā€¦ :slight_smile:

Hi,

One last question and I hope someone didnā€™t answer it yet :), but how do you get your latitude?

Edited: you see I need to enter the latitude in a calendar app to make events.

Thanks,
kel

Hello kel1:

Well, you could use the first number in the ā€œzone.tabā€ file. But if you want to have something more close, if for instance the city that is supposed to be the nearest, isnā€™t that close, then I recommend either googling the latitude as found in some database, or from an Atlas. I really just use the longitude from this database to figure out the time zone, as the timezone, is within a fan of 15Ƌā„¢ (24 timezones = 360Ƌā„¢), so the longitude doesnā€™t matter that much for this.
Even though it is the physical time to GMT one talks about. Then you can adjus this by your real longitude later on, which you probably donā€™t find in the zone.tab file. This is data I prefer to either having entered into a script by a dialogue, or by hard coding in properties, as the the process is a tad too cumbersome. (Creating, and compiling zone info files, updating zone tab, and all that, maybe after having downloaded and compiled tools.) :slight_smile:

Hi McUsr,

I need the latitude to find the sunrise and sunset times for Calendar. I was thinking that eventually Iā€™d make my own application to do this.

After you mentioned reading the zone.tab file, I remembered someone in this thread posting to read that file. Iā€™ll check that out.

Thanks,
kel

Hello kel.

Here is a handler for you to find the latitude.

It so happens that Nigel Garvey, has made a sunrise/sunset script for me, and I think you now is a self-established first victim to try it, once I have it finished. :slight_smile: ( I really hope you will test it, it just need a little bit work for being more userfriendly, than it is today, and thatā€™s not Nigelā€™s fault, just having said it, its origin dates back to the 80ā€™s!).

set ml to latitudeAsInTimePreferences()
to latitudeAsInTimePreferences()
	local LocalRegion, decimalDegree, theMinutes, theSeconds
	try
		tell (do shell script "ls -al /etc/localtime") to set LocalRegion to word -2 & "." & word -1
	on error
		error "longitudeAsInTimePreferences: something is wrong, do you have a position specified in Time Preferences?" number 5000
	end try
	tell (do shell script "sed -ne '/" & LocalRegion & "/ s/^[^-+]*\\([-+][[:digit:]]*\\).*/\\1/p' </usr/share/zoneinfo/zone.tab")
		try
			if length of it is 5 then
				set {decimalDegree, theMinutes} to {(text 1 thru 3 of it as number), (text 4 thru -1 of it as number)}
				if theMinutes Ć¢ā€°  0 then
					set decimalDegree to decimalDegree + theMinutes / 60
				end if
			else # length of it is 8 Thanks to kel1 fo showing me. 
				set {decimalDegree, theMinutes, theSeconds} to {(text 1 thru 3 of it as number), (text 4 thru 5 of it as number), (text 6 thru -1 of it as number)}
				if theMinutes Ć¢ā€°  0 then
					set theMinutes to theMinutes / 60
				end if
				if theSeconds Ć¢ā€°  0 then
					set theSeconds to theSeconds / 3600
				end if
				set decimalDegree to decimalDegree + theMinutes + theSeconds
			end if
		on error
			error "latitudeAsInTimePreferences: something is wrong, do you have a /usr/share/zoneinfo/zone.tab file on your system?" number 5000
		end try
	end tell
	return decimalDegree
end latitudeAsInTimePreferences

Signing off for the evening.

I think I found the path to the zone.info file in Nigelā€™s post #16.

Edited: I just saw your above post with the path. Thanks, Iā€™ll check it out.

Hi McUsr,

It works on my computer! :smiley:

One thing good about having scripts that you can modify is that you can make them more accurate than downloaded applications.

Edited: the app Iā€™m using to make the events in Calendar has a lot of bugs. But it has some good ideas. I think this is the one:
http://osx.iusethis.com/app/sunrisesunset
It needs the time to GMT also besides the latitude and longitude.

Thanks a lot,
kel

Hello.

This is a handler, that returns the time to GMT for a given date ( object), it really only works for offsets in whole hours, so if you need a different resolution, ( minutes) then you will have to rework it.

on timeToGMTForaDate(TZ1date, TZ1)
	# Works only for offsets in full hours
	tell (do shell script ("date -jf '%FT%T' '" & (TZ1date as Ā«class isotĀ» as string) & "' '+%H' ; eraTime=$(date -jf '%FT%T' '" & (TZ1date as Ā«class isotĀ» as string) & "' '+%H') export TZ=GMT ; date -r \"$eraTime\" '+%H'"))
		set timeToUTC to (paragraph 2 of it) - (paragraph 1 of it)
	end tell
	return timeToUTC
end timeToGMTForaDate

Hello.

Here is an improvement, or other version of the former, now you donā€™t have to specify the timezone you are in, and the result is returned in seconds, which is better than hours really.

It is Nigel Garvey that made the handler that makes it possible, and Adam Bell is the one that figured out how to
find the timezone that is used in the Time Preferences of your Mac!

# set dt1 to (current date)
# set timetogmt2 to politicalTimeToGmtFromLocalTZInSeconds(dt1)
on politicalTimeToGmtFromLocalTZInSeconds(AnAsDate)
	local nearestCity, dateCopy
	set nearestCity to (do shell script "readlink /etc/localtime |sed -n 's_/[^/]*/[^/]*/[^/]*/\\([^/]*\\)/\\([^/]*\\).*_\\1/\\2_p'")
	set dateCopy to AnAsDate
	return (AnAsDate - TZtoTZ(dateCopy, nearestCity, "GMT"))
end politicalTimeToGmtFromLocalTZInSeconds

on TZtoTZ(TZ1date, TZ1, TZ2)
	# Nigel Garvey 
	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

Hello.

Here is a cheap way to figure out if the user is using a US formatted date, ( mm.dd.yyyy). If felt this was the right place to post it, since it leverages upon Ā«class isotĀ». (It is funny that Ā«class isotĀ» gets coereced, when you coerece to string, but not to text. :slight_smile: ).

Nigel Garvey has made a much better one, that works regardless of item delimiter in post #62.

on us_datum()
	-- should work for SL and later. 
	local ofs
	set ofs to 0
	repeat
		tell ((current date) + ofs)
			local tids, ditems, sitems
			set {tids, AppleScript's text item delimiters} to Ā¬
				{AppleScript's text item delimiters, {"-", "T"}}
			set ditems to text items of (it as Ā«class isotĀ» as string)
			set AppleScript's text item delimiters to "."
			set sitems to text items of (short date string of it)
			set AppleScript's text item delimiters to tids
			if item 2 of ditems is not item 1 of sitems then
				return false
			else if item 3 of ditems Ć¢ā€°  item 2 of ditems then
				return true
			else
				-- We'll have to do one more test! (2013.2.2 and such dates.)
				set ofs to 12 * days
			end if
		end tell
	end repeat
end us_datum

Hi McUsr,

I was wondering how you could find the userā€™s date formatting! There is one thing. Some peopleā€™s dates are ā€œ/ā€ delimited and not ā€œ.ā€ Need to check for that. Modified ā€œ.ā€ to ā€œ/ā€ for my system:

on us_datum()
	-- should work for SL and later. 
	local ofs
	set ofs to 0
	repeat
		tell ((current date) + ofs)
			local tids, ditems, sitems
			set {tids, AppleScript's text item delimiters} to Ā¬
				{AppleScript's text item delimiters, {"-", "T"}}
			set ditems to text items of (it as Ā«class isotĀ» as string)
			set AppleScript's text item delimiters to "/"
			set sitems to text items of (short date string of it)
			set AppleScript's text item delimiters to tids
			if item 2 of ditems is not item 1 of sitems then
				return false
			else if item 3 of ditems Ć¢ā€°  item 2 of ditems then
				return true
			else
				-- We'll have to do one more test! (2013.2.2 and such dates.)
				set ofs to 12 * days
			end if
		end tell
	end repeat
end us_datum

us_datum()

Edited: just thought of this. Maybe you can check for non-digits and find what the delimiters are. Because, I think the user can set it to anything (not sure) in preferences.

Later,
kel

Hereā€™s a Mavericks alternative. Put it in an ASObjC library and call it:

use scripting additions
use framework "Foundation"

on getGMTOffsetFor:theDate
	set theNSDate to my makeNSDateFrom:theDate
	set theZone to current application's NSTimeZone's localTimeZone()
	return (theZone's secondsFromGMTForDate:theNSDate) as integer
end getGMTOffsetFor:

on makeNSDateFrom:theASDate
	set dateString to "1-1-1904 00:00:00"
	set refDate to date dateString
	set theDiff to theASDate - refDate - 3.061152E+9 - (time to GMT) + (current application's NSTimeZone's localTimeZone()'s daylightSavingTimeOffset())
	set newDate to current application's NSDate's dateWithTimeIntervalSinceReferenceDate:theDiff
	log (newDate's description() as text)
	return newDate
end makeNSDateFrom:

Call it with:

use theLib : script "<lib name>" 
use scripting additions

theLib's getGMTOffsetFor:(current date)

Hello.

I think Iā€™ll live with the alternative, until I eventually need something backward compatible.
Iā€™ll fix the handler I posted for now anyway. -Tomorrow! :slight_smile:

Edit

I really donā€™t have to fix my version some posts above, as Nigel Garvey has made a much better one in post #62.

Hi Shane,

I canā€™t figure out why Iā€™m getting a compile syntax error here:

log (newDate's description() as text)

Expected ā€œ,ā€ but found ā€œ(ā€. with the parenthesis highlighted in description(). If I put a ā€œ:ā€ after description, then it compiles.

THanks,
kel

Put pipes around description:

|description|()

Something there is conflicting with the term.