I'm computing difference between two dates. One date came from Google Drive's createdDate, other date is from datetime.now(). I'm thinking I should get the localized value of createdDate so that the computed difference is accurate.
Please help or guide me what should I do.
Thanks!
Dates returned in Google Drive's queries are in RFC 3339 format. Default timezone is UTC.
If you are using Python, feed.date.rfc3339 is a RFC 3339 date parser and you might want to use this to interact with Python's native datetime library.
Related
I am currently working on a Ingestion API Schema File for Salesforce CDP. Using postman, I was trying to format the data type fields in my payloads using various specifications:
yyyy-mm-dd'T'hh:mm:ss'Z
yyyy-mm-ddThh:mm:ss.SSSZ
yyyy-mm-ddThh:mm:ssZ
and so forth. According to Salesforce's documentation, the payload data type field should be in ISO 8601 UTC Zulu with format yyyy-MM-dd'T'HH:mm:ss.SSS'Z (which does not work as the field value returns empty when ingested, although the call response is 'true'), however, talking to Salesforce support, they have suggested I try the following format:
2019-11-06T06:24:42.558008Z
With this, I finally managed to insert a record with correctly populated date fields into the CDP data object. However, I have never seen this format before and I am not sure how to work with this - I couldn't find any documentation on it that I can use to better understand it. Salesforce support was also not able to provide more explanation than "this is the format that works".
Any help or resource would be greatly appreciated.
(Also, did anyone else ever have this type of issue with Salesforce CDP? The platform is quite new with many bugs and the fact that it only accepts the above format seems a little strange to me...)
It's an RFC 3339 date, a "profile" of ISO 8601.
The RFC does not specify the number of decimal places for the fractional seconds. However, there is precedent in, for example, the Python standard library for using six-digit microseconds:
datetime.isoformat(sep='T', timespec='auto')
Return a string representing the date and time in ISO 8601 format:
YYYY-MM-DDTHH:MM:SS.ffffff, if microsecond is not 0
Different Salesforce APIs have different datetime-formatting requirements and can be quite strict about them. (And not all conform to the RFC). For example, the Bulk API does not work correctly with six-digit microseconds. There's little you can do besides conforming your data to the specific expectations of the API you're using.
Our front end wants only a date. My understanding is that the industry standard for JSON.NET and Web Api is ISO 8601. Is is possible to return a date portion ONLY from our Web Api while adhering to ISO 8601 standards, or will the date property (dateOfBirth) of our JSON object have to have all zeroes for the time portion in order to adhere to the ISO 8601 standard?
ISO 8601 is a standard that specifies many different formats. Section 4.1.2 covers dates, section 4.2.2 covers time of day, and section 4.3 covers date and time of day combined. The spec also defined a "basic format" and an "extended format" for each.
Some examples in the basic format:
Date: 20190611
Local time: 140000
Date and local time: 20190611T140000
Some examples in the extended format:
Date: 2019-06-11
Local time: 14:00:00
Date and local time: 2019-06-11T14:00:00
Also there are variations to the time of day which add Z for UTC or a specific offset from UTC such as -07:00. (These do not apply to the date-only form.)
Thus, to answer your question directly, yes you can pass just the date. That is still ISO 8601 compliant, as long as you use either of the date-only forms shown above. (The extended form is usually chosen for JSON responses.)
By the way, this isn't just an option, it's a best practice. Date-only value such as birth dates and other anniversary dates should not have a time attached - even if it's all zeros. Doing so contorts their meaning.
That said, be aware of some pitfalls:
Some platforms do not have a built-in date-only data type, and will assign midnight.
JavaScript's Date object (via the ECMAScript standard) deviates from ISO 8601 and parses date-only values as if they were at midnight UTC instead of midnight local time. Thus if you are calling your API from a web page, you may want to parse the values yourself, or use a library, or leave them as strings instead of Date objects.
There are certain time zones that have days with forward transitions (such as for DST) right at midnight, meaning the clocks tick from 23:59:59 to 01:00:00. If you specify midnight, some implementations will go forward, some will go backward, and some will error.
If you have to parse a date-only value to a date-time data type, one way to avoid these problems is to assign noon (12:00) instead of midnight (00:00).
Also, you may want to make sure ISO 8601 is indeed the standard you need to comply with. Many people say ISO 8601 when they actually mean RFC 3339. RFC 3339 is mostly compliant with ISO 8601, but only defines a date + time + offset profile. Thus it is appropriate for timestamps, but not whole dates.
When I'm pulling records from the QuickBooks Online API, I'm referring to the MetaData for a few tasks. But the timezone / offset is set to -07:00, like this for example: 2016-05-13T20:45:33-07:00.
Does any one know from experience what timezone they are using or what determines it? And is it possible to change it? I don't really mind storing the datetime in UTC and converting it back when retrieving it, but I need to make sure that the conversion is consistent. So if it's not always going to be the same timezone or offset, then I need to figure that part out too.
Thanks in advance.
I guess I am a bit late to answer, but this is for someone like me who end up here searching for the answer to what exactly is the timezone that Quickbooks Online store its date.
Quickbooks stores date in GMT as their servers are located in that timezone.
Reference : https://quickbooks.intuit.com/learn-support/en-us/employees-and-payroll/how-do-i-change-the-time-zone-setting/00/213730
What's the recommended timestamp format for a REST GET API like this:
http://api.example.com/start_date/{timestamp}
I think the actual date format should be ISO 8601 format, such as YYYY-MM-DDThh:mm:ssZ for UTC time.
Should we use the ISO 8601 version without hyphens and colons, such as:
http://api.example.com/start_date/YYYYMMDDThhmmssZ
or should we encode the ISO 8601 format, using for example base64 encoding?
Check this article for the 5 laws of API dates and times HERE:
Law #1: Use ISO-8601 for your dates
Law #2: Accept any timezone
Law #3: Store it in UTC
Law #4: Return it in UTC
Law #5: Don’t use time if you don’t need it
More info in the docs.
REST doesn't have a recommended date format. Really it boils down to what works best for your end user and your system. Personally, I would want to stick to a standard like you have for ISO 8601 (url encoded).
If not having ugly URI is a concern (e.g. not including the url encoded version of :, -, in you URI) and (human) addressability is not as important, you could also consider epoch time (e.g. http://example.com/start/1331162374). The URL looks a little cleaner, but you certainly lose readability.
The /2012/03/07 is another format you see a lot. You could expand upon that I suppose. If you go this route, just make sure you're either always in GMT time (and make that clear in your documentation) or you might also want to include some sort of timezone indicator.
Ultimately it boils down to what works for your API and your end user. Your API should work for you, not you for it ;-).
Every datetime field in input/output needs to be in UNIX/epoch format. This avoids the confusion between developers across different sides of the API.
Pros:
Epoch format does not have a timezone.
Epoch has a single format (Unix time is a single signed number).
Epoch time is not effected by daylight saving.
Most of the Backend frameworks and all native ios/android APIs support epoch conversion.
Local time conversion part can be done entirely in application side depends on the timezone setting of user's device/browser.
Cons:
Extra processing for converting to UTC for storing in UTC format in the database.
Readability of input/output.
Readability of GET URLs.
Notes:
Timezones are a presentation-layer problem! Most of your code shouldn't be dealing with timezones or local time, it should be passing Unix time around.
If you want to store a humanly-readable time (e.g. logs), consider storing it along with Unix time, not instead of Unix time.
RFC6690 - Constrained RESTful Environments (CoRE) Link Format Does not explicitly state what Date format should be however in section 2. Link Format it points to RFC 3986. This implies that recommendation for date type in RFC 3986 should be used.
Basically RFC 3339 Date and Time on the Internet is the document to look at that says:
date and time format for use in Internet protocols that is a
profile of the ISO 8601 standard for representation of dates and
times using the Gregorian calendar.
what this boils down to : YYYY-MM-ddTHH:mm:ss.ss±hh:mm
(e.g 1937-01-01T12:00:27.87+00:20)
Is the safest bet.
Always use UTC:
For example I have a schedule component that takes in one parameter DATETIME.
When I call this using a GET verb I use the following format where my incoming parameter name is scheduleDate.
Example:
https://localhost/api/getScheduleForDate?scheduleDate=2003-11-21T01:11:11Z
For JavaScript,
I normally save date as ISO format by writing: new Date().toISOString();.
Hopefully, it helps with your project.
GWT doesn't serialize Java Date properly. When I tried sending Date created in Javascript through the wire, I found out that dates between April 1st (funny) and 25th October for years before year 1983 get subtracted by one day.
That means that, say, both 1982-04-01 and 1982-03-31 become 1982-03-31 on the Java side.
Given the dates in question, I would guess that this is some kind of DST problem. I've tried googling, and found only one other reference that describes similar problem.
I also tried submitting bug to the GWT team, but curiously wasn't able to find bugtracker for GWT.
So, my questions are:
Anyone else run into this? I'm on GWT 1.7, and would like to confirm if this happens on 2.0 as well.
My workaround was to send dates as Strings, and parse them on server. Anyone knows better workaround?
Assuming that you are using a java.util.Date
Question 1: It seems that it is fixed in 2.0. I've created both Dates above (1982-04-01 and 1982-03-31) and they come through correctly to the server (both represent on the server as 1982-04-01 and 1982-03-31 respectively). My setup is:
GWT 2.0
Java 1.6
OSX 10.6.2
Question 2: You could always pass the 'milliseconds since January 1, 1970, 00:00:00 GMT' over the async service-which you can get using getTime() on the date object. On the server side you can then instantiate a new Date passing this value in on the constructor:
Date date = new Date(millis);
This saves fiddling around with formatters and parsers.
Dates and times are a complicated subject. The conversion can depend on the locale that the browser is running in and wether both you JVM on the server and the locales of the clients are up-to-date.
In some cases there can be differences because in some regions they switched timezones in the past.
GWT sends dates using just millis since epoch time. Since it is using Date objects, you are limited in that the Dates on the server side will be automatically modified to the servers timezone. Are you sure that you take into account the possible difference in timezones between client and server ?
David
I'm pretty certain the FTR library has some date emulation in it.
http://code.google.com/p/ftr-gwt-library
If you don't have to do client-side conversions (adapt to user's timezone) or calculations send it in a String from the server.
Never came across your specific problem though.
The possible problems soure is difference in Client/Server time zones.
We have also run into a similar problem. It was long enough ago that I do not remember the exact details but the gist of it was there were some minor differences between java.util.Date and the way dates were handled in Javascript. Our workaround was effectively the same as yours, where the actual value sent over the wire was generally a String.