Unix time stamp and timezones - timezone

quick question. I'm working with the Instagram API and everything I'm getting from their response seems to be pacific timezone. Now, I'd like to save this data to a use and display it to visitors. Problem is, visitor may be from all different timezones. So should I convert this to unix timestamp to GMT, then on display, use some sort of javascript or PHP to convert the unix timestamp to a user friendly, timezone adjust date time?
If so, my two questions are... how would I convert a timestamp in PST timezone to GMT and the how would I display that to users from different timezones? Thanks!

You can create a couple TimeZone objects and then create the DateTime object in the correct timezone the convert
$pdtTimezone = new DateTimeZone('America/Los_Angeles');
$userTimeZone = new DateTimeZone(whatever_you_need);
$orig_date_obj = new DateTime( time_to_convert , $pdtTimezone) ;
$orig_date_obj->setTimeZone($usertimezone);

You can do this by using DateTime in php to calculate the offset that you will need to convert from one time zone to another. See http://blog.serverdensity.com/2009/03/21/handling-timezone-conversion-with-php-datetime/

Related

Rails, Postgres and Timezone

I have table which have a datetime field named date. When doing a POST in order to insert a new row, the date sent from the client (browser) looks like 2015-11-20T14:30:00+10:00 which is actually a correct date and timezone.
However, inside Postgres this date has been inserted as 2015-11-20 04:30:00.000000, which as you can see, is not at all the same as above. I know the problem is related to the timezone. But I cannot seems to figure out a fix.
For information, I have configured my app timezone :
class Application < Rails::Application
config.time_zone = 'Brisbane'
end
Ideas?
2015-11-20T14:30:00+10:00 means that the local time of 14:30 is 10 hours ahead of UTC. Your database field reflects the correct UTC value of 04:30. This is often the desired behavior, especially if the value represent a timestamp - the date and time something occured (past tense).
In PostgreSQL, there are two different types of timestamp fields (reference)
The TIMESTAMP WITH TIME ZONE field accepts an input that contains a time zone offset. It then converts the value to UTC for storage. On retrieval, it uses the session's timezone setting.
The TIMESTAMP, or TIMESTAMP WITHOUT TIME ZONE simply stores the date and time given, ignoring any offset, and not converting to UTC.
Most of the time, you should indeed use TIMESTAMP WITH TIME ZONE. You should only use TIMESTAMP WITHOUT TIME ZONE if you need to retain the local date and time value, such as in scheduling of future events and calculation of business hours. And for those scenarios, it often makes more sense to split date and time into separate DATE and TIME fields.
One last thing - if you can avoid it, avoid using Rails time zones and use standard tzdb zones. "Australia/Brisbane" is the full tzdb identifier equivalent to the Rails "Brisbane" time zone. Refer to the section on Rails time zones at the bottom of the timezone tag wiki.
I found this gem to be incredibly useful and easy for correctly setting the time https://github.com/kbaum/browser-timezone-rails

One time zone to another time zone conversion

How to convert one time zone value to another time zone value using <s:date>
For example I would like to convert
CTS to GMT+05:30(or IST) using <s:date> tag
In my database I have added date and user time zone value with respect to GMT.
my data base server is showing time zone CTS(I am unalbe to chage it).
Here I would like to convert date from CTS time zone to user time zone that is GMT+05:30(or IST) or users time zone stored in database
For Indian Standard Time, this is the way:
<s:date name = "yourDate"
format = "dd/MM/yyyy HH:mm:ss a"
timezone = "GMT+05:30" />
In the comments to this related question, you can read about common mistakes you might encounter when dealing with this.
A Date has no TimeZone. A date is just a number of milliseconds since a specific point in time (EPOCH: 01-01-1970, 00:00:00 UTC).
When you save a Date into a database, you are just saving that Long number. If your database has a specific TimeZone, it means that when you will run a query on it, it will format the Dates for human representation with that TimeZone. There are TimeZone settings in your DB, in your AS, in your framework too. But through the whole chain, the Date remains always the same Date object, just represented differently.
Many databases allows you to save the TimeZone informations along with the date. But since you said:
In my database I have added date and user time zone value with respect to GMT.
Then you can absolutely ignore the fact that
my data base server is showing time zone CTS
Just take that Date, and format it with your desired TimeZone, with the code provided.
If this is just confusing you (taking GMT dates, shown as CTS in your DB visualizer, and shown as IST in the browser), then log-print that Date three times in the Action using the three different TimeZones, to have a match between the whole chain, that will help you debugging where the conversions are applied and how.

rails - Store DateTime objects in same time zone as timestamps

