How do I get the utc offset from an address? - ruby-on-rails

I have a RoR application where I store locations using gmaps4rails. Based on the address of the location, I'd like to guess the UTC offset ("+00:00", "-05:00", ..).
Is it possible or I have to ask users (and trust them) to set the correct timezone offset?
By the way, I know that there are some places where the timezone offset may change during the year. In this case, I should use the zone name instead of the offset. Is there a gem that helps to deal with these issues?
Thank you,

Geolocate the address to lat/lon coordinates using any number of web services for this. Then see the options in How to get a time zone from a location using latitude and longitude coordinates? The Ruby gem that Yevgeniy mentioned is listed there, along with other options.
Don't try to get an offset for the location - it could change periodically for DST. Get the time zone instead, such as Asia/Singapore or America/New_York. Then use that to determine the offset for a particular point in time.
See "Time Zone != Offset" in the timezone tag wiki.

Even if you get the solution, it is better to ask them from user. If user in the US wants to see his/her datetime according to timezone in Singapore (because that is his/her homeown), he/she should be shown it like that.

Related

Looking up timezone from region / coordinates

I would like to look up a timezone based on an ISO region code or coordinates.
I have a collection of data points with coordinates, county and region codes, eg:
33.942501,-118.407997,"US","US-CA"
I want to find the IANA timezone identifier, eg. America/Los_Angeles, based on the above info.
Is it possible to do that with NodaTime? I cannot see a way to look up DateTimeZone or timezone identifier from a region code or location.
The GeoTimeZone NuGet package can provide a lookup by lat/long to IANA ID, and then you can use DateTimeZoneProviders.Tzdb[id] to get the DateTimeZone from that. See the project home page for more details.
Within Noda Time itself, you can use TzdbDateTimeZoneSource.Default (or one that you've loaded) and then the ZoneLocations or Zone1970Locations properties to find zones for specific ISO-3166 countries... but they doesn't go below the "country" level (although they do have exemplar lat/long values). They're based on zone.tab and zone1970.tab - so any information not in that file isn't present in Noda Time either.
It sounds like GeoTimeZone is probably your best option here.

Querying by timezone vs location

Moment-timezone time has method momnet.tz that takes two params:
particular datetime
timezone name
It returns time shift (to UTC) that was at given timezone in given datetime. Ok.
The question that bothers me:
do all the locations that currently belong to a particular timezone were in the past belonging to that zone also?
so isn't it possible that if two locations even currently belonging to a certain timezone, in the past (even after 1970) had actually different timezones (shifts to UTC).
Is it possible in principle to query tz-db for specific some kind of location, not a timezone name.
Would be grateful if someone could eliminate my doubts.
Moment-timezone uses the data from the IANA time zone database (aka the TZDB, zoneinfo, or the Olson database). Most of your questions are addressed by that data, rather than by moment-timezone itself. You'll find that other implementations (for other languages, platforms, etc.) have similar behaviors.
There is a great deal of information about how the tzdb works in the theory file in the tzdb itself, and on Wikipedia, but I'll see if I can address your specific questions:
do all the locations that currently belong to a particular timezone were in the past belonging to that zone also?
The TZDB assigns time zones based on cities (because they are less likely to changes over time than other regional boundaries). Generally, one city within a given region whose clocks have been aligned since 1970 will be chosen to represent the time in that region.
When another part of that region changes their clocks differently than the rest of the region, a new time zone is created and a new city is chosen within that region to represent the zone. We call this a "zone split". Time before the split in both zones will match (except the LMT entry), and time at the split and forward will deviate. It doesn't matter if at some point in the future the time in these regions aligns again. There are now two zones and there will continue to be - because they deviated at some point in the past.
so isn't it possible that if two locations even currently belonging to a certain timezone, in the past (even after 1970) had actually different timezones (shifts to UTC).
If there is a distinct history of timekeeping in the region, then there will be two different time zone entries. So when you say "locations", if you mean two different cities with their own time zone names in the TZDB, then by definition they don't belong to the same time zone. For example, Europe/Moscow and Europe/Volgograd are both currently in UTC+3 year-round without DST. However at the start of 1992, Moscow was UTC+3 while Volgograd was UTC+4. Their histories before then deviate even further.
On the other hand, if you are talking about a location that is not specifically referenced in the TZDB, then there is a presumption of alignment. For example, Seattle is in the US Pacific time zone, all of which is represented by America/Los_Angeles. Because there is not a unique America/Seattle, the data is representing that Seattle does not have a unique time zone history than Los Angeles.
That said - there have been a few very minor edge cases that have come up in the past where a small town that is on the boundary line between two time zones has to chose between which zone to observe. It has also happened that a small town distinctly on one side of the boundary has chosen to unofficially follow the time zone in a neighboring larger city on the other side of a boundary. These changes are sometimes mentioned on the tzdb discussion list, but are rarely recorded in the data as a distinct zone.
With these edge cases, keep in mind that the TZDB only tracks cities - not regional boundaries that may divide cities or towns. For that, you'd have to go different data source. The best one I know of is Evan Siroky's timezone-boundary-builder project.
Is it possible in principle to query tz-db for specific some kind of location, not a timezone name.
You'll have to be more specific about what you mean by "location". If you mean a latitude/longitude coordinates - then the timezone-boundary-builder data, and the projects that use them, are the route to go. They will help you resolve a tzdb identifier, which you can then use with moment-timezone or other libraries.

What is the opposite of an AoE expiry?

I'm speccing an application that displays time periods to the user. The goal is to present periods in a simple view (no time, no timezones) and detailed view (date and time, with timezone data). The simple view should be unambiguous, in other words the user can glance at it and their assumptions about what they see are correct (they are valid in the local timezone).
For the end of the global period, displaying the date in the AoE timezone [1] will solve this problem. For example, a submission deadline might display as 2018-04-03 (actually 2018-04-03 23:59:59 AoE). This means submissions are accepted as long as it is April 3 somewhere on the planet.
But I also want to indicate that start of a global period. For example, if submissions open on April 2 2018 00:01, they are accepted as soon as it is April 2 somewhere on the planet. (This would currently be at UTC+14, matching the Line Islands.)
I can't see a way to use AoE to derive a global start time. Is there an equivalent to AoE (a standardized semantic timezone) that tracks the global start time?
Notes:
Hardcoding UTC-12 and UTC+14 is the simple answer for the modern day. But I'm looking for semantic timezones that would be updated if the values changed (and not reference non-existent historical datetimes).
I thought I'd seen Etc/AoE in the tz database but this is not the case.
References:
AoE
UTC-12:00
UTC+14:00
[1] The Anywhere on Earth (AoE) timezone represents the moment a datetime expires "anywhere on Earth". It currently matches time at Howland Island (UTC-12). If a UTC-13 timezone were invented, it would be updated to track that.
As far as I could understand, AoE is not a timezone as defined by IANA (AFAIK, a list of all offsets from some geographic region during history).
It's more like a "concept", an idea of a specific date being valid in any place on earth. As you said, this notion of "being valid" will change if more timezones are created or removed.
I don't even know if date/time API's can properly handle AoE automatically - maybe I should study more. But my conclusion is that the only way to achieve your goal is to check manually:
you could check all available timezones and see if the date is valid there, comparing to the current date/time at that zone
you could configure the UTC+14 as the offset to be compared, and make some scheduled job (daily/weekly/every-time-IANA-publishes-a-new-version?) to check all zones and set the correct one (with the biggest offset?). You must also take care if this zone has Daylight Saving changes, because the offset will change as well (and what to do with overlaps, when clocks shift 1 hour back and a local time may exist twice?)

Is there a site that allows timezone conversion on a given date easily by URL

I am looking for a timezone converter site which accepts arguments of a time, city, and date on the command line and opens up a page showing the equivalent time/date in my current locale. (Needing to specify my current locale would be acceptable.) I do need it to be a little smart about searching for the cities - I don't want to have to enter an exact timezone syntax but rather a substring which results in a unique search.
Unfortunately spending money is not an option - I've got to find a free service.
More detail:
I use DTRT extensively and would love to be able to do an instant time zone conversion straight from my address bar.
I would like to type this:
3pm Dallas 2015-03-20
and get a page telling me what time that will be in my current location (and perhaps in certain other locations I would set up).
The DTRT is designed to simply convert the query string in the URL to a different URL so I'm looking for a site that might accept GET parameters like this in the URL. I've done quite a bit of googling, but so far everything I have found either (1) requires me to go through their interface to convert the cities to codes or (2) doesn't do GET parameters at all.
Any time zone converters you know that do this? The closest I've found is this and it uses those codes...
Here is another option which works just by naming the city in the URL, but it has no capability of doing it for another date. When I am setting up meetings when one city changes to DST one week and another city 3 weeks later I absolutely have to have the date capability.
Have you tried wolfram alpha?
https://www.wolframalpha.com/input/?i=3pm+Dallas+2015-03-20

Autodetect timezone in Rails given UTC offset and DST

I basically want to autodetect a user's timezone using Rails. I can use this JS code at the user's browser (http://www.onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/) to send a form with the UTC offset and the fact that the time zone observes DST during summer or not, in the user's time zone.
Once I have that info in the server, I want to select the matching time zone. In Rails, I can get a list of time zones with ActiveSupport::TimeZone.all. Also, I can filter zones by utf offset thanks to the utc_offset method. However, I don't know how to filter the timezones that do/don't observe DST.
E.g. suppose a user lives in Amsterdam. Filtering by UTC offset will return Berlin, Belgrado, Madrid, etc timezones, as well as West Central Africa. All of them, but West Central Africa, would be appropriate timezones for a user in Amsterdam (as they provide the same time/date), but I need to filter West Central Africa, which does not perform DST in summer.
How can I do this in Rails? Also, are any of my assumptions wrong?
I thought maybe http://geokit.rubyforge.org/ would be helpful. You could get the coordinates of user location (or city/ country). The only thing you would have to do is guess the time zone based on city/country.

Resources