Display time zone code for users - javascript

Have a site for training webex events. Our company is located in several different timezones. In the past everything has been converted to Pacific time (where we are headquartered). Trying to focus more on user experience and make things more local and less about HQ.
So all the times are shown in local time, but this is now confusing users because they don't expect it. I'd like to add three letter initials (PST, CMT, EST, HAST or HST, etc.)
As I'm looking into this I'm keep getting referred back to moment timezone. We are already using moment for other date/time stuff, so that would be awesome.
But all the timezone examples are like this:
moment.tz([2012, 0], 'America/New_York').format('z'); // EST
Basically it seems like you already need to know what timezone the user is in. If I already knew what timezone they were in I wouldn't need moment to tell me. Also the documentation says:
...By default, moment objects are created in the local time zone....
I'm located in Portland, Oregon, javascript new Date() shows (PST) (in Chrome at least), but moment.tz().zoneAbbr() is UTC, so clearly not my local time zone.
I found this thread that recommends using jsTimezoneDetect.
moment.tz(new Date(), jstz.determine().name()).format('z')
I understand why this is a complex thing given locations around the world and different daylight savings schemes. But I have to wonder -- am I missing something? Is there some easier way to do this?

Related

How do I get the result of javascript new Date().getTimezoneOffset() transferred to C# backend?

See the title: for the solution I'm working on, I need to get the current timezone offset (from the client, running javascript/jQuery) and use it in backend C# code.
The question is rather similar to the one asked here, but there are a few differences - the main one being that I am pretty sure that the time on the client computer won't be tampered with. So new Date().getTimezoneOffset() will do just fine.
I cannot read the value upon submitting a form since the user is not working in a form: after the user has logged in, among the items that are visible on the screen is a table with data entered by the user or by other users. This data contains UTC datetimes that have to be adjusted according to the client's timezone. C# code is responsible for retrieving and formatting the data - hence my question.
What would suffice, is storing the value somewhere so that C# can read it when necessary. But I don't think that can be done as well. What would be the approach here?
Thanks in advance!
Your suggested approach is flawed in that the current offset from the client's browser is only going to apply to the current date and time. In reality, time zone offsets change over time within a given time zone. You cannot just take a singular offset from one point in time and expect to use it to convert other dates and times to the same time zone. Instead, you need to use the string that identifies the time zone, not an offset from that zone.
As an example, consider the Eastern time zone in the United States. For part of the year, it uses UTC-5, and we call it Eastern Standard Time (EST). In another other part of the year, it uses UTC-4, and we call it Eastern Daylight Time (EDT). This time zone is identified by either the IANA time zone ID "America/New_York", or the Windows time zone ID "Eastern Standard Time" (which covers the entire zone, both EST and EDT despite its wording).
So, break this problem apart into a few steps:
In JavaScript, identify the users's IANA time zone (America/New_York):
If you are targeting modern web browsers, you can call this function:
Intl.DateTimeFormat().resolvedOptions().timeZone
If you need to support older web browsers, you can use jsTimeZoneDetect, or moment.tz.guess() from Moment-Timezone.
Send that string to your web server through whatever mechinsm you like (form post, XHR, fetch, etc.)
In your .NET code, receive that string and use it to reference the time zone and do the conversion. You have two options:
You can use Noda Time, passing the IANA time zone ID to DateTimeZoneProviders.Tzdb as shown in the example on the home page.
You can use .NET's built-in TimeZoneInfo object. If you're running .NET Core on non-Windows systems (Linux, OSX, etc.) you can just pass the IANA time zone ID to TimeZoneInfo.FindSystemTimeZoneById. If you are on Windows, you'll need to first convert it to a Windows time zone ID ("Eastern Standard Time"). You can use TZConvert.GetTimeZoneInfo from my TimeZoneConverter library.
Once you have either a DateTimeZone from Noda Time, or a TimeZoneInfo object, you can use the methods on it to convert UTC values to local time values for that time zone. Each of these will apply the correct offset for the point in time being converted.
I'll also say, many applications simply ask the user to choose their time zone from a dropdown list and save it in a user profile. As long as you're storing a time zone identifier string and not just a numeric offset, this approach is perfectly acceptable to replace steps 1 and 2 above.

Print the time for a given location

