// const add = require('date-fns/add')
const examples = [{
start: '2023-10-29T03:00:00.000Z',
delta: {
hours: 0
},
utc: '2023-10-29T03:00:00.000Z',
},
{
start: '2023-10-29T03:00:00.000Z',
delta: {
hours: -1
},
utc: '2023-10-29T02:00:00.000Z',
},
{
start: '2023-10-29T03:00:00.000Z',
delta: {
hours: -2
},
utc: '2023-10-29T01:00:00.000Z',
},
{
start: '2023-10-29T03:00:00.000Z',
delta: {
hours: -3
},
utc: '2023-10-29T00:00:00.000Z',
},
{
start: '2023-10-29T03:00:00.000Z',
delta: {
hours: -4
},
utc: '2023-10-28T23:00:00.000Z',
},
{
start: '2023-11-13T10:59:13.371Z',
delta: {
days: -15,
hours: -4
},
utc: '2023-10-29T06:59:13.371Z',
},
{
start: '2023-11-13T10:59:13.371Z',
delta: {
days: -16
},
utc: '2023-10-28T10:59:13.371Z',
},
{
start: '2023-11-13T10:59:13.371Z',
delta: {
days: -16,
hours: -4
},
utc: '2023-10-28T06:59:13.371Z',
},
{
start: '2023-11-13T10:59:13.371Z',
delta: {
hours: -(16 * 24 + 4)
},
utc: '2023-10-28T06:59:13.371Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
days: -1
},
utc: '2023-10-29T00:00:00.000Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
days: -2
},
utc: '2023-10-28T00:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
hours: 0
},
utc: '2023-03-26T04:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
hours: -1
},
utc: '2023-03-26T03:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
hours: -2
},
utc: '2023-03-26T02:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
hours: -3
},
utc: '2023-03-26T01:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
days: -1
},
utc: '2023-03-25T04:00:00.000Z',
},
{
start: '2023-03-26T04:00:00.000Z',
delta: {
days: -1,
hours: 1
},
utc: '2023-03-25T05:00:00.000Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-11-29T00:00:00.000Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-10-01T00:00:00.000Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-10-29T00:00:00.000Z',
},
{
start: '2023-10-30T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-10-31T00:00:00.000Z',
},
{
start: '2023-10-29T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-11-28T00:00:00.000Z',
},
{
start: '2023-10-29T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-09-30T00:00:00.000Z',
},
{
start: '2023-10-29T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-10-28T00:00:00.000Z',
},
{
start: '2023-10-29T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-10-30T00:00:00.000Z',
},
{
start: '2023-10-28T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-11-27T00:00:00.000Z',
},
{
start: '2023-10-28T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-09-29T00:00:00.000Z',
},
{
start: '2023-10-28T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-10-27T00:00:00.000Z',
},
{
start: '2023-10-28T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-10-29T00:00:00.000Z',
},
{
start: '2023-03-27T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-04-26T00:00:00.000Z',
},
{
start: '2023-03-27T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-02-28T00:00:00.000Z',
},
{
start: '2023-03-27T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-03-26T00:00:00.000Z',
},
{
start: '2023-03-27T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-03-28T00:00:00.000Z',
},
{
start: '2023-03-26T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-04-25T00:00:00.000Z',
},
{
start: '2023-03-26T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-02-27T00:00:00.000Z',
},
{
start: '2023-03-26T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-03-25T00:00:00.000Z',
},
{
start: '2023-03-26T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-03-27T00:00:00.000Z',
},
{
start: '2023-03-25T00:00:00.000Z',
delta: {
months: 1,
days: -1
},
utc: '2023-04-24T00:00:00.000Z',
},
{
start: '2023-03-25T00:00:00.000Z',
delta: {
months: -1,
days: 1
},
utc: '2023-02-26T00:00:00.000Z',
},
{
start: '2023-03-25T00:00:00.000Z',
delta: {
years: 1,
days: -1
},
utc: '2024-03-24T00:00:00.000Z',
},
{
start: '2023-03-25T00:00:00.000Z',
delta: {
years: -1,
days: 1
},
utc: '2022-03-26T00:00:00.000Z',
},
]
const addDuration = (date, delta) => {
const {
years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0
} = delta
const dateWithCalendarDelta = add(date, {
months,
years,
days,
weeks
})
const tzDelta = date.getTimezoneOffset() - dateWithCalendarDelta.getTimezoneOffset()
return add(dateWithCalendarDelta, {
hours,
minutes: minutes + tzDelta,
seconds
})
}
const main = () => {
console.table(
examples.map(({
start,
delta,
utc
}) => {
const add1 = add(new Date(start), delta)
const ok1 = add1.toISOString() === utc ? '✅' : '❌'
const add2 = addDuration(new Date(start), delta)
const ok2 = add2.toISOString() === utc ? '✅' : '❌'
return {
start: new Date(start),
delta,
utc: new Date(utc),
add1,
ok1,
add2,
ok2
}
document.querySelector('tbody')
}),
)
}
setTimeout(main, 500)
<script type="module">
import { add } from 'https://esm.run/date-fns';
window.add = add;
</script>