Timezone issues with timestamps in the FQL table 'event' - timezone

I'm having trouble with event timezones in the start_time and end_time fields in the event FQL table. I want to show the timestamp in a formatted date that accounts for the user timezone. Empirically, it appears the timestamps are in the PST timezone, so I convert them to GMT and add the user timezone, as contained in the timezone field in the user table. Conversion to GMT is performed by Java, with the following code (this should account for daylight saving time automatically):
long millis = 1000 * timestamp;
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
int offset = tz.getOffset(millis);
long timestampGMT = millis + offset;
However, this approach produces different results than the Facebook site.
For example I have an event with start_time=1317416400 and a user with timezone=2. Converting to GMT and adding the user timezone I get September 30th 2011, 16:00:00, but the Facebook site shows September 30th 2011, 14:00:00.
How can I obtain the correct (as in FB site) result?
Examples:
Summer:
http://www.facebook.com/event.php?eid=234094353309432
Created by a user on GMT+2
Time shown on the site: Friday, September 30 · 2:00pm - 7:00pm
start_time (from FQL): 1317416400
If it was UTC, then: Friday, September 30th 2011, 21:00:00 (GMT)
If it was PDT (with DST, so GMT-7), then: Friday, September 30th 2011, 14:00:00 (GMT-7)
Winter:
http://www.facebook.com/event.php?eid=254174591293234
Created by a user on GMT+2
Time shown on the site: Sunday, December 25 · 1:00pm - 4:00pm
start_time (from FQL): 1324846800
If it was UTC, then: Sunday, December 25th 2011, 21:00:00 (GMT)
If it was PST (no DST, so GMT-8), then: Sunday, December 25th 2011, 13:00:00 (GMT-8)
Thanks

Related

How to compare UTC to DateTime.now in Ruby

I am trying to check if a time submitted by the user in a datetime_field in a form is less than the current time.
My current issue is that the submitted date is that exact date in UTC, is Mon, 13 Apr 2020 23:00:00 UTC +00:00, however, DateTime.now.utc is 2020-04-14 03:14:00.694513 UTC.
I would like to be able to compare just the dates and the times to compare them, regardless of the timezone they are in.

Convert US Central Time to different time zones using moment JS

I have a Date Time(Friday, 27 October 2017 4:00:00 AM) in US Central Time zone (CDT). I want to convert this Date Time into different time zones. These are time zones i wanted to convert.
Eastern Time (EDT)
Pacific Time (PDT)
New Delhi, India (IST)
Central Europian Time (CET)
Riyadh, Saudi Arabia (AST)
Pakistan Standard Time (PKT)
Lagos, Nigeria (WAT)
Australian Standard Time (AET)
Greenwich Mean Time (GMT)
Moscow, Russia (MSK)
China Standard Time (CST)
This is how i am doing
var dateTime = moment.tz("2017-10-27 4:00:00 AM", "America/Chicago");
var IST = dateTime.tz('Asia/Calcutta').format('MMMM Do YYYY, h:mm:ss a');
console.log(IST) // October 27th 2017, 9:30:00 am
The returned Date Time is wrong. Because Indian Standard Time is 10 hours and 30 minutes ahead of Central Time.
It should be Friday, 27 October 2017 2:30 PM (IST)
Thanks!
The problem isn't with the conversion to the Indian time zone - it's the original parsing of the Chicago time.
This:
var dateTime = moment.tz("2017-10-27 4:00:00 AM", "America/Chicago");
... is treated as 4am UTC, and then converted to America/Chicago, so it ends up representing 11pm local time (on October 26th) in Chicago. You can see that by just logging the value of dateTime.
If you change the code to:
var dateTime = moment.tz("2017-10-27 04:00:00", "America/Chicago");
... then it's treated as 4am local time on the 27th, which is what I believe you expected. The result of the conversion to Asia/Calcutta is then 2:30pm as you expected.
So either change the format of your input, or specify that format. For example, this works fine too:
var dateTime = moment.tz("2017-10-27 4:00:00 AM", "YYYY-MM-DD h:mm:ss a", "America/Chicago");

moment-timezone format doesn't return the expected result

Using the tz() function from moment-timezone as follow:
moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format()
//returns '2017-10-15T13:53:43+08:00'
moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format('h:m A')
//I expect to return '9:53 PM' but it returns '1:53 PM'
Ultimately, I want to apply the fromNow() function to format the result. But when I apply it, it uses the initial timestamp and ignore the timezone applied.
moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').fromNow()
//I expect to return '1 min ago' when actual time is 13:54 UTC (21:54 in HK) but it returns '8 hours ago'
What am I doing wrong here?
When you do:
moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong');
You're creating a date/time that corresponds to October 15th 2017, at 1:53 PM in Hong Kong - which, in turn, corresponds to 2017-10-15T05:53:43Z (5:53 AM in UTC).
When you call the format() function:
moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format();
It returns:
2017-10-15T13:53:43+08:00
The +08:00 part is just the UTC offset - it just tells that Hong Kong is 8 hours ahead UTC. But 2017-10-15T13:53:43+08:00 (1:53 PM in Hong Kong) is exactly the same instant as 2017-10-15T05:53:43Z (5:53 AM in UTC). That's why fromNow(), when the current time is 13:54 UTC, returns 8 hours.
If you want the date/time that corresponds to 1:53 PM in UTC, you should use the utc() function:
// October 15th 2017, 1:53 PM in UTC
moment.utc('2017-10-15 13:53:43');
Now, when the current time is 13:54 UTC, fromNow() will return 1 minute (because the date/time represents 1:53 PM in UTC).
To convert this to Hong Kong timezone, just use the tz() function:
// convert 1:53 PM UTC to Hong Kong timezone (9:53 PM)
moment.utc('2017-10-15 13:53:43').tz('Asia/Hong_Kong').format('h:m A');
This will convert 1:53 PM UTC to Hong Kong timezone (resulting in 9:53 PM):

