How can I display the correct created and modified times in my webapp? - ruby-on-rails

I'm working on a Rails application that's kind of like a blog. Users create Entries. I'm trying to work out how to handle time storage and display. I've read this writeup about Rails timezone support.
It's great but it doesn't cover what my app needs to do. It only looks at cases where you want to convert stored time to the current logged in user's time zone. In contrast, the effect I want is...
A user creates an entry in California at 10:00 a.m.
A couple years later he moves to New York and then at some point looks at his old entry. The "created" date should say "10:00 a.m." He doesn't care about time zones. He just wants to know what time of day he felt like it was when he wrote the entry.
If he then edits the Entry in New York the displayed "modified" date is, again, his subjective time of day when he made the edit. (Let's assume he went to "preferences" and changed his time zone setting when he moved.)
Also, for the sake of thoroughness, the app should be able to report the "real" absolute time when an Entry was created or updated.
(Note -- my imaginary user is a guy, but for women it should work roughly the same way.)
The way I'm thinking of implementing it is...
Have the attributes User#time_zone, Entry#created_at_utc, and Entry#updated_at_utc in addition to the standard created_at and updated_at.
The user selects their time zone from a menu when they sign up. (They can change it later if they want.)
The app uses User#time_zone to store created_at and updated_at in the user's subjective local time. If it's 10:00 a.m. for them, the app writes "10:00 a.m." to the DB.
The app also saves the current UTC time in the aforementioned _utc fields to deal with the last requirement above.
Is that a good way to do it? Is there a better way?

The two roads you can take are:
Store a timezone (UTC) in the user account as well as in every post - update the post's timezone along with the updated_at field whenever the user changes the post (if he or she has changed timezones).
Store the timezone only in the user account. When the user changes timezones, update every post that belongs to the user and add/subtract to the created_at/updated_at dates.
The first option seems like the cleanest option to take. For this you would only have to create a new method in your post record:
def locational_updated_at
updated_at + timezone.seconds
end
Where timezone is an integer containing the seconds since UTC.

If you can, you should avoid storing two different sets of timestamps, and you should avoid storing any non-UTC dates. Both of these things will lead to confusion. I'm not completely sure I understand what you're doing (though I like your idea of subjective time), but wouldn't it be enough to just attach a time zone to every post, and always use that zone to display the times? It would default to the time zone set in the author's account, so he could change it when he moved cross-country without affecting previous posts.
I think that's all you need--to attach a time zone to every post. Is that sufficient? Or am I missing some part of this?

Related

rails - where to store writeable system-wide variables

I've had a read of similar questions and not found a simple answer. I need to store a date value that has nothing to do with my models.
For example, let's say I have a screen which displays a graph of user activity based on all records being created after a specific date. I need to store that date somewhere. An admin user will change this initial date depending on whether they need to look at the last six months, or the last year etc. That setting will then be the same for all admin users. So it's not an admin user setting.
I thought about a config file, but then it needs to be writable and these seem idea for values that are being looked up but not edited on a regular basis?
Any advice appreciated..

handing daily tasks in rails with timezones and DST

In my app, users can select a time that they want to receive a daily email. I then regularly run a script to find users who have an upcoming email to send and send it. So, if users elect to have an email that goes out at 7AM, I look for users with that selected as their time and send it.
The problem is of course timezones. I'm going to have users in different timezones and need 7AM to always be 7AM, regardless of timezones or daylight savings.
I can understand how to do it for display purposes, but I can't find much info on executing queries that have to factor in the timezone and DST for a collection of users with varying times and timezones.
This can probably be most easily accomplished by simply saving everything in the database as UTC. You can adjust the times for display and incoming form data by using the users' specified time zone.

How to get time adjusted to user timezone in Sitecore CMS

I'm using custom command to import data for newly created item in Sitecore. Since there is a lot of data importing, this process is in the background. I send an email with import status once it is completed. I am able to get email from UserProfile:
User currentUser = Sitecore.Context.User;
UserProfile currentProfile = currentUser.Profile;
The problem is that we have import starting time in the email. Since I haven't find where the user time zone is stored, I can't adjust it to match the user time zone.
Do you happen to know if there is any setting to define user time zone from the C# code?
P.S. In the bottom right corner there is a correct time adjusted for the current user, but I didn't find any information on how and where it stored
I'm not sure it's stored (in fact I believe Sitecore stores DateTime relative to the CM server and not the client).
For you to have an accurate timezone for the visitor/customer, you'd need to either ask for it directly (registration prompt or user profile option) or look it up using Geo data from the originating ip (though with VPNs and public access points this becomes increasingly less reliable).
My suggestion would be to store the start time in UTC and (if necessary) let the user know it was started at that time. If a time elapsed is required, perform the calculation before sending the email off--since start time and end time are relative to the server anyways, just let them know it took "5min 30sec" to complete. If they receive the email at 5:08pm (email timestamp) they can do some simple match and assume it was started at 5:03 (or thereabouts).
I believe the time in the bottom right of the Desktop is using the users local system time (most likely using JavaScript) so it is not dependent on their Sitecore user profile.
There doesn't appear to be any timezone information stored against the user profile, the best you can get the is the CultureInfo based on the Regional ISO Code, although this still is not truly accurate for countries with multiple timezones (USA, Canada, Russia, Australia etc).
You could extend the User Profile to add custom properties and store a timezone field, but it is not available by default.
My suggestion would be to list the start time in UTC time, and let the user mentally adjust to their own timezone. This is what I have done previously, esp since servers themselves could be located in any location.

Rails 4 local Time shown according to local time zone

I am working on rails 4 application. I want to show the time for comment I created. If I open the site in india then time should be shown in IST (according to indian standard) and If I am in USA so for the same comment that i made in india time should be shown according to USA time zone.
What do I need to do in my config file for development and production?
Do I need to change anything in database?
Please help me.
Rails always saves times in UTC (universal time), and the server has a setting which tells it which timezone it (the server) is running in.
To show different times to the client, Rails (which runs on the server) will need to know which time zone the client is in. This isn't in a standard request header so you will need to get them to submit the information somehow. Once you know their timezone you can ensure that you always show times to the user using their timezone - there are helpers for this.
Getting their timezone can be done explicitly, eg by giving them a timezone dropdown in their "My Account" page, and then saving that in their user record, and/or by making it more upfront and forcing them to choose one in a popup, if you don't know it.
Or, you can do it for them using Javascript, passing it through in a cookie. See this article for an example of how to do it.
http://thisbythem.com/blog/clientside-timezone-detection/
Well one solution can be to store the time zone of the user in the database, write a filter
around_action in your ApplicationController which would set the Time.zone to the time_zone from the database field.
You might want to look at Time.zone and TimeZone in the rails api
Here is a railscast , you can figure it out from the comments and the github link.

Is it safe to store time zone ids in a database or can they change?

I have just started working with NodaTime. In my app, the user creates an event and chooses a time zone. Regardless of whether I use the BCL (Windows) time zone list or the TZDB (Olson) list (and do not mix them!), I need to persist the id of the time zone to my database so that I can later recreate the timezone-aware time.
Given that timezone ids appear to be somewhat arbitrary and are not an ISO standard, can I rely on always finding that id in future when I call GetZoneOrNull?
I am assuming that the GetZoneOrNull method is the defence against that happening; that is, when it is passed an id that does not exist in its own Ids collection. My question is: if an id has been retrieved from the Ids collection, can I trust that GetZoneOrNull will never in future return null?
But if an Id can disappear from history, what is the best strategy to deal with that?
Obviously, if you switch between windows' timezones and TZDB then the timezone Ids will be different. Olson timezone Ids are meant to be stable and should not change. Even though I say that, there have been changes in the past, but the old Ids still exist and are aliases for the new ones. All the "region/city" ids are the new style and that scheme was chosen so that they should never have to change again. Old ids were sometimes named based on legal names of timezone which are subject to change.
We are storing the Olson Id of the timezone in a table on my current project.
I can't speak for windows timezone ids.

Resources