ISO-8601 extension proposal: Relative Dates

Photo of an open calendar booklet

ISO8601 is an excellent standard and deserves high praise.

Something missing is the ability to specify relative dates and times, such as “next week”, “an hour ago”, or even “the start of month, at three weeks ago”.

I work primarily in PHP and JS, which both have ways of interpreting human-language strings to adjust a given date-time. Not wanting to use two different standards, it seems appropriate to create a third.

My initial thoughts follow, and I welcome constructive feedback.

A string of text is provided to alter a given date-time, which would default to the current date-time.

The string starts with C (for comparative), similar to durations starting with P (for periods), and repetition starting with R.

Each of the following parts of the string is an instruction. Instructions have three elements: a sign (+-=) followed by a number followed by a letter. The letter denotes the unit of the change, the sign sets the direction and the number determines the distance. If the sign is = then the instruction is setting that value absolutely.

Like ISO-8601, a T splits the date and the time, allowing M to be unambiguous. If it is not present, then M will be assumed to denote months.

An example of C +1Y -1M =14D T +2H =0M =0S, run against 2025-09-15T17:12:13, would result in 2026-08-14T19:00:00 since it adds 1 year, decrements the month to August, sets the day of the month to the 17th, adds 2 hours, and sets the minutes and seconds to zero.

Negatives may be written with either the minus or the hyphen-minus.

Whitespace may be included for human legibility, but will be ignored by parsers.

Instructions starting +0 and -0 are ignored as they imply no change.

Letters W and Q denote week and quarter respectively. Week calculation is as per ISO-8601; they start on Mondays, and are counted from the first week containing a Thursday.

Instructions =0M (unless after T), =0W, and =0D are all invalid since there is no zeroth month, week, nor day of the month. Similarly, using = to specify non-existent days will be impossible, e.g. =32D will throw errors rather than wrapping to the first of the next month.

For convenience, the number 0 (or 1 for months and days) may be replaced by a ^. The last of the related unit, e.g. the 59th minute or the 29th day of February in a leap-year, may be found replacing the number with $.

@todo choose a way to specify e.g. "start of the week"

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.