` element to your markup. Provide a default formatted date as the element's text content (e.g. April 1, 2014).
- ``` html
- <relative-time datetime="2014-04-01T16:30:00-08:00">
- April 1, 2014
- </relative-time>
- ```
Depending on how far in the future this is being viewed, the element's text will be replaced with one of the following formats:
- 6 years from now
- 20 days from now
- 4 hours from now
- 7 minutes from now
- just now
- 30 seconds ago
- a minute ago
- 30 minutes ago
- an hour ago
- 20 hours ago
- a day ago
- 20 days ago
- on Apr 1, 2014
So, a relative date phrase is used for up to a month and then the actual date is shown.
Attributes
| Property Name | Attribute Name | Possible Values | Default Value |
|:---------------|:-----------------|:-----------------------------------------------------------------------------------------|:-----------------------|
| datetime | datetime | string | - |
| format | format | 'auto'\|'micro'\|'elapsed'\|string | 'auto' |
| date | - | Date \| null | - |
| tense | tense | 'auto'\|'past'\|'future' | 'auto' |
| precision | precision | 'year'\|'month'\|'day'\|'hour'\|'minute'\|'second' | 'second' |
| threshold | threshold | string | 'P30D' |
| prefix | prefix | string | 'on' |
| second | second | 'numeric'\|'2-digit'\|undefined | undefined |
| minute | minute | 'numeric'\|'2-digit'\|undefined | undefined |
| hour | hour | 'numeric'\|'2-digit'\|undefined | undefined |
| weekday | weekday | 'short'\|'long'\|'narrow'\|undefined | undefined |
| day | day | 'numeric'\|'2-digit'\|undefined | 'numeric' |
| month | month | 'numeric'\|'2-digit'\|'short'\|'long'\|'narrow'\|undefined | 'short' |
| `year` | `year` | `'numeric'\|'2-digit'\|undefined` | `'numeric'`*|| timeZoneName | time-zone-name | 'long'\|'short'\|'shortOffset'\|'longOffset'\|'shortGeneric'\|'longGeneric'\|undefined | undefined |
*: If unspecified, `year` will return `'numeric'` if `datetime` represents the same year as the current year. It will return `undefined` if unspecified and if `datetime` represents a different year to the current year.
datetime (string)
This is the datetime that the element is meant to represent. This must be a valid
ISO8601 DateTime. It is also possible to use the
date property on the element to set the date.
el.date expects a
Date object, while
el.datetime expects a string. Setting one will override the other.
- ``` html
- <relative-time datetime="2014-04-01T16:30:00-08:00" tense="past">
- April 1, 2038
- </relative-time>
- <script>
- const el = document.querySelector('relative-time')
- console.assert(el.date.toISOString() === el.datetime)
- el.date = new Date()
- console.assert(el.datetime !== "2014-04-01T16:30:00-08:00")
- </script>
- ```
format ('auto'|'micro'|'elapsed'|string, default: 'auto')
The default format is auto, but this can be changed to micro or elapsed.
The default auto format will display dates relative to the current time (unless they are past the threshold value - see below). The values are rounded to display a single unit, for example if the time between the given datetime and the current wall clock time exceeds a day, then the format will _only_ ouput in days, and will not display hours, minutes or seconds.
The micro format which will display relative dates (within the threshold) in a more compact format. Similar to auto, the micro format rounds values to the nearest largest value. Additionally, micro format will not round _lower_ than 1 minute, as such a datetime which is less than a minute from the current wall clock time will display '1m'.
The elapsed format will always non-rounded units of time, where any non-zero unit of time is displayed in the compact notation format. This format is also absolute, and so tense does not apply. This can be useful for displaying actively running timers.
| format=auto | format=micro | format=elapsed |
|:-------------:|:--------------:|:----------------:|
| in 2 years | 2y | 2y 10d 3h 20m 8s |
| 2 years ago | 2y | 2y 10d 3h 20m 8s |
| in 30 days | 30d | 30d 4h 20m 8s |
| 21 minutes ago| 21m | 21m 30s |
| 37 seconds ago| 1m | 37s |
Additionally, format accepts a
strftime compatible format. Providing a strftime format will override all other attributes on the element, and the time will be displayed formatted based on the strftime value. This can be useful, for example, to dynamically remove relative formatting based on a user action.
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" threshold="P100Y" format="micro">
-
- </relative-time>
- ```
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" format="%Y-%m-%d">
-
- </relative-time>
- ```
tense ('auto'|'past'|'future', default: auto)
If format is anything other than 'auto' or 'micro' then this value will be ignored.
Tense can be used to fix relative-time to always display a date's relative tense in the future or the past. Setting tense=past will always display future dates as now, while setting it to future will always display past dates as now.
- ``` html
- <relative-time datetime="2038-04-01T16:30:00-08:00" tense="past">
- April 1, 2038
- </relative-time>
- ```
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" tense="future">
- April 1, 2038
- </relative-time>
- ```
precision ('year'|'month'|'day'|'hour'|'minute'|'second', default: 'second')
If format is anything other than 'elapsed' then this value will be ignored.
Precision can be used to limit the display of an elapsed formatted time. By default the elapsed time will display times down to the second level of precision. Changing this value will truncate the display to the respective unit, and smaller units will be elided. Some examples:
| precision= | Display |
|:-------------:|:-------------------:|
| seconds | 2y 6m 10d 3h 20m 8s |
| minutes | 2y 6m 10d 3h 20m |
| hours | 2y 6m 10d 3h |
| days | 2y 6m 10d |
| months | 2y 6m |
| years | 2y |
threshold (string, default: P30D)
If tense is anything other than 'auto' or format is anything other than 'auto' or 'micro' then this value will be ignored.
Threshold can be used to specify when a relative display (e.g. "5 days ago") should turn into an absolute display (i.e. the full date). This should be a valid
ISO8601 Time Duration. If the difference between the current time and the specified
datetime is _more_ than the duration, then the date will be displayed as an absolute value (i.e. the full date), otherwise it will be formatted to a relative display (e.g. "5 days ago").
The default value for this is P30D, meaning if the current time is more than 30 days away from the specified date time, then an absolute date will be displayed.
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" threshold="P100Y">
-
- </relative-time>
- ```
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" threshold="P0S">
-
- </relative-time>
- ```
prefix (string, default: 'on')
If tense is anything other than 'auto' or format is anything other than 'auto' or 'micro' then this value will be ignored.
When formatting an absolute date (see above threshold for more details) it can be useful to prefix the date with some text. The default value for this is on but it can be any string value, an will be prepended to the date.
- ``` html
- <relative-time datetime="1970-04-01T16:30:00-08:00" prefix="this happened on">
-
- </relative-time>
- ```
second, minute, hour, weekday, day, month, year, timeZoneName
For dates outside of the specified
threshold, the formatting of the date can be configured using these attributes. The values for these attributes are passed to
Intl.DateTimeFormat:
lang
Lang is a
built-in global attribute. Relative Time will use this to provide an applicable language to the
Intl APIs. If the individual element does not have a
lang attribute then it will traverse upwards in the tree to find the closest element that does, or default the lang to
en.
Additional Elements
In addition to `` this package provides convenience elements, which are configurations over ``. These additional elements will be removed in a future major version release.
time-until
This element is the same as ``. `.tense` will always return `future`, regardless of the value set in the attribute.
You can use `time-until` to always display a relative date that's in the future. It operates much like ``, except in the reverse, with past events shown as `just now` and future events always showing as relative:
- in 10 years
- in 20 days
- in 6 hours
- in 20 minutes
- in 30 seconds
- just now
Add a `` element to your markup. Provide a default formatted date as the element's text content (e.g. April 1, 2024).
- ``` html
- <time-until datetime="2024-04-01T16:30:00-08:00">
- April 1, 2024
- </time-until>
- ```
Micro format
The optional format="micro" attribute shortens the descriptions to 1m, 1h, 1d, 1y.
- ``` html
- <time-until datetime="2012-04-01T16:30:00-08:00" format="micro">
- April 1, 2014
- </time-until>
- ```
time-ago
This element is the same as ``. `.tense` will always return `past`, regardless of the value set in the attribute.
An always relative time-ago-in-words description can be generated by using the time-ago element extension. This is similar to the relative-time extension. However, this will never switch to displaying the date. It strictly shows relative date phrases, even after a month has passed.
- ``` html
- <time-ago datetime="2012-04-01T16:30:00-08:00">
- April 1, 2014
- </time-ago>
- ```
For example, if this markup is viewed two years in the future, the element's text will read 2 years ago.
Micro format
The optional format="micro" attribute shortens the descriptions to 1m, 1h, 1d, 1y.
- ``` html
- <time-ago datetime="2012-04-01T16:30:00-08:00" format="micro">
- April 1, 2014
- </time-ago>
- ```
local-time
This is a variation of `` with some subtly different formatting.
This custom time extension is useful for formatting a date and time in the user's preferred locale format.
- ``` html
- <local-time datetime="2014-04-01T16:30:00-08:00"
- month="short"
- day="numeric"
- year="numeric"
- hour="numeric"
- minute="numeric">
- April 1, 2014 4:30PM PDT
- </local-time>
- ```
When this markup is viewed in a CDT timezone, it will show Apr 1, 2014 6:30PM. If it's viewed in a browser with European date preferences, it will read 1 Apr 2014 18:30.
Browser Support
Browsers without native [custom element support][support] require a [polyfill][].
- Chrome
- Firefox
- Safari
- Microsoft Edge
[support]: https://caniuse.com/custom-elementsv1
[polyfill]: https://github.com/webcomponents/custom-elements
See Also
Most of this implementation is based on Basecamp's
local_time component. Thanks to @javan for open sourcing that work and allowing for others to build on top of it.
@rmm5t's
jquery-timeago is one of the old time-ago-in-words JS plugins.