How to deal with User's timezones in Rails - ruby-on-rails

I know it's difficult to detect user's timezones so it would be a best practice to display available timezones to the users and let them select.
How do I get this generated for Rails?
Also how would I use this? Should I save this as string "US/Michigan" and use some class methods to convert this in my current server time when I want to process some user related cron tasks?

The TZInfo gem should be helpful to you:
http://www.rubydoc.info/gems/tzinfo/frames
(On Windows, you also need tzinfo-data to support it, on other OS's you shouldn't).
There are a LOT of timezones, so I'm not sure if displaying a list of all of them is the best UI or not. But you could.
TZInfo::Timezone.all
Will return all timezones as TZInfo::Timezone objects. (583 objects). To get the canonical identifiers for each timezone, you could do:
TZInfo::Timezone.all.collect(&:canonical_identifier)
It looks like some canonical identifiers are of the form "America/New York", but others are not. "Libya", "Egypt", technical things like "Etc/GMT+7" -- so maybe you don't really want to show all of them. It looks like instead of TZInfo::Timezone.all, you could use ZInfo::Timezone.all_country_zone_identifiers to get just the more "normal" ones (still 418).
You could also choose to have the user choose a country first, then choose a timezone from within that country -- TZInfo supports that, grouping timezones by country where they are in use, see the README for more info.
I'm not really sure what the best UI here is. If I were you, I'd look at as many websites and apps as possible to see how they do it -- although it might be hard to find any that let the user choose the timezone! Figuring out the right UI and implementing it are kind of two separate problems. But once you figure out the UI you want, the TZInfo gem should give you what you need to implement it.
I think you probably do want to 'detect' the user's timezone first, and only force them to select it if they notice the detection was wrong. I'm not sure the best ways to try and detect. I havne't used it, but [here's a Javascript library] that tries to detect user's current timezone as the canonical identifier you should be able to use with TZInfo to actually convert to GMT or another timezone.
Timezones are officially uniquely identified by strings like "America/New York", so that is what makes sense to store as representing a timezone, yep. And TZInfo will give you the methods you need to take those canonical identifiers, and use them to get a timezone object you can use to convert from local time in that timezone to GMT or server time. (You are probably best off always using GMT in your code and storing as GMT in the database, rather than 'server local time').

Related

Change jenkins timestamp according to the browser timezone

I have a really simple question and couldn't find the answer about. Is it possible to change the jenkins timestamp according to the user's browser timezone. As my Jenkins server is in UTC but some of our users are in Central timezone while other are in few different timezones. So I want that they see the task(s) timestamp according to their browser time/timezone. How we can achieve this? Thanks
One possible approach for this could be to deliver all dates in a default timezone and use momentjs or a similar library to convert the date time on the frontend side to either the browsers timezone (this could be the default) or to a manually selected one.
This would be rather easy to implement and would not require any big changes in jenkins itself, just all places that deliver times must be wrapped in some markup, e.g. a class and some data-fields (e.g. data-datetime containing an rfc3339 timestamp)
Jenkins issues JENKINS-19887 and JENKINS-1962 detail potential fixes that could be introduced, though they haven't been implemented in any version of the system yet.
If you're only looking for timestamps with the browser's time zone in your console output (with all other timestamps unmodified), Timestamper provides this functionality.

MVC Handling Timezones and JSON Serialization - How to Convert to Specific Timezone

