- Notifications
You must be signed in to change notification settings - Fork184
Web component extensions to the standard <time> element.
License
github/relative-time-element
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Formats a timestamp as a localized string or as relative text that auto-updates in the user's browser.
This allows the server to cache HTML fragments containing dates and lets the browser choose how to localize the displayed time according to the user's preferences. For example, the server may have cached the following generated markup:
<relative-timedatetime="2014-04-01T16:30:00-08:00"> April 1, 2014 4:30pm</relative-time>
Every visitor is served the same markup from the server's cache. When it reaches the browser, the customrelative-time
JavaScript localizes the element's text into the local timezone and formatting.
<relative-timedatetime="2014-04-01T16:30:00-08:00"> 1 Apr 2014 21:30</relative-time>
Dates are displayed before months, and a 24-hour clock is used, according to the user's browser settings.
If the browser's JavaScript is disabled, the default text served in the cached markup is still displayed.
Available onnpm as@github/relative-time-element.
npm install @github/relative-time-element
This element uses theIntl.DateTimeFormat
&Intl.RelativeTimeFormat
APIs, which are supported by all modern JS engines. If you need to support an older browser, you may need to introduce a polyfill forIntl.DateTimeFormat
&Intl.RelativeTimeFormat
.
Add a<relative-time>
element to your markup. Provide a default formatted date as the element's text content (e.g. April 1, 2014). It also MUST have adatetime
attribute set to an ISO 8601 formatted timestamp.
<relative-timedatetime="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.
Property Name | Attribute Name | Possible Values | Default Value |
---|---|---|---|
datetime | datetime | string | - |
format | format | 'datetime'|'relative'|'duration' | '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' |
formatStyle | format-style | 'long'|'short'|'narrow' | * |
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 | ** |
day | day | 'numeric'|'2-digit'|undefined | 'numeric' |
month | month | 'numeric'|'2-digit'|'short'|'long'|'narrow'|undefined | *** |
year | year | 'numeric'|'2-digit'|undefined | **** |
timeZoneName | time-zone-name | 'long'|'short'|'shortOffset'|'longOffset' |'shortGeneric'|'longGeneric'|undefined | undefined |
noTitle | no-title | - | - |
*: If unspecified,formatStyle
will return'narrow'
ifformat
is'elapsed'
or'micro'
,'short'
if the format is'relative'
or'datetime'
, otherwise it will be'long'
.
**: If unspecified,month
will return the same value asformatStyle
wheneverformat
is'datetime'
, otherwise it will be'short'
.
***: If unspecified,weekday
will return the same value asformatStyle
wheneverformat
is'datetime'
, otherwise it will beundefined
.
****: If unspecified,year
will return'numeric'
ifdatetime
represents the same year as the current year. It will returnundefined
if unspecified and ifdatetime
represents a different year to the current year.
This is the datetime that the element is meant to represent. This must be a validISO8601 DateTime. It is also possible to use thedate
property on the element to set the date.el.date
expects aDate
object, whileel.datetime
expects a string. Setting one will override the other.
<relative-timedatetime="2014-04-01T16:30:00-08:00"tense="past"> April 1, 2038<!-- Will display "now" until April 1 2038 at 16:30:01! --></relative-time><script>constel=document.querySelector('relative-time')console.assert(el.date.toISOString()===el.datetime)el.date=newDate()console.assert(el.datetime!=="2014-04-01T16:30:00-08:00")</script>
Format can be either'datetime'
,'relative'
, or'duration'
. It can also be one of several deprecated formats of'auto'
,'micro'
, or'elapsed'
.
The default format isauto
, which is an alias forrelative
. In the next major version this will berelative
.
Thedatetime
format will display a localised datetime, based on the other properties of the element. It usesIntl.DateTimeFormat
to display thedatetime
in a localised format.
Unless specified, it will considerweekday
to be'long'
,month
to be'long'
, and'year'
to benumeric
if thedatetime
is the same as the given year. OverridingformatStyle
will change bothweekday
andmonth
default values. Examples of this format with the default options and anen
locale:
Wed, 26 Aug 2021
Sat, 31 Dec
(assuming thedatetime
is same year as the current year)
The defaultrelative
format will display dates relative to the current time (unless they are past thethreshold
value - see below). The values are rounded to display a single unit, for example if the time between the givendatetime
and the current wall clock time exceeds a day, then the format willonly output in days, and will not display hours, minutes or seconds. Some examples of this format with the default options and anen
locale:
in 20 days
20 days ago
in 1 minute
on 31 Aug
(assuming the current date is the same year as the current year, and is more than 30 days away from 31 Aug)on 26 Aug 2021
(assuming the current date is more than 30 days away from 26 Aug 2021)
Theduration
format will display the time remaining (or elapsed time) from the given datetime, counting down the number of years, months, weeks, days, hours, minutes, and seconds. Any value that is0
will be omitted from the display by default. Examples of this format with the default options and anen
locale:
4 hours, 2 minutes, 30 seconds
4 hours
8 days, 30 minutes, 1 second
This is similar to theformat=duration
, except theformatStyle
defaults tonarrow
. Code that usesformat=elapsed
should migrate toformat=duration formatStyle=narrow
, as it will be removed in a later version.
This is identical toformat=relative
. Code that usesformat=auto
should migrate toformat=relative
as this will be the new default in a later version.
Themicro
format which will display relative dates (within the threshold) in a more compact format. Similar torelative
, themicro
format rounds values to the nearest largest value. Additionally,micro
format will not roundlower than 1 minute, as such adatetime
which is less than a minute from the current wall clock time will display'1m'
.
Code that usesformat=micro
should consider migrating toformat=relative
(perhaps withformatStyle=narrow
), asformat=micro
can be difficult for users to understand, and can cause issues with assistive technologies. For example some screen readers (such as VoiceOver for mac) will read out1m
as1 meter
.
format=datetime | format=relative | format=duration | format=micro | format=elapsed |
---|---|---|---|---|
Wed 26 May 2024 | in 2 years | 2 years, 10 days, 3 hours, 20 minutes, 8 seconds | 2y | 2y 10d 3h 20m 8s |
Wed 26 Aug 2021 | 2 years ago | 2 years, 10 days, 3 hours, 8 seconds | 2y | 2y 10d 3h 8s |
Jan 15 2023 | in 30 days | 30 days, 4 hours, 20 minutes, 8 seconds | 30d | 30d 4h 20m 8s |
Dec 15 2022 | 21 minutes ago | 21 minutes, 30 seconds | 21m | 21m 30s |
Dec 15 2022 | 37 seconds ago | 37 seconds | 1m | 37s |
Ifformat
is'datetime'
then this value will be ignored.
Tense can be used to preventduration
orrelative
formatted dates displaying dates in a tense other than the one specified. Settingtense=past
will always display futurerelative
dates asnow
andduration
dates as0 seconds
, while setting it tofuture
will always display past datesrelative
asnow
and pastduration
dates as0 seconds
.
For example when the givendatetime
is 40 seconds behind of the current date:
tense= | format=duration | format=relative |
---|---|---|
future | 0s | now |
past | 40s | 40s ago |
auto | 40s | 40s ago |
<relative-timedatetime="2038-04-01T16:30:00-08:00"tense="past"> April 1, 2038<!-- Will display "now" until April 1 2038 at 16:30:01! --></relative-time>
<relative-timedatetime="1970-04-01T16:30:00-08:00"tense="future"> April 1, 2038<!-- Will display "now" unless you had a time machine and went back to 1970 --></relative-time>
Ifformat
isdatetime
then this value will be ignored.
Precision can be used to limit the display of anrelative
orduration
formatted time. By default times will display down to thesecond
level of precision. Changing this value will truncate the display by zeroing out any unit lower than the given unit, as such units smaller than the given unit won't be displayed duringduration
, andrelative
will displaynow
if the time away from the current time is less than the given precision unit.
precision= | format=duration |
---|---|
second | 2y 6m 10d 3h 20m 8s |
minute | 2y 6m 10d 3h 20m |
hour | 2y 6m 10d 3h |
day | 2y 6m 10d |
month | 2y 6m |
year | 2y |
precision= | format=relative |
---|---|
second | 25 seconds |
minute | now |
hour | now |
day | now |
month | now |
year | now |
Iftense
is anything other than'auto'
, orformat
is'relative'
(or the deprecated'auto'
or'micro'
values), 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 validISO8601 Time Duration. If the difference between the current time and the specifieddatetime
ismore 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 isP30D
, meaning if the current time is more than 30 days away from the specified date time, then an absolute date will be displayed.
<relative-timedatetime="1970-04-01T16:30:00-08:00"threshold="P100Y"><!-- Will display "<N> years ago" until 2070 when it will display "on April 1, 1970" --></relative-time>
<relative-timedatetime="1970-04-01T16:30:00-08:00"threshold="P0S"><!-- Will always display "on April 1, 1970" --></relative-time>
Iftense
is anything other than'auto'
, orformat
is anything other than'relative'
(or the deprecated'auto'
or'micro'
values), then this value will be ignored.
When formatting an absolute date (see abovethreshold
for more details) it can be useful to prefix the date with some text. The default value for this ison
but it can be any string value, an will be prepended to the date.
<relative-timedatetime="1970-04-01T16:30:00-08:00"prefix="this happened on"><!-- Will always display "this happened on April 1, 1970" --></relative-time>
This will used to determine the length of the unit names. This value is passed to theIntl
objects as thestyle
option. Some examples of how this can be used:
format= | formatStyle= | Display |
---|---|---|
relative | long | in 1 month |
relative | short | in 1 mo. |
relative | narrow | in 1 mo. |
duration | long | 1 month, 2 days, 4 hours |
duration | short | 1 mth, 2 days, 4 hr |
duration | narrow | 1m 2d 4h |
For dates outside of the specifiedthreshold
, the formatting of the date can be configured using these attributes. The values for these attributes are passed toIntl.DateTimeFormat:
Lang is abuilt-in global attribute. Relative Time will use this to provide an applicable language to theIntl
APIs. If the individual element does not have alang
attribute then it will traverse upwards in the tree to find the closest element that does, or default the lang toen
.
Adding theno-title
attribute will remove thetitle
attribute from the<relative-time>
element. Thetitle
attribute is inaccessible to screen reader and keyboard users, so not adding a title attribute allows a user to create a custom, accessible tooltip if one is desired.
Browsers without nativecustom element support require apolyfill.
Browsers without native support forIntl.RelativeTimeFormat
orIntl.DateTimeFormat
(such as Safari 13 or Edge 18) will also need polyfills.
- Chrome
- Firefox
- Safari (version 14 and above)
- Microsoft Edge (version 79 and above)
Most of this implementation is based on Basecamp'slocal_time component. Thanks to @javan for open sourcing that work and allowing for others to build on top of it.
@rmm5t'sjquery-timeago is one of the old time-ago-in-words JS plugins.
About
Web component extensions to the standard <time> element.
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.