When i save a DateTime schedule_time to the DB, it saves according to my local time, but the timestamps (created_at) are saved apparently in UTC (7 hours ahead of my pacific time)
So if i submit the form setting my schedule_time for right now it will be 7 hours different than my created_at.
i need to show many users their times in their own selected zone, and i also need to compare times against each other, so i want all db entries to be in the same zone. Testing on my machine, my user has his zone saved as Pacific (-7:00), but its saving schedule_time in local time, not really UTC, so when i try to display the time back like this:
#item.schedule_time.in_time_zone(#user.time_zone)
it actually takes the stored datetime and subtracts seven hours from it giving me 7 hours before i wanted. i think the best thing is to just store all the datetimes in a uniform way so i can compare them easily.
changing this value config.time_zone = 'UTC' does nothing to change the stored format of my datetime. it stores in my local time regardless, while storing the timepstamps in real UTC.
ive also tried to reformat the datetime before storing it, with in_time_zone(#user.time_zone) but it had no effect on the stored time.
if i can just get schedule_time stored in UTC just like my timestamps are stored i could make this work! any ideas?
If you want to store schedule_time converted to UTC before storing it in the database, you can include a before_save callback in your Item model to convert it as follows:
before_save { |item| item.schedule_time = item.schedule_time.utc }
sorry i was totally on the wrong track.
the issue was with the jquery date picker i was using (will_pickdate). it returns a date and time but with a +0000 time zone offset. by default, the picker autofills with the current local time, but when i submitted that, rails basically thought it was receiving a time in UTC and added it as my local time but with +0000.
in order to store the date properly i have to keep the time and date from the picker intact, but just shift the +0000 part to something appropriate:
my_time.change(offset: user_time_zone_offset)

Accounting for daylight savings in rails webapp and iCal

Right, this is a bit confusing for me, so I'm going to try and explain from the top!
I have a rails web app. It's an internal company app and will only be used in the UK.
One of the things the app does is manage meetings.
Meetings have a date & time when they start. There's a date/time picker on the form which allows the user to pick the date & time the meeting is for. I save this date AS IS into the database. All meetings last 2 hours, so the end time is simply start + 2 hours.
Example:
2013-06-23 6:45PM in the form is stored in the db as 2013-06-23 18:45:00
2013-12-23 6.45pm in the form is stored in the db as 2013-12-23 18:45:00
Note that the first date is during Daylight Savings (BST) and the second is during GMT. I don't actually care whether it is GMT or BST: the meeting happens at that time, absolutely.
Inside the rails webapp, I simply print out the exact date & time from the DB - formatted nicely, of course!
Now, at some point I send an email to the organiser of the meeting, and the person they're meeting with. This email tells them the the date & time of the meeting etc, and also includes an iCal (.ics) file for them to put into their (Outlook usually, but also Apple or gmail) calendar.
The issue I am having is that (using the above examples) Outlook shows the meetings like this:
Meeting #1: Start: 23/06/2013 7:45pm, End: 23/06/2013 9:45pm
Meeting #2: Start: 23/12/2013 6:45pm, End: 23/12/2013 8:45pm
Note that it has adjusted the first one because of the BST/GMT thing.
The text of the .ics file contains this code:
Meeting #1:
BEGIN:VCALENDAR
...
DTEND:20130623T204500Z
DTSTART:20130623T184500Z
...
END:VCALENDAR
Meeting #2:
BEGIN:VCALENDAR
...
DTEND:20131223T204500Z
DTSTART:20131223T184500Z
...
END:VCALENDAR
So I am encoding the dates/times using the Z timezone (UTC). I understand this is why Outlook mis converting the UTC time into the BST time for #1 and leaving #2 alone (because GMT == UTC)
My question is: how do I stop this happening? I want the time the meeting is scheduled for to be the absolute, actual time, regardless of GMT/BST: 6:45pm
Should I be storing the date-times as UTC in the DB? How would this be done (I assume it would apply to all dates, not just meeting start dates). And how to re-convert them back into the actual datetime when I display them in the webapp?
Extra:
I have an entry in my initializers/time_formats.rb like this:
:ical => "%Y%m%dT%H%M00Z"
So dates come out like "20130623T184500Z". I use this when building the ics. And this I think is the issue - if the date/time is during BST I don't want to be using Z, but something else?
Your problem is your date/time format. You have:
DTSTART:20130623T184500Z
in your .ics file and this corresponds to 19:45 BST (as British summer time is UTC+1).
There are a few things you should do. First, you can simply remove the 'Z' from the end of your dates. This means that the times inherit the timezone of the calendar, or the underlying application.
This will work assuming that the machines which are running Outlook are all in the Europe/London timezone. If not, or if you want to be a bit safer, you should also specify the following after your BEGIN: VCALENDAR line:
X-WR-TIMEZONE:Europe/London
This specifies the default timezone for all dates which are not specified explicitly.
Finally, if this does not work for any reason then you need to define your datetimes explicitly. First you need to add a timezone definition for Europe/London to the calendar. The info you need is available at http://www.tzurl.org/zoneinfo-outlook/Europe/London.ics. Then you need to ensure that all datetimes are of the format:
DTSTART;TZID=Europe/London:20130623T184500
This last approach is the best, as it means that if your requirements expand to other timezones you will be able to handle them relatively easily.
Sorry to answer this myself, but in case anyone else runs into this here's what I found was the cause of my particular issue. Note that the answer above re timezones also makes sense!
My rails app is storing UTC datetimes in the DB (as is default)
But, it also thought it's own timezone was UTC, which also seems to be the default.
The upshot of that is essentially it was storing local dates, local to UTC anyway. Changing the app to know it was sitting in Europe/London made it so the dates in the DB are all now accurately UTC (meaning, they're an hour off if I'm currently in BST)
I can now use the Z datetime format in iCals, and outlook and the rails app both convert the UTC date back into the actual datetime for the viewing-user's locale (Europe/London for everyone at the moment). This is what I wanted.

Storing DateTime in UTC

If one only works with dates and no time, would it still be wise to save all your dates in UTC for a multi timezone app?
I suggest using DateTimeOffset - this allows you to store both the DateTime and the UTC offset.
Also, read this SO question about timezone best practices.
The general the answer is yes, but it will introduce errors in time conversion if time part is not stored. Timezone conversions need time part to produce meaningful results. So just store full UTC time (i.e. date and time), since you can always trim it to just date if necessary.

Resources