Supposing I have
a date (i.e. an UTC timestamp),
a location (e.g. "Paris") that I may encode as I wish (and which isn't the one of the browser),
no permanent internet access
then what can I do if I want to format my date for this specific location, correctly dealing with daylight saving time when/if it occurs ? I'd prefer a standard based solution. I expect the solution to either include a reliable table of some sorts or to call some browser/computer magic.
Of course, as the offset is dependent of the moment, I can't just store the location as an offset.
Here are 2 points which ease the problem :
I won't deal with dates before 2010
if some country decides to change the rules regarding its timezone, it's acceptable for me to release a new code/library
Have a look at moment.js which support localization in a pretty nice way as well as time zones.
For the location issue, I would say you will have a really hard time solving that without an Internet connection. I would say the only way to solve it is to have your users enter a country (and maybe time zone) manually.

time zones: user preference vs client-side Javascript

In Javascript it's fairly straightforward to render and manipulate dates in the current user's local time zone using the methods of the Date object. For example, toLocaleString() for output and the 7-argument form of the Date constructor for input. So up until now I haven't even bothered setting a time zone as a user preference. Internally everything is stored, computed and sent back and forth to the client using UTC, and we do the translation client-side for both input and output.
For example, suppose a user has their local machine's time zone set to US Eastern. When looking at my web page, an event that occurred at Unix timestamp 1359416775000 would render as, say "Mon Jan 28 18:46:15 2013" with code no more complex than
new Date(1359416775000).toLocaleString();
But suppose I need to send that user an email about this event. What time zone should I use to render the timestamp in this email? The obvious answer is to let the user pick their time zone. Now suppose I do this and this user picks US/Eastern. Great. Now suppose the next time the user logs into my website their local machine is on US Central time. That same piece of Javascript code would now cause the timestamp to render as "Mon Jan 28 17:46:15 2013".
Is this really the right behavior? The user has picked a time zone in my application, but it only applies to email?
This seems like a common enough problem that I feel like there ought to be a common best practice, I'm just wondering what that is.
You should, by default always display times in the users local time zone. At any point of you display the time using another time zone, this should be made clear by also printing the timezone.
As such, if the users time zone is US/Eastern, you would display a time in hos time zone, in your example "Mon Jan 28 18:46:15 2013", while if you show him an event that actually happens in US/Central, you should show "Mon Jan 28 17:46:15 2013 US/Central".
Now if the user moves to a computer whose time zone is US/Central, then yes, as default you should now show him the time in US/Central. So you would in both cases display the date as "Mon Jan 28 18:46:15 2013", no time zone necessary. They will have the computers current time in the corner of the screen, so it won't cause much confusion.
If you let the user pick his timezone, which is common in sites where the time display isn't decided by the client time zone setting, then you should by default show the times in that time zone all the time, no matter what time zone the computer is in. Remember that it is up to the user to make sure his computer is in the right time zone. Most people who travel with their laptops won't change the time zone when they move.
It is theoretically possible for you to warn the user that he has selected another time zone than the one he seems to be located in, by getting a geolocation from the IP. But unless you are writing a calendar application I would think that annoys people more than it helps them.
Unfortunately you cannot set the user's timezone which is used by the non-UTC date methods.
You can only work around that by adding/substracting your custom timezone offset when outputting/reading a date, like in this example.

How do you calculate if a specific time in a specific time zone is affected by daylight savings using JavaScript?

I know that new Date().getTimezoneOffset() accounts for the local user's timezone & DST, but how to calculate the current local time in say Timbuktu for an arbitrary time in the future?
JavaScript does not have a timezone database built in to the language (as can be seen by perusing the spec). Instead it only has the concept of "local time" and "UTC time," with there being only one local timezone.
It is possible there is a browser API for getting a timezone database, but I have never heard of it. There are some third-party projects that interface with such databases; a quick search turns up timezone-js.
I doubt there is any algorithm that could give you what you want. The nations of the world often choose not to follow the standard time zone rules. Worse the changeover dates for DST are different.
There are 3 sources that I can think of to check:
Jeppesen, a subsidiary of Boeing, is the primarily civilian supplier for the entire world for aeronautical navigation information. I just checked my old Jeppesen manual that I ceased getting weekly updates for when I retired 13 years ago. It gives the time zone for all major airports in the world and the dates of their DST change. Go here for contact info. I would suspect that by now it's conveniently available electronically, but Jeppesen doesn't give anything away for free.
ICAO, the International Civil Aviation Organization (part of the UN now I think) would I think maintain that information, but I'm not so sure about the DST data. Their data, I believe, is available either free or for a nominal charge.
IATA, the International Air Transport Association, might also maintain that data.
I would think that the last two organizations might respond favorably to a simple request for a URL with that data if they know of one.
Also, if can get ahold of any airline dispatcher working international flights, they would have to have that information available.
Also, check this and others you'll see if you Google "airline time zone and dst data."
The easy part is accounting for timezones. You can find the default (+0) timezone by just subtracting timezone*60*60 seconds from the date, then adding the new timezone*60*60 to the date.
Then it's just a matter of making the time you want, using:
d = new Date(year, month, day, hours, minutes, seconds, milliseconds)

Time Zone Sensitive Date and Time Display in Web Applications?

I am looking for recommendations on displaying times in a web application in a time zone other than the user's current time zone.
We store our dates/times in UTC/GMT in the database, so it is not an issue to format the time for UTC/GMT or the user's current time zone. However, in other situations we need to display the time from the point of view of an arbitrary time zone (i.e. every date/time on this page is in Eastern, regardless of whether or not the user is in West Coast, Central, Eastern, etc.).
In the past we have stored offsets or time zone info, then done the calculations in server code in .Net or else we have done some client-side manipulations in javascript that I would prefer to avoid, since it all becomes very dependent on javascript and the user's browser. I'd like to know the best way to do this in a more client-side/MVC type application.
Here is an example:
Date stored in db: 1302790667 (Thu, 14 Apr 2011 14:17:47 GMT)
Converted date displayed for a client in Central time zone: Thu Apr 14 09:17:47 2011
Date I actually want to display, always in Eastern time zone: Thu Apr 14 10:17:47 2011
In the above example, it's easy to get the time in UTC (#1) or the user's current time zone (#2) but it is more difficult to get #3. My options seem to be:
Store offsets or time zones in the db and do calculations on the client - this is what we've done in the past with .Net but it seems even messier in client side code is the path we are currently trying to avoid.
Do the conversion on the server and send down a full date for display to the client - client receives a string ("Thu Apr 14 10:17:47 2011"). This works but it's not very flexible.
Do the conversion on the server, break it into parts and send those down to the client, then put them back together. ("{DayOfWeek:Thu, Month:Apr, Day:14, Hour:10, Minute:17}"). This gives us the correct data and gives us more flexibility in formatting the date but it feels a little wrong for this scenario.
Any other options ideas? How do others handle similar situations? Thanks.
Our results:
I tried out a few libraries like Datejs, MS Ajax, etc. and I was never very happy with them. Datejs didn't work at all in a few of my test cases, is not actively maintained, and seemed to focus a lot on syntactic sugar that we don't need (date.today().first().thursday(), etc.)
We do use jQuery for some basic date/time parsing.
I came across a lot of "roll-your-own" client-side date conversion "hacks", most of which only addressed the conversion to UTC, started off working fine, and then eventually fell apart on some edge case. This one was the 90% solution for a lot of standard UTC conversion but didn't solve our "arbitrary timezone" issue.
Between the code complexity the conversion routines added and the bugs they seemed to cause, we decided to avoid client side date processing most of the time. We do the date conversions on the server with our existing date handling routines and pass the formatted dates or info down as properties to be used by the view. If we need a separate date, we just add another property. There are usually only a few properties that we need at a time (i.e. EventDateUTC, EventDateLocal, EventDateAlwaysAustralia, and EventDayOfWeek).
I offer the suggestion that you look into the Datejs library. It offers a bunch of extensions to basic JavaScript date manipulation, including a "setTimezone()" method and flexible ways to convert a date into a formatted string for display.
I usually hesitate to suggest libraries when their use is not explicitly allowed for in questions, but Datejs isn't very large and it's pretty solid (even though it's called an "alpha" release). If you'd prefer not to rely on something like that, you might want to look at it anyway just to see the basics of how its extensions were implemented.

Categories

Resources