I've spent quite a bit of time on stackoverflow and the internet trying to determine what has been done in my situation. I am building a
centralized line of business website that could span multiple timezones. Based on some valuable information here I have a plan in place to handle this.
Timezone will be a part of a user profile
All Dates will be stored in UTC
EF sets DateTimeKind to UTC on retrieval from database
Is it possible to prevent EntityFramework 4 from overwriting customized properties?
Create some html helpers for DatePickers and DateDisplays to convert UTC time to local time (based off user timezone)
Use Model Binding to convert back to UTC on form posts.
Timezone Strategy
Now to the issue I don't know how to solve. Kendo UI uses JSON to pass information back and forth and as far as I can tell the JSON.net serializer cannot serialize a date to a specific time zone. I can serialize the date as UTC or have JSON.net automatically convert it to local time using the DateTimeZoneHandling setting but that would be local time on the server. From looking at the JSON.net code, I'm not sure I could even write a converter to do what I wanted. So far now if I send the date as UTC through JSON.net and Kendo automatically converts the time to the browser's local timezone.
Assuming User Profile timezone = Browser Timezone seems a little scary for me and I wanted to see what stackoverflow suggests I do. Thank you in advance.
Technology
ASP.net MVC 5
Entity Framework 6
Telerik Kendo UI Controls
JSON.net
Unfortunately I don't know many of the tools you are using, but I know how I would handle timezones.
I would use UTC everywhere, except when displaying times (or rather: datetimes) and in user input.
I would let the browser's JavaScript do the conversion in output, using the browser's timezone. In input, the conversion can be done either client side or server side. In the latter case the timezone must be part of the information sent from the browser to the server. The UTC timezone on the servers should be set at a level as low as possible, and, if possible, in all components (OS, web server, DB...).
A user's preferred timezone is nonetheless useful for all cases where the timezone is not known (e.g., in email communications - but remember to always have the timezone in time formats).
There are times (no pun intended...) when the above is not easy or does not apply. E.g., a schedule (calendar), to which the user attaches the timezone they have in their head, not necessarily the browser's one. Another case is when the user's timezone has to be known for some computation that can not easily be done on the browser - in this case the server will have to get the timezone from the browser first. But most of the time (still no pun intented...) you can happily do without timezones (with UTC) except immediately before showing something to the user or immediately after getting something from the user.
Regarding your last paragraph: you will very soon run into trouble if you assume "user profile timezone = browser timezone".
Some last words of advice:
"Timezone" is an ambiguous term. It may refer to a fixed offset from UTC (like UTC+1), or to the rules for calculating this offset for any instant in a given area (like the timezone of Rome, Italy). Always use the second meaning (e.g., don't use the current offset for a date in the future or past, but correctly convert datetimes back and forth), and remember that both can change during a user's session.
Be careful not to handle "pure" dates as the midnight of the same day (and not as noon either - people in Samoa will thank you), because then the date can change when the timezone changes. In other words, don't attach time information to pure dates.
P.S.: By following a link of yours, I was happy to find that I totally agree with the closing remark of this answer (by someone with more SO reputation than me)
You certainly can pass UTC to the browser and let it convert, but you have to be aware of the potential for inaccuracies. You also can convert server-side and pass a DateTimeOffset in your JSON, but you may need to render it yourself, using something like moment.js.
In the end, what you should do is entirely up to you. Many use cases are similar, but there are plenty of acceptable different paths depending on your exact needs.
Your question is very broad the way you have asked it. What parts are you most concerned with? Kendo? EF? JavaScript? Client-side time zone conversion? Formatting? Could you refine it or provide some context to the type of things your date/time values are representing? Otherwise, you may get some useful tidbits, but it will be hard to provide a definitive answer.
(Oh, and you might be interested in this.)
I was finally able to find this answer here https://stackoverflow.com/a/11968692/3412859 that will allow me to write my own JSONconverter and convert to a specific time zone before it is serialized. I now have all of the dates being converted on the server side based on the timezone setting in the user profile.
I had this problem , too.
It works for me.
I translated the time format to
Start=2016-4-9T8:30:00.000Z
End=2016-4-9T13:30:00.000Z
in background or database.
By doing this,local time zone is useful.

.net MVC Application server time is different

So my web apis depend a lot on the current time of the user for authorization. The problem is the current time of the user is almost always different from the server's datetime. Was wondering if anybody can give me a suggestion as to how to properly deal with it.
My first solution was to convert every time to GMT 0400 time. But it seems like I'll have to store the location of the user or something like that, also I'm not really sure how to do it.
Thanks!
Welcome to the wonderful horrible world of localization. There's no easy way to handle this type of stuff in a reliable way. It takes work and lots of testing. First off, you should dump .NET's built-in DateTime localization immediately. Use something like NodaTime. It will make your life much easier (especially when it comes to testing that your localization code actually works).
The chief problem you're going to have is that there's no reliable way to get the user's timezone server-side. You have two options:
Just have the user explicitly choose their timezone and store it in their profile for future use. This is obviously the most reliable method, but it means you'll either need to force your users to enter this information or resort to some default plan if it's missing.
Use Javascript (you can see the methodology here). Essentially, you can use JS to set the value of a hidden field or send the info with AJAX. Obviously the user's client will need to have JS support and have that support enabled (pretty safe bet in 99.99% of cases, but there are still screen readers and such that don't have JS support and some users prefer to disable JS out of security concerns).
However, typically when it comes to use timestamps in authorization, only the server time matters anyways. The only use I know of is creating digests to prevent replay attacks, but the timestamp will be created based on server time and then validated based on server time. How is your use case different?

how to effectively keep/update postal and telephone code format for each country?

currently we have a table for regex format for phone and postal code for countries that we use to validate when the user register through our forms.
but the problem remains on the maintenance on the correctness of these format, thus what's a good way to ensure that we always have the latest copy of this information? is there a web service/etc that i can use to get this?
or does it even make sense to keep all these format but instead use a relaxed method to ensure that the user just keys in something which roughly matches the format?
the information is used solely for shipping and billing address.
we're using asp.net 2.0 btw.
thanks
The UPU hold information on international postal address formats, which includes postcodes, so you can periodically check there.
I don't know a way you can be updated automatically, these things get change every now and then, and you need to have backward support also, not enough to know the current format, so usually I don't put anything strong on phone format. postal codes are more stable.

Grails application serving multiple timezones

What is the correct way to deal with timezones in a grails application that has users in multiple timezones? Is there a standard aproach to muilt timezone Grails applications? Maybe there is something simlar to the way Rails handles multi timezone support? http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/
Is there a way to set the current timezone per user session? This would mean you could have multiple active user sessions with different timezones being used for dealing with ”Date”.
Im trying to avoid having to manually deal with timezone conversions.
Thanks
First, it is often a good idea to present the user with a choice - which timezone he is in. You can try to infer it from his settings, but that's not reliable. In grails you can let the user select his timezone by:
<g:timeZoneSelect name="myTimeZone" />
Note that the value attribute defaults to the current Locale. So I'd guess grails' default localeresolver will do a fine job guessing the locale of the user.
For that to work you need to store all times in the DB in UTC (or another timezone which is fixed for the whole application)
The documentation of <g:formatDate> claims it has only 3 attributes, but it seems since at least version 1.2 it supports a timeZone attribute. So you'd have to put timeZone="${currentUser.timeZone}"
You could try using JodaTime and DateTime class, it has timezone inside. Still, I believe you'll need to store times in UTС. For that, you'll have to provide own mapping to GORM that applies UTC, own date formatting taglib that takes into account user timezone, and some more things.
OTOH, if you have some common functionality, like background jobs (I believe you will), what time zone is it going to use?

Resources