Parse timezone int to string (timezone name) (facebook api)
How do you convert a timezone from int to string (etc: Europe/Stockholm)?
You can't. Read "Time Zone != Offset" in the timezone tag wiki.
Facebook's documentation explains that the timezone
field is the user's timezone offset from UTC.
What it doesn't make clear, but I have found through experimentation, is that it is not necessarily the user's current offset, but it instead it is the offset as of the user's last log in. If the user changes time zones, or daylight saving time begins or ends, that will not be reflected in the Facebook data until the user's next log in.
See also these posts:
- Facebook API, timezone and country
- FaceBook Time zone and Event Times
how to convert facebook's userinfo timzone field to Time Zone name?
I still don’t know which language you’re after (if any particular). Here’s a Java solution:
long secondsPerHour = TimeUnit.HOURS.toSeconds(1);
long offsetSeconds = Math.round(5.5 * secondsPerHour);
if (offsetSeconds < ZoneOffset.MIN.getTotalSeconds()
|| offsetSeconds > ZoneOffset.MAX.getTotalSeconds()) {
System.out.println("Not a valid UTC offset, is out of range");
} else {
ZoneOffset offset = ZoneOffset.ofTotalSeconds((int) offsetSeconds);
System.out.println(offset);
}
It prints
+05:30
You can use the ZoneOffset
from this snippet anywhere a ZoneId
is expected, since ZoneOffset
is a subclass of ZoneId
. ZoneId
is the modern Java class to represent a time zone.
How are user's timezone encoded in facebook
Use the graph explorer with a valid token (or request a token) and look at an example. You'll see that the timezone is a number representing the hours ahead or behind UTC.
https://developers.facebook.com/tools/explorer/?method=GET&path=me
Mine is currently 1, which is BST (UTC + 1 hour). I believe yours, being in France, will be 2 (summertime is automatic), and San Francisco will be -7. India will be 5.5
Does Facebook's login API update the timezone offset depending on whether DST is used in a user's area?
Facebook's documentation explains that the timezone
field is the user's timezone offset from UTC.
What it doesn't make clear, but I have found through experimentation, is that it is not necessarily the user's current offset, but it instead it is the offset as of the user's last log in. If the user changes time zones, or daylight saving time begins or ends, that will not be reflected in the Facebook data until the user's next log in.
See also this related question.
Facebook API, timezone and country
Per this documentation, the only way for a user to change their timezone is to change their computer's timezone and log out and back in to Facebook. This would lead me to believe that they are simply taking the offset from UTC in JavaScript in the browser and passing it back to the server.
So the value of the timezone
field coming back from the Facebook Graph API is probably the offset as of the last time the user logged in.
It's also possible it represents the offset as of the date the user signed up, and that it can't change. I couldn't find any reference in the documentation, so one would have to experiment to be sure.
At either rate, one can't derive the time zone from the offset alone. There are many time zones that have the same offset. For a useful analogy, see my answer on a related subject here.
Set the User's timezone when the only info is a UTC offset number.
No. Time zones don't work that way. A time zone offset only applies to a specific point in time. Many time zones share the same offset at various times. Some are indistinguishable from others with an offset alone.
For example, -7
could be MST, or it could be PDT. It might be used with "America/Phoenix"
, which is on MST year-round. But it might belong to "America/Denver"
which would use MST (-7) in the winter and MDT (-6) in the summer. Or it might belong to "America/Los_Angeles"
, using PST (-8) on the winter and PDT (-7) in the summer.
See also, the timezone tag wiki
Regarding Facebook, it's only giving you the time zone offset as of the user's last login. It is not necessarily even the correct offset for the current moment in time.
Problem parsing date/time with timezone name using Howard Hinnant's library
When reading an offset with %z
(e.g. -0600
), combined with a sys_time
type such as system_clock::time_point
, the parse time point is interpreted as a local time, and the offset is applied to get the sys_time
, as desired in your first two examples.
However this is not the case when reading a time zone name or abbreviation with %Z
(note the change from lower case z to upper case Z).
%Z
parses a time zone abbreviation or name, which is just a string. The common case is for this to just parse an abbreviation, e.g. CST. And in general, there is no unique mapping from an abbreviation to an offset. And so the offset can not be internally applied. Thus the parsed value should always be interpreted as a local time.
However all is not lost. You can parse the time zone name with %Z
into a string, and then look up the time_zone
with that name and use it to convert the parse local_time
into a sys_time
. This could look like:
#include "date/tz.h"
#include <chrono>
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
istringstream in{"2022-04-01 12:17:00.1234 US/Central"};
string tz_name;
local_time<microseconds> local_tp;
in >> parse("%F %T%t%Z", local_tp, tz_name);
system_clock::time_point tp = locate_zone(tz_name)->to_sys(local_tp);
cout << tp << '\n';
}
Just add a string
as the third argument in your parse
call, and make sure the first argument is a local_time
instead of a sys_time
. Then use locate_zone
to get a time_zone const*
and call to_sys
with that, passing in the parsed local_time
.
The above program outputs:
2022-04-01 17:17:00.123400
This is an hour off from the -6h offset because US/Central goes to daylight saving on 2022-03-13 (-5h offset).
How can I convert the facebook post created_time to the time zone of the user?
This is the code I use to convert a UTC time string to a localized time string. Note the key for conversion is to use the TimeZone
methods getRawOffset()
, inDaylightTime(...)
and getDSTSavings()
.
Note my date format is slightly different to what you are using so you'll need to change it.
public String GetLocalDateStringFromUTCString(String utcLongDateTime) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String localDateString = null;
long when = 0;
try {
when = dateFormat.parse(utcLongDateTime).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
localDateString = dateFormat.format(new Date(when + TimeZone.getDefault().getRawOffset() + (TimeZone.getDefault().inDaylightTime(new Date()) ? TimeZone.getDefault().getDSTSavings() : 0)));
return localDateString;
}
Obviously you want a Date
object so you just need to change this line...
localDateString = dateFormat.format(new Date(when + TimeZone.getDefault().getRawOffset() + (TimeZone.getDefault().inDaylightTime(new Date()) ? TimeZone.getDefault().getDSTSavings() : 0)));
...to...
Date localDate = new Date(when + TimeZone.getDefault().getRawOffset() + (TimeZone.getDefault().inDaylightTime(new Date()) ? TimeZone.getDefault().getDSTSavings() : 0));
...then you just need to change the return type of the method and return localDate
.
Get UTC date time by Date and time Zone name
I would use a library like Day.js for this purpose. You can parse in the date and time in a timezone, convert to UTC, then display in the desired format.
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(customParseFormat);
function getUTCDateTime(date, time, timeZoneName) {
const utcDate = dayjs
.tz(`${date} ${time}`, "YYYY-MM-DD HH:mm", timeZoneName)
.utc()
.format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]");
return utcDate;
}
Parse Datetime with +0 timezone
Any ideas what I have overseen?
strftime.org claims that %z
UTC offset in the form ±HHMM[SS[.ffffff]] (empty string if the object
is naive).
this mean that it must contain at least 4 digits after +
or -
(HHMM
part, which is compulsory), taking this is account Dec 03 2020 01: +0
is not compliant with used format string, whilst Dec 03 2020 01: +0000
is
import datetime
dtObj = datetime.datetime.strptime("Dec 03 2020 01: +0000", '%b %d %Y %I: %z')
print(dtObj)
gives output
2020-12-03 01:00:00+00:00
Related Topics
PHP Adds Keys to Decoded and Then Encoded JSON Data
Forbidden :You Don't Have Permission to Access /Phpmyadmin on This Server
Environment Driven Database Settings in Laravel
Comparing Bcrypt Hash Between PHP and Nodejs
Cosine Similarity VS Hamming Distance
Dynamically Load Information to Twitter Bootstrap Modal
Phpexcel_Writer_Exception with Message "Could Not Close Zip File PHP://Output."
Problem with Adding Root Path Using PHP Domdocument
Only Variables Should Be Passed by Reference In... on Line 13 Fail
PHP File Uploads Doesnot Read $_Files['Image']
How to Send JSON Response in Symfony2 Controller
How to Pass Param from Controller to Layout in Yii2
How to Retrieve All Variables from a Twig Template