Figure out time by latitude/longitude? - iphone

Here's the deal. I have a latitude/longitude set of a location. I need to figure out what the current time is in that location. Here's how I was getting it before:
NSDateFormatter *theFormatter = [[NSDateFormatter alloc] init];
[theFormatter setDateFormat:#"h:mm a"];
NSDate *todaysdate = [NSDate date];
NSString *todaysDate = [theFormatter stringFromDate:todaysdate];
[theFormatter release];
However, I realized that this will give the time for the user's current location. Is there an API somewhere that gives me the time based off of a lat/lon pair?
Thanks in advance.

Unfortunately timezones (and time in general) is never as simple as you would like.
For a simple approximation you can follow jer's suggestion. Longitude ranges from -180 to 180 degrees, there are 24 hours in a day, so you get 15 degrees of longitude per time zone. Center those time zones on 0 degrees longitude so UTC extends from -7.5 to 7.5, UTC+1 is from 7.5 to 22.5, UTC-1 is from -7.5 to -22.5, and so on. You would then have a very simplistic, and wrong, model of how we use time zones.
Take a look at this map of time zones.
Time zones are not well ordered; regions in UTC-1 are adjacent to regions in UTC-3.
UTC-9.5, UTC-4.5, UTC+3.5, UTC+5.75, and UTC+13 are all valid time zones and actively in use.
Once you get that sorted out then you can start to consider daylight savings time.

No, you will have to write one. Since the latitude and longitude points are well known, and timezones are also well known (though change periodically), all you have to do is map where the lat/long boxes are in given timezones, and calculate if your current position is in which one of those boxes. Once you know which box you're in, you'll have enough info to figure out what your time is.

This is not a trivial problem -- but it's not one without a solution. Services like Geonames and WeatherBug are very restrictive and/or costly so don't start developing something before you thoroughly understand their terms of service.
Here are the steps that I followed for my Appcelerator-based iPhone app:
Locate a list of coordinates that describe all timezones as polygons and read them into a SQLite table.
Make a best guess of which timezone the user is in (or is seeking), based on the longitude. This will be several zones.
Pull the polygons of each of the best-guess timezones from the database and run each one through a find-point-in-polygon algorithm. The one that returns true is the correct timezone.
If you a not concerned about Daylight Saving Time, you're done, otherwise, you have a mess to deal with. The landscape of DST is completely illogical and changes frequently. The best I could do was to Google "Daylight saving time rules" (start looking here: Sources for Time Zone and Daylight Saving Time Data) and be prepared to do a lot of work setting up list that you can use for the calculation. Mine still does not work perfectly after a lot of tweaking.

Use this data dump and import it into your program. Then locate the country in which your lat/long exists and it's time zone. You can then calculate what time it is at a specific lat/lon.
Geonames

I've written a small Java class to do this, with the data embedded in the code. It could be easily translated to ObjectiveC. The database is embedded in the code itself. It's accurate to 22km.
https://sites.google.com/a/edval.biz/www/mapping-lat-lng-s-to-timezones

Related

How To Get Timezone Of Date In Swift

I only want to get the current date object's timezone. The Date class in Swift does not have a way to do so. I have seen ways to convert from one timezone to another. But no way to do so extracting the timezone from a date object.
Why is that?
Is there a way to do so? Thoughts on how? Thanks
Dates don’t have time zones. They’re simply a point in time.
E.g., the moment in which Neil Armstrong stepped foot on the moon. You could describe that moment in UTC, or EST, or any other TZ (or even in other calendar systems), but they’re all referring to the same moment. That would be modelled by a singular date object.
By another analogy, an object has a width, but it doesn't know its unit. Its width can be measured in centimetres, inches, plank lengths or light years. These are all abstractions we put on top of the concept of distance, and they all describe the same thing.
Internally, they’re just a Double that counts the number of secs since the reference date. Clearly, there's no timezone there.
Any time zones you see relating to dates are just an interpretive layer on top of that (e.g. print will call .description, which will format it to your local tz for your convenience.).

iCalendar durations where the duration's date portion ends inside a DST discontinuity

RFC 5545 and other standards like JSCalendar define a P1DT12H duration as one nominal day plus 12 exact hours. Normally this will be 36 real-world ("exact" or "accurate") hours, but:
If a Spring DST transition happens during the "one nominal day" part of that duration, then the accurate duration will be only 35 hours.
If a Fall DST transition happens during the "one nominal day" part, then the accurate duration will be 37 hours.
But what if the starting date/time is exactly one nominal day before a discontinuous period? For example, a P1DT12H duration added to 2020-03-07T02:30 in America/Los_Angeles where DST starts at 2020-03-08T02:00. In that case, what should be the calculated local time at the end of that duration?
Is it 2020-03-08T14:30? 2020-03-08T13:30? 2020-03-08T15:30? Something else? Also: why?
The problem is that the naive way of calculating the exact duration would be to add the date portion of the duration using nominal units, then convert that intermediate result to UTC and add the time portion of the duration using exact time. But that intermediate result is an invalid nominal time that's skipped, then the local time of that intermediate value is 2020-03-08T03:30 (3:30AM, not 2:30AM) because RFC 5545 says:
If the local time described does not occur (when changing from standard to daylight time), the DATE-TIME value is interpreted using the UTC offset before the gap in local times.
So using that interpretation of the spec, the final result after adding the 12-exact-hour time portion should be 2020-03-08T15:30 or 3:30PM.
Is this the "correct" answer according to RFC 5455? If not, what should be the answer and why?
Or is this an ambiguity in the standard and there's no objectively correct answer?
I was hoping someone else would answer. Here is my understanding:
Two concepts here:
Either one has the DTEND and is calculating the DURATION, which as you have established, will vary if there is daylight saving change during the event, OR
one has the duration and is calculating the DTEND. It is best to do that in UTC for safety sake.
RE your question:
But what if the starting date/time is exactly one nominal day before a discontinuous period? In that case, what should be the calculated local time at the end of that duration?
For calculating DTEND, nominal day at same time takes us to invalid time. If one uses UTC to calc that nominal day, one gets 3.30 am. The spec says:
In the case of discontinuities in the time scale, such as the change
from standard time to daylight time and back, the computation of the
exact duration requires the subtraction or addition of the change of
duration of the discontinuity.
I understand this to mean yes, when working out the CALCULATED duration (ie where you have DTSTART and DTEND) will vary depending in the events point in the calendar, as you have noted.
RE your question
But that intermediate result is an invalid nominal time that's skipped, then the local time of that intermediate value is 2020-03-08T03:30 (3:30AM, not 2:30AM...."
Yes, however in calculating further I think you went wrong adding the 12H to the local time. Spec says use the earlier UTC offset, which I take to mean use that to get UTC time, use UTC for the calcs, then convert back.
If the local time described does not occur (when changing from
standard to daylight time), the DATE-TIME value is interpreted using
the UTC offset before the gap in local times.
Note this is the UTC offset. So one nominal day takes us to 2.30am which does not 'exist' in LA on 8 March, so we use the UTC offset before the time gap. -8 hours which gives us UTC=10h30.
Plus 12H gives us UTC 22H30.
If we stay with the -8 offset for calculation purposes, we get local time 14:30.
*It is not 100% spelled out in the specification that this is it. More worked examples to confirm would be good.
Advice I have seen elsewhere is to store times in UTC time, do the calcs in UTC time, then for display, calculate local time.*
RE:
Is it 2020-03-08T14:30?
Is this the "correct" answer according to RFC 5455? If not, what should be the answer and why?
I understand it to be 14H30. I cross checked using PHP, with calcs in LosAngeles and in UTC time before DST & during DST, using both datetime->add https://www.php.net/manual/en/datetime.add.php and https://www.php.net/manual/en/datetime.modify.php and consistently got that answer.
I think correct is 2020-03-08T14:30 because if one uses the UTC offset as specified and calcs in UTC, that is what one gets.
PHP Workings
add a nominal day P01D
Before DST:
2020-03-06T02:30:00-08:00
2020-03-07T02:30:00-08:00 with modify
2020-03-07T02:30:00-08:00 add date interval
Over DST:
2020-03-07T02:30:00-08:00
2020-03-08T03:30:00-07:00 with modify
2020-03-08T03:30:00-07:00 add date interval
add a nominal day plus 12 H ie: P01DT12H
Before DST:
2020-03-06T02:30:00-08:00
2020-03-07T14:30:00-08:00 add date interval
Over DST:
2020-03-07T02:30:00-08:00
2020-03-08T14:30:00-07:00 with modify
2020-03-08T14:30:00-07:00 add date interval
For checking offset: https://www.timeanddate.com/worldclock/meetingtime.html?day=8&month=3&year=2020&p1=137&iv=0

pyephem - does the right ascension calculation for the sun account for the Equation of Time

I am looking to calculate the highest precision lat lon for the subsolar point, in a particular datetime moment, as is reasonably possible using pyephem, with the help of some other library(s) if they are needed.
Relevant context:
Anyone who has used pyephem, already knows that for certain calculations it requires certain setup values before computing body positions, those values including the datetime (epoch of the observation), the location of the observer, and of course, the body being investigated. Solutions for the subsolar point through the use of pyephem, that I have found online, show the time in utc as the time needed for the pyephem setup.
Remembering way back to my first exposure to astronomy, and to celestial navigation, utc is a variant of a mean day, compared to an actual solar day, where an actual solar day's duration throughout the year varies due to several factors of the nature of the earth's orbit. Because the length of an actual solar day varies throughout the year, for certain types of astronomical calculations, this requires the Equation of Time to more precisely map the actual solar day measurements to a mean and fixed 24 hour day system such as utc. Before the advent of sufficiently accurate 'pendulum movement' clock mechanisms, and now crystal controlled clock mechanisms, going back to when sundials were the accurate timepiece, the more sophisticated sundials included markings to apply a yearly approximation of this important Equation of Time, soon after it had been observed and definitively documented. Therefore, relevant to my question, since utc is a variant of mean day, and not the true solar day, but normalized to 24 hours exactly, there is this question now of how or if pyephem incorporates the Equation of Time in its right ascension solutions for the sun. At present, I imagine the EoT is required for accuracy, as I try to visualize the sun's position against the background of stars, as seen from the earth, as the earth revolves around the sun, with historically observed variations that are made available and useful and essential with the Equation of Time.
Summary then of my question:
If it is not necessary to explicitly enter an EoT value in pyephem, because it is not relevant for computing the most accurate subsolar point, please explain why. If it is relevant, as I presently think it is, please tell me if pyephem, in its right acension calculation of the sun (and other bodies), as a body, does in fact, apply the Equation of Time as appropriate. Does it do so transparently? Is there a way to input an explicit value for it, if such is known, an EoT value that might be more accurate or more up to date compared to what pyephem is using transparently?
Some initial research results that formed the question:
Upon doing a search through various search engines, I found several posts in topical forums that give what seems a very simple answer for finding the subsolar point. Finding the lattitude apears to be the less complicated part of the solution, being simply the computed declination. Finding the longitude is where the question arose in my thinking, and now I wonder if it is applicable for the declination as well, since using the properly precise time is essential for the most precise result of both declination(lat) and longitude of the subsolar point. I always applied the EoT from the Nautical Almanac, back when I was involved with celestial navigation.
Two links, specific to pyephem, present the same approach to the subsolar point solution. When the question(s) was first asked, Brandon Rhodes quickly presented the single line formula using pyephem's computing of the sun's right ascension. His was specifically the code for the longitude calculation in a more theoretical tone, without all the pyephem contextual details. Liam Kennedy presented a more complete context of python code, showing those additional pyephem details, so that one could 'copy and paste' the entire block of code, (needing only to add the import ephem and import datetime), and modify it as appropriate, which I also found to be a useful review. The code is from these links...
Computing sub-solar point
Confusion with using dec/ra to compute sub-lunar location
subsolar point:
Brandon's code
lon = body.ra - greenwich.sidereral_time()
Liam's code
sunLon = math.degrees(sun.ra - greenwich.sidereal_time() )
Nowhere in these two posts is there a mention of the Equation of Time, and yet a variant of mean day is being used as an input value here
greenwich.date = datetime.utcnow()
utc as a variant of mean day is EoT unaware, by its construction definition as a mean day, which then normally makes it a requirement to adjust it with the EoT for certain astronomical usefulness.
To further clarify this requirement, there are many navigation and astronomical references that go into considerable detail discussing it. But I will stick to refering to some forum posts such as the following:
https://forum.cosmoquest.org/showthread.php?55871-Finding-the-subsolar-point
specifically the post by grant hutchison 2007-mar-20, 04:33 pm
You can use the NOAA Solar Position Calculator, but it's kind of convoluted.
http://www.srrb.noaa.gov/highlights/sunrise/azel.html
note: the NOAA calculator, as of this writing, 2019-12-19, does have an input box where one is to enter the Equation of Time in minutes. That page has a link to a more updated calculator.
https://www.esrl.noaa.gov/gmd/grad/solcalc/
The more up to date page also calculates and displays the Equation of Time, clarifying its relevance. Now, continuing to quote Grant's post...
First, use the calculator to derive the Equation of Time and Solar Declination for the date and time you're interested in, at the location zero latitude and zero longitude, with no UTC offset.
The 2007 March equinox is at 21 March 00:08:30 UTC. Type that time and date into the calculator and, sure enough, you find the solar declination is zero: the sun is over the equator at that moment. For any other date and time, the solar declination will convert directly to the latitude of the subsolar point.
Now we need the longitude. First, work out the true solar time using the Equation of Time figure: it's -7.42 minutes in this case. That's the offset between the position of the mean sun and the real sun. Adding that figure to our UTC time tells us that the real sun is just 1.03 minutes past midnight (8.5-7.42) at the time of interest. Divide that figure by 60*24 (to get the fraction of a day) and multiply by 360 (to get degrees): that gives us 0.2575 degrees past midnight. So the sun will be on the noon meridian at 180-0.2575 degrees east = 179.7425 E. That's our longitude.
Combine the two, and the subsolar point is 0.0000N 179.7425E.
We can check that I haven't mixed my pluses and minuses by typing the derived coordinates of the subsolar point into the solar calculator (Lat 00:00:00, Lon -179:44:33), keeping the UTC offset at zero and the date and time at your time of interest, 21 March 00:08:30. That comes up with an Azimuth of zero and an Altitude of 89.98 degrees, confirming that we have the sun crossing the meridian within a couple of hundredths of a degree of directly overhead. Phew. It works, but it's a bit of a pain. Maybe someone can offer a calculator that will do more of the work for you.
And a followup post of his dated about an hour and a half later...
Some notes to the above, FWIW:
The difference between Dynamical Time and UTC this year is 65 seconds, so working from the Dynamical Time of the solstice we get the UTC time (to the nearest second) to be 00:07:25 UTC, which fits with G O R T's nearest-minute value, above.
The reason G O R T and I come up with a different subsolar longitude for the same time (00:07:00 UTC) is because of that pesky -7.42 minutes in the equation of time: although that time is after midnight at Greenwich, the real sun is still 42 seconds short of crossing the midnight line. That shifts the calculated subsolar point from the eastern to the western hemisphere. 7.42 minutes is equivalent to 1.855 degrees, which is exactly the difference between my calculated longitude of 179:53:42W and G O R T's of 178:15:00E.
My question is therefore based on this research, and based on my past experience with celestial navigation. I imagine that as vital as the Equation of Time might be to the problem, it would be incorporated into pyephem's calculation(s), since a mean day is input into pyephem's API. Seeing nowhere in these snippet solution postings where EoT is to be specified in the pyephem API, my assumption is that it would be internally and transparently implemented? I am not comfortable with this assumption, and so I have posted this question. Clarification would benefit the confidence of users, particularly newbies such as myself.
Update 12-20-2019:
I suspect the answer is yes, pyephem accounts for EoT, but it does not call it that? The way ephem, libastro, takes into account some other effect or relationship probably answers my question(s). I am reviewing:
https://rhodesmill.org/pyephem/radec
Needing to read it very slowly, while drawing some pictures, and waiting for an astronomy book so I can catch up on a very much misplaced education on this matter. I'm thinking that perhaps the term Equation of Time only has meaning in a narrow context of reconciling the solar day to a mean day metric, as experienced on earth, while pyephem solves in a broader context and uses more broadly applicable terminology, of which I need to be re-educated, which includes such resulting effects as the Equation of Time? Or I am only displaying my ignorance? Until I can more competently write my own answer, please do contribute any helpful comments or answers that can steer my study.
I think that your question, stated more briefly, is: does the libastro library that underlies PyEphem assume that the Earth’s orbit is a circle along which the Earth travels at a uniform rate? Because if it assumes a circular orbit and uniform rate for the Earth, then a correction ­— the Equation of Time — would need to appear for the fact that the Earth in fact varies its speed along its orbit.
I suggest that you can answer this question for yourself experimentally. If PyEphem assumes uniform circular motion for the Earth, then the number of degrees traveled by the Sun each day will be the same. Try looping over a long series of days. For the same time each day, ask the Sun for its right ascension and declination, and then use separation() to check the angle traveled between those points.
If the angle traveled by the Sun is the same each day, then PyEphem is modeling the Sun’s motion very poorly and you will need to apply an Equation of Time correction to get its true position.
But if the daily angle is varying — small in July, large in January — then PyEphem must be modeling the Earth’s motion more accurately. If you dig into the source code, you will find that its model is called the VSOP87 model of predicting where the Earth and Sun are. Your own experiments should show how the model behaves as the Sun travels the sky through the year.

Android app dev: Finding the best way to synchronize the timestamps of two sensors

There's already a good answer on the technical details and constraints of timing the gyro measurement:
Movesense, timestamp source of imu data, and timing issues in general
However, I would like to ask more practical question from the Android app developer perspective working with two sensors and requirement for high accuracy with Gyro measurement timing.
What would be the most accurate way to synchronize/consolidate the timestamps from two sensors and put the measurements on the same time axis?
The sensor SW version 1.7 introduced Time/Detailed API to check the internal time stamp and the UTC time set on the sensor device. This is how I imagined it would play out with two sensors:
Before subscribing anything, set the UTC time (microseconds) on the sensor1 and sensor2 based on Android device time (PUT /Time)
Get the difference of the "Time since sensor turned on" (in milliseconds) and "UTC time set on sensor" (in microseconds) (on sensor1 and sensor2) (GET /Time/Detailed).
Calculate the difference of these two timestamps (in milliseconds)(for both sensors).
Get the gyro values from the sensor with the internal timestamp. Add the calculated value from step 3 to the internal timestamp to get the correct/global UTC time value.
Is this procedure correct?
Is there a more efficient or accurate way to do this? E.g. the GATT service to set the time was mentioned in the linked post as the fastest way. Anything else?
How about the possible drift in the sensor time for gyro? Are there any tricks to limit the impact of the drift afterwards? Would it make sense to get the /Time/Detailed info during longer measurements and check if the internal clock has drifted/changed compared to the UTC time?
Thanks!
Very good guestion!
Looking at the accuracy of the crystals (+- 20 ppm) it means that typical drift between sensors should be no more than 40 ppm. That translates to about 0.14 seconds over an hour. for longer measurements and or better accuracy, a better synchronization is needed.
Luckily the clock drift should stay relatively constant unless the temperature of the sensor is changing rapidly. Therefore it should be enough to compare the mobile phone clock and each sensor UTC at the beginning and end of the measurement. Any drift of each of sensors should be visible and the timestamps easily compensated.
If there is need to even more accurate timestamps, taking regular samples of /Time/Detailed from each sensor and comparing it to the phone clock should provide a way to estimate possible sensor clock drift.
Full Disclosure: I work for the Movesense team

Is there a built in mechanism for Miles/KM interchangeability for iPhone?

I am currently working on a map-based iPhone application and wish to display some information to the user. For my application, it makes sense to have a setting of some sort where the user can choose Miles or Kilometers. Is there a built in mechanism (maybe similar to string localization) for doing this kind of value switching so that I can avoid an if-block around each time I want to display something to the user?
Take a look at NSLocale. You should be able to get the current locale using [NSLocale currentLocale]. Then call [theLocale objectForKey: NSLocaleMeasurementSystem] and look at the results which should tell you if the users locale uses the metric system. The docs for NSLocale have a constants section which list all of the values that can be passed to the locale.
Using this you would make your own function that could be used in your program to return your distance in a locale specific way.
Based on my quick test NSLocaleUsesMetricSystem may not work for finding if the users' region uses kilometers or miles.
In the U.K, the distances are in Miles and speed in Miles per hour but NSLocaleUsesMetricSystem returns 1.
In the U.S, NSLocaleUsesMetricSystem returns 0 which is correct (distance is in Miles and speed in Miles per hour).
In India, NSLocaleUsesMetricSystemreturns 1 which is correct again (distance is in Kilometers and spee in kph).