Get a valid datetime
attribute for HTML <time>
(among others).
The whole datetime
specification is covered in 4 functions:
datetime()
for a specific moment (561 B);datetimeTz()
for a specific moment in a given timezone (840 B);duration()
for a duration (335 B);tzOffset()
for a timezone offset (378 B).
Additionally, a DateTime
class and some other functions are provided.
The package is lightweight (~ 1.2 KB compressed for import *
), tree-shakeable and include types.
- Summary usage
- Installation
- Usage
datetime()
to express a moment at different levels of precision:- date
- time and UTC time
- datetime and UTC datetime
- alternative to the UTC syntax with
utc()
tzOffset()
to express a timezone offsetdatetimeTz()
to express a moment with a specific timezone offsetduration()
to expressing a duration
- Other functions
daysBetween
to get the number of days between two datesweekNumber
to get the week number (in the year) of a date
- The
DateTime
class - Various:
import * from 'datetime-attribute'
const now = new Date()
datetime(now) // '2021-03-14'
datetime(now, 'time') // '10:29'
datetimeTz(now, 'datetime', -7) // '2021-03-14T10:29-07:00'
utc(now, 'time') // '09:29Z'
tzOffset(-9, 30) // '-09:30' (Marquesas Islands)
duration({ d: 4, h: 3, m: 17 }) // 'P4DT3H17M'
const importantMeeting = new DateTime(2021, 12, 17, 19, 00) // 17/11
const meetingWeek = importantMeeting.getWeek() // 46
importantMeeting.setWeek(meetingWeek + 1) // meeting now on 24/11
importantMeeting.to('week') // 2021W47
importantMeeting.to('datetime') // 2021-11-24T19:00
daysBetween(now, importantMeeting) // 248
Install the package:
npm install datetime-attribute
Then, import the functions you need in your script:
// if you only need `datetime` and `duration`
import { datetime, duration } from 'datetime-attribute'
// if you need everything
import * from 'datetime-attribute'
Not a NPM user? Download the package files in your project.
datetime()
accepts two optional arguments: a Date object, and a precision keywords.
import { datetime } from 'datetime-attribute'
const now = new Date() // We’re 14 March 2021 and it’s 10:29 in Brussels.
datetime(now) // '2021-03-14'
datetime(now, 'datetime') // '2021-03-14T10:29'
Without argument, it defaults to today:
datetime() // today formatted in YYYY-mm-dd
datetime((new Date()), 'day') // same
By default, datetime()
precision is day
, resulting in a YYYY-mm-dd
output. Many other values are available.
precision | example output | description |
---|---|---|
day |
2021-03-14 |
the default, fitting a calendar |
year |
2021 |
only the year |
yearless |
03-14 |
a day in a month |
month |
2021-03 |
a month in a year |
week |
2021W10 |
the week number (ISO-8601 spec) and its year |
Time:
precision | example output | description |
---|---|---|
time |
10:29 |
hours and minutes, like most clocks |
second |
10:29:00 |
time with precision up to seconds |
ms |
10:29:00.000 |
time with precision up to milliseconds |
To get UTC time, add utc
to the time keyword:
precision | example output | description |
---|---|---|
time utc |
09:29Z |
time , shifted to UTC time |
second utc |
09:29:00Z |
second , shifted to UTC time |
ms utc |
09:29:00.000Z |
ms , shifted to UTC time |
Datetime:
precision | example output | description |
---|---|---|
datetime |
2021-03-14T10:29 |
a local datetime (= date + time separated by T ) |
datetime second |
2021-03-14T10:29:00 |
time with precision up to seconds |
datetime ms |
2021-03-14T10:29:00.000 |
time with precision up to milliseconds |
To get UTC datetime, add utc
to the datetime keyword:
precision | example output | description |
---|---|---|
datetime utc |
2021-03-14T09:29Z |
datetime , shifted to UTC time |
datetime second utc |
2021-03-14T09:29:00Z |
datetime second , shifted to UTC time |
datetime ms utc |
2021-03-14T09:29:00.000Z |
datetime ms , shifted to UTC time |
💡 Instead of adding utc
to a time or datetime keyword, you can use utc(date, precision)
, which has datetime
as default precision:
import { datetime, utc } from 'datetime-attribute'
const now = new Date() // We’re 14 March 2021 and it’s 10:29 in Brussels.
// These are the same:
utc(now, 'time') // `09:29Z`
datetime(now, 'time utc') // `09:29Z`
// These are the same:
utc(now) // `2021-03-14T09:29Z`
utc(now, 'datetime') // `2021-03-14T09:29Z`
datetime(now, 'datetime utc') // `2021-03-14T09:29Z`
Timezone offsets are a comparison against UTC time. For example, +01:00
means “one hour ahead of UTC time” and -05:00
means “five hours behind UTC time”.
tzOffset()
accepts three optional arguments for hours, minutes, and compliance to real-life boundaries. Without argument, the local timezone offset is returned (and may differ based on daylight saving time).
import { tzOffset } from 'datetime-attribute'
tzOffset(3) // '+03:00' (Moscow)
tzOffset(-9, 30) // '-09:30' (Marquesas Islands)
tzOffset(-9.5) // '-09:30' (same with 1 parameter)
tzOffset(0) // 'Z' (Ghana; 'Z' is equal to '+00:00')
// in Belgium
tzOffset() // '+01:00'
tzOffset() // '+02:00' (under daylight time saving)
The timezone offset will be adjusted to fit in the spec range (from -23:59
to +23:59
). This means tzOffset(44)
will output +20:00
instead of +44:00
.
However, timezone offsets of countries in the world are all between -12:00
and +14:00
. If you want tzOffset(44)
to output -04:00
so that it matches real-life boundaries, give it a third parameter (default: false
):
tzOffset(44) // '+20:00'
tzOffset(44, 0, true) // '-04:00'
Curious about timezones? Have a look at the timezone map and the daylight time saving chaos.
As datetime()
doesn’t care about timezones, you can use datetimeTz()
when you need to be explicit about the timezone of a moment.
💡 datetimeTz()
is basically a concatenation of datetime(date, precision)
and tzOffset(hours, minutes)
, so be sure to read about them.
It accepts the same 5 parameters, all optional:
datetimeTz(date, precision, offsetHours, offsetMinutes, inRealLifeBoundaries)
- A date object (default:
new Date()
) - A precision keywords among:
time
second
ms
datetime
(default)datetime second
datetime ms
- Hours offset like in
tzOffset()
- Minutes offset like in
tzOffset()
- Boundaries of the timezone offset like in
tzOffset()
When hours and minutes are not specified, the local timezone offset is used.
import { datetime, datetimeTz } from 'datetime-attribute'
const now = new Date() // We’re 2 April 2021 and it’s 23:51 in Brussels.
datetime(now) // '2021-04-02'
datetimeTz(now) // '2021-04-02T23:51+02:00'
datetime(now, 'time') // '23:51'
datetime(now, 'time utc') // '21:51Z' (same as previous, converted to UTC)
datetimeTz(now, 'time', 0) // '23:51Z' (datetimeTz does not convert)
datetimeTz(now, 'time') // '23:51+02:00' (fall back on local timezone)
datetimeTz(now, 'time', 9) // '23:51+09:00'
datetimeTz(now, 'time', -3, 30) // '23:51-03:30'
datetimeTz(now, 'time', -14, 0, true) // '23:51+10:00'
datetimeTz()
does not convert your moment to another timezone: it only adds the wanted timezone to the moment. Its purpose is to generate a valid datetime
attribute saying “here’s a moment, it has this [hours, minutes] timezone offset”.
Let’s take this sentence and its HTML:
When I’m in Brussels, I wake up at 8 o’clock every day.
<p>When I’m in Brussels, I wake up <time datetime="08:00+02:00">at 8 o’clock</time> every day.</p>
Here’s how you can get the datetime
attribute fitting this sentence:
// const awakeningAt = new Date(…) // a Date object with 08:00 as time
datetimeTz(awakeningAt, 'time', 2) // '08:00+02:00'
duration()
requires an object with entries for different levels of durations, from seconds to weeks. It also accepts a second parameter to control the conversion of units overflow (default: true
).
import { duration } from 'datetime-attribute'
const countdownBeforeBigParty = {
w: 3, // 3 weeks
d: 5, // 5 days
h: 10, // 10 hours
m: 43, // 43 minutes
s: 2.61 // 2.610 seconds
}
duration(countdownBeforeBigParty) // 'P3W5DT10H43M2'
All object keys are optional:
duration({ h: 17 }) // 'PT17H'
Values exceeding a unit are converted to upper units:
duration({ h: 31, m: 63, s: 175 }) // 'P1DT8H5M55S'
If you don’t need this behaviour, pass false
as second parameter (default valut: true
).
duration({ m: 175 }) // 'PT2H55M'
duration({ m: 175 }, false) // 'PT175M'
Under the hood, the core features of datetime-attribute
uses additional functions that you can also import
individually.
Calculate the difference between 2 dates in days, discarding the time of day. It subtracts the first Date
object from the second one.
import { daysBetween } from 'datetime-attribute'
const january1st = new Date(2021, 0, 1, 10, 10, 12)
const january11th = new Date(2021, 0, 11, 10, 10, 12)
const january19th = new Date(2021, 0, 19, 10, 10, 12)
daysBetween(january1st, january11th) // 10
daysBetween(january19th, january11th) // -8
Get the week number as defined by the WHATWG, following the ISO-8601 specs:
- a week starts on Monday;
- the first week of the year includes a Thursday;
- week numbers go from 1 to 53.
It accepts a Date
object.
import { weekNumber } from 'datetime-attribute'
const january1st = new Date(2021, 0, 1, 10, 10, 12)
const january11th = new Date(2021, 0, 11, 10, 10, 12)
const togoIndependanceDay = new Date(1960, 3, 27)
weekNumber(togoIndependanceDay) // 17
weekNumber(january1st) // 53: it’s a Friday!
weekNumber(january11th) // 2
The DateTime
class extends the native Date
object with methods allowing you to interact with the week number or to output a datetime
string.
Its constructor remains the same as the Date
one.
import { DateTime } from 'datetime-attribute'
// One of the many ways to instantiate a `Date`, and this `DateTime`.
const summer = new DateTime(2021, 5, 21) // June 21, 2021
Returns the week of the year, giving the same output as weekNumber()
.
const summer = new DateTime(2021, 5, 21) // June 21, 2021
summer.getWeek() // 25
Shifts the date to the provided week, while preserving its initial day. In other words, if the initial date is a Friday, then the shifted date remains a Friday.
const summer = new DateTime(2021, 5, 21) // June 21, 2021
summer.setWeek(26) // shifts the date to June 28, 2021
summer.getWeek() // now it’s 26
Returns a datetime
attribute. DateTime.to()
accepts the same precision
keywords as datetime()
.
const summer = new DateTime(2021, 5, 21) // June 21, 2021
summer.to('month') // 2021-06
summer.to('yearless') // 06-21
summer.to('datetime second') // 2021-06-21T00:00:00
See CHANGELOG.md or the releases.
datetime-attribute
is provided for modern browsers usage with standard JavaScript syntax:
- it is up to you to transpile it for legacy browsers;
- you can’t import it using
require('datetime-attribute')
.
If you’d like one of those features, feel free to open an issue and/or a PR that won’t have any side effects for modern usage. Read more about ESModules.
<time>
is not alone! Other elements can benefit from datetime-attribute
:
<input>
of the following types:date
,datetime-local
,month
,week
,time
: check theirmin
,max
,value
,datalist
attributes.<del>
and<ins>
accept adatetime
attribute.- Microdata types: DateTime and Time properties.
- Open Graph dates properties:
release_date
,published_time
,modified_time
andexpiration_time
. - The browser WebExtensions history search API.
The datetime-attribute package is open-sourced software licensed under the DWTFYWTPL.