Why does adding and subtracting 2 months to a date not give back the same date?

I'm a bit confused about this outcome, taking today's date minus 2 months, and then taking that date again and adding two months, does not give me today's date when assign the dates to a variable.
Time.zone
"Eastern Time (US & Canada)"
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> a = today - 2.months # This is persisted to the db
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> b = a + 2.months
=> Wed, 30 Aug 2017 00:00:00 EDT -04:00
If I however, just use the same object, it moves back and forth properly:
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> today - 2.months
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> today + 2.months
=> Tue, 31 Oct 2017 00:00:00 EDT -04:00
The problem is obviously when "a" gets saved to a database, and then retrieved later on, and calculated plus 2 months..., it should match today's date.
TL;DR
A month is not a fixed duration. Adding or taking a month does not give the same "time shift" depending on which day you are.
The usual algorithm
to add or take months is the following :
try to land on the same day number (4th, 30th, 31st) as you started, just by changing the month
if you would land on an impossible date (like 31th September, 30th February, 29th February for some years) then just go the maximum allowed day number of this month
This implies that adding some months then taking out the same number of months will not necessarily give you back the same date.
Examples :
31st of some month + 1 month --> One would want to get to the 31th of next month
But if there is no 31st of next month (like for 31th of August, no 31st of September), then what to do ?
Usual interpretation would say that you want to go to the end of the month, this is 30th September (for rent or other monthly subscription, for instance)
But usually, 30th of some month - 1 month --> One would want to get to the 30th of the previous month.
That would lead to .... 30th of August. Not 31th of August.
Hence: some date + 1 month - 1 month does not necessarily give the original date !
Another example :
Start at the 30th of August.
Take a month -> 30th of July
Add a month -> You want to get to 30th of August (same number, next month) or to the end of August ?
The default algorithm will try to give the same day number -> 30th of August (which is more logical now)
Also with days...
Note that the same problem happens with days,but much less often ! When some days don't have the same number of hours, for daylight saving days, when adding and taking same number of days you might not get back to the original date and time as you started from.

Grails - Get next/previous TimeZone

I'm working with a Grails application and I can't find a clear way to translate a date from one TimeZone to the next/previous TimeZone available (I will define what I consider the next/previous Timezone below).
The facts:
I'm working with date filters in a Grails Application so we can retrieve information based on those filters. The application supports TimeZone so the logged user can set his profile to a particular Timezone.
The dates of the filter are on UTC format and the information on the database is stored also on UTC.
The question:
The user logged has his profile on Timezone UTC+00.
There is a predefined date filter called "This Week", when a user clicks on it generate a period of dates corresponding to the current week in UTC so we can bring all the information on the database from the current week.
If we are on the current day (Thu 19 Nov 2015) the dates the filter will generate for "This Week" to look on the database would be:
Sun Nov 15 00:00:00 UTC 2015 to Sun Nov 22 23:59:59 UTC 2015
This is correct and will bring all the information on the database on that period.
Now, suppose the user doing this has set a Timezone UTC +01.
If we are on the current day (Thu 19 Nov 2015) the dates the filter will generate to look on the database would be the same period:
Sun Nov 15 00:00:00 UTC 2015 to Sun Nov 22 23:59:59 UTC 2015
But in this case I need to translate them to a correct TimeZone because the "This Week" for the current user won't be the same for a user on UTC +01 this is because for this user the date Sun Nov 15 00:00:00 would correspond to the date
Sun Nov 14 23:00:00 on the UTC time (since he/she is one hour ahead) and therefore when filter by "This Week" I should search on the database by the dates:
Sun Nov 14 23:00:00 UTC 2015 to Sun Nov 22 22:59:59 UTC 2015
The thing is I have created a method utcDateToUserTZ(date) to translate from an UTCDate to LocalTimeZone date but this would convert the UTC dates:
Sun Nov 15 00:00:00 UTC 2015 to Sun Nov 22 23:59:59 UTC 2015
into
Sun Nov 15 01:00:00 UTC 2015 to Sun Nov 23 00:59:59 UTC 2015
And that is not what I'm looking for. I need those dates to be translated to the previous TimeZone.
I hope no to be walking around with an issue that has a simpler solution, in which case I hope you can tell me if there exist something easier to solve this.
Thanks,
The method commented before is:
public DateTime utcDateToUserTZ(Date date) {
TimeZone profileTimeZone = getCurrentUserProfile().timeZone
DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(profileTimeZone)
return new DateTime(date, dateTimeZone).withZone(dateTimeZone)
}

Resources