microsoft / microsoft/api-guidelines

Feedback on Dates and Times in Section 11

Open
#22 4 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
23.3k
Forks
2.7k
PR merge metrics
No merged PRs in 30d

Description

Please review the following constructive criticism with regard to the date and time guidelines in section 11.

Iso8601Literal is poorly defined
  • ECMAScript is not the normative reference for ISO8601, and actually gets parts of it wrong. For details, refer to my blog on this subject, and to tc39/ecma262#87 and tc39/ecma262#138.
  • The preferred reference should be RFC 3339. The W3C's Date and Time Formats note is also applicable.
  • The guidance misses a very important consideration, which is that date-time forms should be fully qualified with either Z or a numeric offset +/-HH:MM so that they represent a distinct point in time:
    • "2016-07-16T08:23:45Z" is a specific point in Coordinated Universal Time (UTC).
    • "2016-07-16T01:23:45-07:00" is the same point in time with a particular time zone offset.
    • "2016-07-16T01:23:45" is not a specific point in time. It could be interpreted differently depending on time zones. While this is type of data may be useful within an application, it has very little meaning in an API and should generally be discouraged as an interchange format.
  • The guidance misses another very important consideration, which is that date-only forms should not carry any time element or time zone offset.
    • "2016-07-16" is a valid date. Date-only values should always be passed like this.
    • "2016-07-16T00:00:00Z" is not a date. It's a date-time at midnight UTC. The equivalent date value may be quite different when adjusted to the local time zone. This is a commonly encountered anti-pattern, and should be actively discouraged.
    • "2016-07-16T00:00:00" is also not a date. It's a date-time at midnight local time. The main problem here is that not every local date has a midnight (due to daylight saving time spring-forward gaps). For example, "2016-10-16T00:00:00" does not exist in most of Brazil. Given this value, and this time zone context, some implementations may skip forward to 1:00, some may skip backward to 23:00 the prior day, and some may throw an exception.

To address all of these, the guidance should recommend using the date-time and full-date formats defined in RFC 3339 § 5.6.

StructuredDateLiteral is not good advice
  • The list of DateKind value codes appears to be invented here. I know of no JSON library that will create or read value in this split two-state form. You would have to create your own intermediate objects, then either have a long case-statement to handle all the different kinds, or limit yourself to one particular kind. Indeed, the guidance talks about how different clients would need to understand the kind of the server. This requirement defeats the purpose of having an interchange format to begin with. In other words, it's no more helpful to have a kind property that tells you what format to expect in the value property than it would be to describe the custom format in the API's documentation.
  • The list is by no means complete of all the different custom formats that have been used for date and time values. As soon as you start picking and choosing from which custom formats you want to honor, you open it up for others to add more. Notably absent is RFC822/2822 such as used in HTTP headers, and also the abhorant but widespread ASP.NET JSON date format. (See Scott Hanselman's blog post, On the nightmare that is JSON Dates. Plus, JSON.NET and ASP.NET Web API.) I'm not advocating for either of these, but if you continue down this route - eventually someone will. There are many others also.
  • Some of the formats in the list are completely inappropriate for the web.
    • The "O" format is being used for OLE Automation Dates - this format uses an ambiguous local time scale, while most of the others use UTC. Also, some implementations base it from 1900-01-01 or 1899-12-31, instead of 1899-12-30, and there is extra work to account for negative values. This is something that should be only handled directly when interfacing to/from OLE values - such as by calling DateTime.FromOADate or DateTime.ToOADate in .NET. The OADate values themselves should never be put into a web API.
    • The "X" format honors the Excel 1900 leap year bug - really? This should never leak out of Excel. Putting it in an API would be a horrible thing to do.
  • This document is supposed to be about best practices - guidelines that REST APIs should follow. Therefore, I highly recommend you remove this section entirely. Formats that are specific to a particular language should not be used in a language-neutral setting. The only advice should be to use the common interchange formats described by ISO8601.
Misc other items
  • The info on Durations in 11.4 is good, but it would also be good to mention that one should be careful to avoid specifying Months or Years unless they actually mean the variable unit of time associated with a calendar month or a calendar year. In other words, do not assume all months are 30 days, or all years are 365 days.
  • The info on Intervals in 11.5 is acceptable, but it's equally acceptable to simply place each value into a separate JSON property. This is more common in practice, as there are few parsers that natively recognize the interval format. In other words, { "interval" : "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z" } is less commonly used than { "start" : "2007-03-01T13:00:00Z", "end" : "2008-05-11T15:30:00Z" }. Though either are technically acceptable, the latter is usually prefered because it's easier to work with.
    • The same applies for Recurring Intervals in 11.6. Also note that this format is much less commonly encountered in web APIs than it is in scheduling systems. I'm not sure how much value it has in this document as a recommendation for REST APIs.

Thanks.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read section 11, especially the guidance on Iso8601Literal, StructuredDateLiteral, Durations in 11.4, Intervals in 11.5, and Recurring Intervals in 11.6. Compare the recommendations with RFC 3339 §5.6 and decide which date, duration, and interval guidance should be revised or removed; done means the section reflects the agreed language-neutral REST API guidance.

Written by the indexing model from the issue text.

Assessment

Domain
api, documentation
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.