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.
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.
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.
I want to implement timezone in my web application. I researched and saw most web app use a GMT dropdown, here is the link to that dropdown http://www.attackwork.com/BlogEntry/6/Time-Zone-Dropdown-Select-List/Default.aspx
Then I saw this article suggesting UTC is the way to go when it comes to implement timezone. https://web.archive.org/web/20210513223048/http://aspnet.4guysfromrolla.com/articles/081507-1.aspx Basically it's saying don't use DateTime.Now instead use DateTime.UtcNow
My questions are,
Is there a dropdown of the timezones in UTC, like the first link I showed there is one on GMT?
Should I really use UTC or GMT?
.NET 3.5 provides the TimeZoneInfo class which should make it relatively simple for you to populate a dropdown with time zones. GMT came before UTC and UTC was officially instituted on January 1, 1972. See this link for more information. For today's purposes, the two are pretty much synonymous, though they have different historical origins. Use whichever looks and functions better for your purposes.
I'm not sure if this is what you intended to ask, but in your database you should always store timestamps in UTC/GMT (as noted by others they mean essentially the same thing). For each user of your web app, store the time zone preference.
Then whenever you display the timestamp for something to a user, convert the UTC time in the database to the user's timezone.
GMT (Greenwich Mean Time) is the same as UTC (Universal Coordinated Time). This isn't an either/or choice - use it :)
Use Localization settings, functions and features anywhere possible.
If you aren't running against SQL Server 2008 or don't want to abstract timezone management to the database, you should store all times as UTC/GMT and apply the timezone difference based off the user's profile setting, so that users from all around the world can see timestamps on events in their local time.
The distinction between UTC and GMT is probably too fine to bother with in your code. However, it's probably a good idea to always save and process times internally with zero timezone offset, and deal with it as a presentation concern.
It's also possible to use JavaScript to determine the user's probable timezone: examine the timezone offsets for some pair of Date objects reasonably close to the solstices (even January 1 and July 1 makes a suitable approximation) to obtain a coarse timezone identification. Feel free to use this information to determine a default timezone, but do allow it to be changed by the user: JavaScript doesn't provide sufficient detail to select the exact timezone with national and regional historical shifts, and it may not be enabled by the user anyway.
I have an asp.net webservice with a parameter of type datetime. I have noticed asp.net seems to offset the date based on the clients timezone.
I need to disable this functionality. I simply want to pass a date (i.e. 3/15/2009) to the webservice from javascript without any timezone context.
Is my only option to change the parameter type to string then convert it server side, or is there some way to disable the deserializer from offsetting my date param ?
I'd use a string.
It kind of makes sense - a DateTime is really a "point in time", so when two clients are talking about the same DateTime, they're talking about the same INSTANT. So saying "the meteor will hit earth in 5 minutes", should adjust itself to the timezone.
You could use a UTC date instead: http://www.java2s.com/Code/JavaScript/Date-Time/GetUTCDate.htm
I had exactly this "problem" and when I thought it through, I realized that the way it worked was indeed correct, at least for my scenario. In my case, I was receiving an activeFrom and activeTo date. These can only be dates (no time part) when I actually submit these values to the processor. Our web server is in Eastern Time. I happened to be testing from a client in Central Time. My test case was failing because the value stored in the database did not match what I sent (EG 04/01/2009 01:00 vs 04/01/2009 00:00).
I thought about just stripping off the time part. This seemed OK until I considered a request coming in from a time zone east of Eastern (which would happen becuase we have clients in Thailand). I was upset because the resulting date would be one day before the date sent in the request. Then I realized, that's exactly the date I want to use.
Hopefully your scenario will work out as serendipitously as mine.