I want to show the timezone code (such as BST or GMT) based on the user's locale. However, in each browser it is positioned in different places from new Date().toLocaleString() and on some browsers (such as Opera) it is not available at all.
It looks like the solution would be to get a database or structure of timezone codes against timezone offset but there can be multiple matches (e.g. BST == GMT) and I can't even find such a list.
Does this mean it can't be done?
You have to manually define the timezone differences in your code. It is complicated because GMT time is different than UTC (Zulu) time. GMT includes a change for daylight savings time, while UTC has no daylight savings and is otherwise the same timezone representation.
Additional confusion is that not all political zones define their timezones to vary by an example number of hours. India is UTC + 5.5 hours and Afghanistan UTC + 4.5 hours. Notice that is UTC and not GMT as the base as those countries do not observe daylight savings. Some small island nations in the southwest Pacific can vary on the quarter hour.
Then some political timezone definitions have internal differentiation. Arizona is typically considered to be in the US Pacific timezone, GMT - 8 hours, except that it does not observe daylight savings, so half the year it is in US Mountain timezone as Arizona is really UTC - 8.
With all that confusion there are hundreds of definitions for timezones, and some of those change as political boundaries change. I just say screw it and use either the user's clock time or adjust to UTC time by dynamically adjusting a constant in your JavaScript from the server to reflect a known value that represents UTC time when the user requested the page.
Related
I had an issue where dates were out by one day when displaying on an asp.net web form. These dates are only used for display so I can pass them as strings to resolved the issue, but I'm curious about why I'm seeing this behaviour.
I'm in Ireland, and while Ireland is more or less in line with GMT, we use IST (Irish Standard Time) during summer instead of DST and then revert to GMT for Winter. This has the same effect as being on GMT, but "officially" is slightly different.
As we're not on GMT, in the past, IST and DST didn't always line up.
For example, in 1958, IST started in the 20th April and ended on the 5th October whereas, DST started on the 27th of April and ended on 26th of October.
So if a date between the 5th and 26th of October 1958 is passed to JS, JS will display it as the previous day.
I wrote this this code to try and understand what's going on:
DateTime date = new DateTime(1958, 10, 4);
while (date <= new DateTime(1958, 10, 30))
{
Console.WriteLine($"normal : {date} | isDst? : {date.IsDaylightSavingTime()}");
Console.WriteLine($"universal: {date.ToUniversalTime()} | isDst? : {date.ToUniversalTime().IsDaylightSavingTime()}");
Console.WriteLine($"local : {date.ToLocalTime()} | isDst? : {date.ToLocalTime().IsDaylightSavingTime()}");
Console.WriteLine("-------------------------");
date = date.AddDays(1);
}
Which produced this output (truncated):
So I can see there are a number of days being mis identified as DST days, but it doesn't seem like that would cause this? If both .Net and JS though they were DST days, then surely the end result should be correct?
Additionally, why is there a 2 hour difference between the output of ToUniversalTime and ToLocalTime during DST?
Here's a screenshot of JS processing a few dates duirng this problematic window
You can see that JS (or chrome?) is aware that during the 5th to the 27th of that year, Ireland is no longer on GMT+1 (even though it still says it's IST) so why is the date passed from VB an incorrect date? I though they both got their datetime information from the same source i.e. the host pc?
You appear to be running .NET on Windows, in which case .NET is using the Windows time zone data for your local time zone.
The Windows time zone data does not have the full history of time zone changes from all time. Microsoft's policy only guarantees historical data is present for dates from 2010 forward, though some time zones have historical data before then.
Conversely, Chrome is using time zone data from ICU, which uses IANA time zone data. IANA time zones have historical data since at least 1970, though many time zones have historical data before then.
With specific regard to Ireland, IANA has Irish time zone data going back to 1880. Windows has no history for Ireland at all, so it assumes the current rule has always been in effect. In reality, the current rule has been in effect since Oct 1968, so any dates before then will only have accurate time zone information in the IANA data.
If you run the same .NET code you showed above on Linux or MacOS, you'll see that .NET will use IANA time zone data on those platforms and your results will match up for 1958. Or, if you pick a more recent date your results will match on Windows too.
In short - don't run these sorts of tests on old dates and expect to get the same fidelity that you'll get with modern dates.
You also asked:
Additionally, why is there a 2 hour difference between the output of ToUniversalTime and ToLocalTime during DST?
Your date variables are all DateTime where .Kind is DateTimeKind.Unspecified. The IsDaylightSavingTime method will treat such values as if they belonged to the local time zone, as if they actually had DateTimeKind.Local. The same is true for the ToUniversalTime method, however, the ToLocalTime method will assume that DateTime values with DateTimeKind.Unspecified kind are actually in terms of UTC - as if they were DateTimeKind.Utc. Thus, when DST is in effect, date.ToUniversalTime() shifts an hour backward, and date.ToLocalTime() shifts an hour forward.
You can avoid such ambiguities by using DateTimeOffset instead of DateTime.
I am investigating an issue involving the conversion of serialized UTC dates in to JavaScript date objects; I have read a few questions on this topic already but I am still unclear.
Firstly let me say that I am in the UK. If I take for example the UTC epoch 1473805800000, which is Tue, 13 Sep 2016 22:30:00 GMT, then use that value to create a JavaScript date:
var date = new Date(1473805800000);
console.log(date);
The console logs:
Tue Sep 13 2016 23:30:00 GMT+0100 (GMT Summer Time)
I.e. the browser has recognised that an extra hour needs to be added for DST.
My question is, if I were to run this same code again after the 30th October when the clocks have gone back, would I still get the same result of 23:30, or would it be 22:30 as if it were GMT? In other words, has the browser added an hour because the subject date is DST or because we are currently in DST?
I'm prevented from altering my work station's system clock by group policy, otherwise I would skip it forward in time and test this myself.
Javascript Date objects use a time value that is an offset in milliseconds since 1970-01-01T00:00:00Z. It is always UTC.
If the Date constructor is given a single number argument, it is treated as a UTC time value, so represents the same instant in time regardless of system time zone settings.
When you use console.log(date), the built–in toString method is called which generates an implementation dependent string, generally using the current time zone setting of the host system to create a convenient, human readable string.
The current daylight saving rules in the system are used to determine the offset to use for "local" time, so if the date changes from a time when daylight saving applies to one when it doesn't, the time zone offset will be similarly adjusted (note that daylight saving offsets aren't always 1 hour). It does not matter what the current system offset is, the one used is based on the setting for the date and time that the time value represents.
Also, Date objects are very simple, they're just a time value. The time zone offset comes from system settings, it's not a property of the Date itself.
So, given:
My question is, if I were to run this same code again after the 30th
October when the clocks have gone back, would I still get the same
result of 23:30, or would it be 22:30 as if it were GMT?
the answer is "yes", it will still be 23:30 since on 13 September BST applies. It doesn't matter when the code is run, only what the system offset setting is for that date.
In your case, the Date was created using epoch 1473805800000 and converted to your timezone GMT+0100. Epoch is always UTC time, therefore it was read as UTC and converted to your current timezone.
On September 13 2016, GMT+01 had summer time, therefore it was considered in the calculus.
In my case, I get the following, running the same code as yours:
Thu Sep 15 2016 14:13:14 GMT-0300 (E. South America Standard Time)
I already read a lot of post and a little confused with UTC, GMT and daylight saving time.
Anyone can explain about javascript Date() object with UTC, GMT and daylight saving time.
The main point I want to know is, when we work with date, we need to think or not about daylight saving time.
And the calculation of UTC,GMT and daylight saving time is same or not in different kind of programming languages.
UTC is a standard, GMT is a time zone. UTC uses the same offset as GMT, i.e. +00:00. They are essentially interchangeable when discussing offsets.
All javascript (ECMAScript) Date objects use a time value that is UTC milliseconds since 1970-01-01T00:00:00Z. When the Date constructor is called without any arguments, it gets the time and time zone offset from the host system and calculates the time value. Therefore, the accuracy of the generated date depends on the accuracy of those components.
When outputting date values using the UTC methods (e.g. getUTCHours, getUTCMinutes, etc.), the vaules are UTC (GMT). When not using those methods (e.g. getHours, getMinutes, etc.) the host system time zone offset is used with the time value to generate "local" values from the UTC time value.
Whether daylight saving is applied or not depends on the host system settings. Whatever the current rules are for the host system time zone changes for daylight saving are applied to all dates, regardless of the actual offset that date (e.g. if currently DST starts on the first Sunday in October then it will be assumed to have always started on the first Sunday in October).
Date object behaviour is described in ECMA-262 §20.3.2 and a bit more clearly (for some parts) in MDN Date.
I have a page which allows a user to view and edit times (with dates) stored in a database. The times are stored in the database in UTC and attached to a location with a different timezone. When the user views the times they are shown in the attached timezone and not necessarily the timezone of the browser. The user should then be able to edit a time and make and AJAX request. I need to be able to convert the inputted time from an arbitrary timezone to UTC in javascript, but the only conversion javascript seems to allow is from browser timezone to UTC. Passing an absolute offset in javascript is not going to work because the user should be able to edit times before or after daylight savings. This seems like it should be a problem that has been solved before... any pointers?
This is an extremely nasty problem. As long as the user is presented with all times in his/her own timezone (or in GMT), you would have no problem. But asking JS to provide accurate local Daylight Saving Time values for different locales is nasty stuff. The browser is aware of GMT and local time and (thanks to the OS) it also knows when DST kicks in locally. But without changing the user's system timezone information, JS has no way of telling when DST kicks in in another locale. The rules of when DST comes into effect not only differ from country to country, the date can change unexpectedly over time (remember when North American countries recently moved DST dates?). You can likely figure out the locale DST details on your server pretty easily and communicate that to the browser. But it's probably not practical to attempt it entirely in the browser. You could have a sort of DST_changeover_by_locale array in your application, but you'd need to update it periodically.
[EDIT] There seems to be some confusion about how the JS Date object works in regards to timezones. Here are some useful points:
Timezone offsets
// Create a time in winter (Standard time)
dt = new Date('Jan 1 2010 12:00:00 GMT-0000');
alert(dt.getTimezoneOffset());
// In Japan right now, users would see "-540"
// In New York right now, users would see "300"
// Create a time in summer (DST)
dt = new Date('Jul 1 2010 12:00:00 GMT-0000');
alert(dt.getTimezoneOffset());
// In Japan right now, users would see "-540"
// In New York right now, users would see "240"
// NOTE: Japan has no DST while NY does
Parsing dates to local time
// The following will all return the same time string, which will be
// the time according to the user's OS time settings and locale
alert((new Date('Jun 25 2010 13:30:00 GMT-0230'))); // Newfoundland time
alert((new Date('Jun 25 2010 13:00:00 GMT-0300'))); // Atlantic time
alert((new Date('Jun 25 2010 12:00:00 GMT-0400'))); // Eastern time
alert((new Date('Jun 25 2010 11:00:00 GMT-0500'))); // Central time
alert((new Date('Jun 25 2010 10:00:00 GMT-0600'))); // Mountain time
alert((new Date('Jun 25 2010 9:00:00 GMT-0700'))); // Pacific time
Timestamps
// If you don't want to work with strings, use numbers instead.
// These return the JS timestamp for the same values above.
// The value is a *delta*, so it is unaffected by DST.
alert((new Date('Jun 25 2010 13:30:00 GMT-0230')).getTime()); // Newfoundland time
alert((new Date('Jun 25 2010 13:00:00 GMT-0300')).getTime()); // Atlantic time
alert((new Date('Jun 25 2010 12:00:00 GMT-0400')).getTime()); // Eastern time
alert((new Date('Jun 25 2010 11:00:00 GMT-0500')).getTime()); // Central time
alert((new Date('Jun 25 2010 10:00:00 GMT-0600')).getTime()); // Mountain time
alert((new Date('Jun 25 2010 9:00:00 GMT-0700')).getTime()); // Pacific time
I don't think you have to do the timezone conversion on the browser. You can just display an "opaque" date time on the client, let them modify it, then post to the server to convert it to UTC, as required.
Not sure if I should put this as an answer but I cannot leave a comment as I did not associate that temporary account with this ID...
Unfortunately it looks like doing the time zone calculation server side is the only clean way to do this, however I'm still hopeful someone might have another solution. By convention in this code all times should be sent in UTC and I'd like to avoid breaking that convention (and making it confusing in other places we might use the service call) if possible.
I have a calendar built in JavaScript that compares dates with PHP. The JavaScript date object is set using PHP, but, when I compare future dates, they appear to be out of sync.
PHP is set to GMT and JavaScript is set to UTC; how do these standards differ, and could this be causing the problem?
From Coordinated Universal Time on Wikipedia:
Coordinated Universal Time (UTC) is a time standard based on International Atomic Time (TAI) with leap seconds added at irregular intervals to compensate for the Earth's slowing rotation.
From Greenwich Mean Time on Wikipedia:
UTC is an atomic time scale which only approximates GMT with a tolerance of 0.9 second
One is measured from the sun and another from an atomic clock.
For your purposes, they are the same.
For computers, GMT is UTC+0 - so they are the equivalent.
If you strictly go by the definition of what UTC and GMT are, there is no real practical difference as others have pointed out.
However one needs to be careful as there are certain cases where (possibly legacy) terminology is used such as in the Microsoft Timezone index values
The difference is that in that context, what is referred to as the "GMT timezone" (code 55) is, in reality, the "GMT locale" which is the locale used by Dublin, Edinburgh, Lisbon, London (all of which observe daylight savings time) which is differentiated from Greenwich Standard Time (code 5A) which is used by Monrovia and Reykjavik both of which do not observe daylight savings time.
The practical difference is that if a system is set up to use UTC (code 80000050 under the semantics specified above) then it will not automatically switch to daylight savings time while if you set your time zone to GMT (code 55) then there's a good chance it automatically switches to BST during the summer without you noticing.