Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b332980
isAfter, isBefore and diffMilliseconds now accept null/undefined to a…
WilcoSp May 11, 2024
d4a18df
Merge branch 'formkit:main' into feature/maybeDateInput
WilcoSp Jul 3, 2024
97172ad
isBefore & isAfter doc change from now -> the current time
WilcoSp Jul 3, 2024
174ceda
all diff* functions now accept optional date arguments
WilcoSp Jul 3, 2024
f19d14d
all add* functions now support optional date argument.
WilcoSp Jul 3, 2024
ab21913
same* now also support optional date arguments
WilcoSp Jul 3, 2024
f394303
nearestDay now accepts optional date input
WilcoSp Jul 10, 2024
33932a1
*end, *start, yearDays, monthDays & dayOfYear now support optional da…
WilcoSp Jul 10, 2024
472155b
offset, removeOffset, tzDate, fill & createPartMap now support option…
WilcoSp Jul 10, 2024
0634095
added isFuture & isPast
WilcoSp Jul 31, 2024
c3c1958
fix sameSecond inputDateA to Maybe
WilcoSp Jul 31, 2024
6ae532a
yearStart inputDate to maybe type
WilcoSp Jul 31, 2024
3724166
export isFuture & isPast
WilcoSp Jul 31, 2024
571561e
jsdoc change for MaybeDateInput to use `current time` instead of `now`
WilcoSp Aug 14, 2024
ce44fb1
created diff function
WilcoSp Aug 14, 2024
856eff2
corrected test o=for current time
WilcoSp Aug 14, 2024
3a0c77c
added add function
WilcoSp Aug 14, 2024
8abf0c1
Merge branch 'formkit:main' into feature/diff
WilcoSp Aug 23, 2024
95dfd25
moving the date over flow handling to a separate function
WilcoSp Sep 18, 2024
f11251f
refactored the handleOverflow to have dateOverflow last
WilcoSp Oct 12, 2024
f682e63
added setMilliseconds/Seconds/Minutes/Hour and their tests
WilcoSp Oct 12, 2024
ef59448
added setDayOfMonth and it's tests
WilcoSp Oct 12, 2024
370c674
adding exports for set* functions
WilcoSp Oct 12, 2024
f7f372e
exporting handleOverflow
WilcoSp Oct 12, 2024
7c899f5
adding jsdoc for handleOverflow
WilcoSp Oct 12, 2024
77e8c58
..
WilcoSp Oct 12, 2024
1118ccd
docs: update documents of API interfaces
ashphy Mar 20, 2025
4e9442f
fix: offset() returns NaN for dates with non 4-digit years
tk1024 Apr 2, 2026
655674f
Merge pull request #82 from tk1024/fix/offset-non-4-digit-year
justin-schroeder May 8, 2026
e2c43b8
Merge pull request #79 from ashphy/update-document-of-api-interfaces
justin-schroeder May 8, 2026
258eb32
Merge pull request #75 from WilcoSp/feature/set
justin-schroeder May 8, 2026
b9159cf
Merge pull request #69 from WilcoSp/feature/diff
justin-schroeder May 8, 2026
30838aa
chore: prepare Tempo 1.1.0 PR updates
justin-schroeder May 8, 2026
bd47809
fix: prevent mixed-sign diff durations
justin-schroeder May 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/components/content/Data.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const fns: Record<
ap: {
name: "ap",
description: "Returns either am or pm but in any given locale.",
return: "Date",
return: "string",
arguments: [
{
name: "amOrPm",
Expand Down Expand Up @@ -80,7 +80,7 @@ const fns: Record<
type: "Date",
},
],
return: "string",
return: "boolean",
},
monthDays: {
name: "month-days",
Expand Down
51 changes: 50 additions & 1 deletion docs/components/content/Helpers.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
<script lang="ts" setup>
import sizes from "../../assets/func-sizes.json"
import type { FunctionRef } from "../../src/types"
import type { FunctionRef, ObjectRef } from "../../src/types"

const durationProperties: ObjectRef["properties"] = [
{ name: "years?", type: "number", jsdoc: ["Years in the duration."] },
{ name: "months?", type: "number", jsdoc: ["Months in the duration."] },
{ name: "weeks?", type: "number", jsdoc: ["Weeks in the duration."] },
{ name: "days?", type: "number", jsdoc: ["Days in the duration."] },
{ name: "hours?", type: "number", jsdoc: ["Hours in the duration."] },
{ name: "minutes?", type: "number", jsdoc: ["Minutes in the duration."] },
{ name: "seconds?", type: "number", jsdoc: ["Seconds in the duration."] },
{ name: "milliseconds?", type: "number", jsdoc: ["Milliseconds in the duration."] },
]

const diffOptionsProperties: ObjectRef["properties"] = [
{
name: "abs?",
type: "boolean",
jsdoc: ["Return absolute values instead of signed values."],
},
{
name: "skip?",
type: "Array<keyof Duration> | Set<keyof Duration>",
jsdoc: ["Units to omit while calculating the duration."],
},
]

const fns: Record<
string,
Expand All @@ -12,6 +36,27 @@ const fns: Record<
tip?: string
}
> = {
diff: {
description:
"Returns the difference between two dates as a duration object. The result can be passed to <code>add</code> or formatted with <code>Intl.DurationFormat</code>.",
return: "Duration",
arguments: [
{
name: "dateA",
type: "string | Date | null",
},
{
name: "dateB",
type: "string | Date",
},
{
name: "options",
type: "DiffOptions",
comment: "abs, skip",
},
],
example: "diff",
},
diffMilliseconds: {
description:
"Returns the number of milliseconds difference between two date objects.",
Expand Down Expand Up @@ -326,6 +371,10 @@ const fns: Record<
:arguments="def.arguments"
:return="def.return"
/>
<template v-if="fn === 'diff'">
<ObjectReference type="Duration" :properties="durationProperties" />
<ObjectReference type="DiffOptions" :properties="diffOptionsProperties" />
</template>
<p v-html="def.description" />
<CodeExample v-if="def.example" :file="def.example" />
<CalloutInfo v-if="def.tip">
Expand Down
172 changes: 171 additions & 1 deletion docs/components/content/Modify.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
<script lang="ts" setup>
import sizes from "../../assets/func-sizes.json"
import type { FunctionRef } from "../../src/types"
import type { FunctionRef, ObjectRef } from "../../src/types"

const durationProperties: ObjectRef["properties"] = [
{ name: "years?", type: "number", jsdoc: ["Years to add."] },
{ name: "months?", type: "number", jsdoc: ["Months to add."] },
{ name: "weeks?", type: "number", jsdoc: ["Weeks to add."] },
{ name: "days?", type: "number", jsdoc: ["Days to add."] },
{ name: "hours?", type: "number", jsdoc: ["Hours to add."] },
{ name: "minutes?", type: "number", jsdoc: ["Minutes to add."] },
{ name: "seconds?", type: "number", jsdoc: ["Seconds to add."] },
{ name: "milliseconds?", type: "number", jsdoc: ["Milliseconds to add."] },
]

const fns: Record<
string,
Expand All @@ -13,6 +24,28 @@ const fns: Record<
tip?: string
}
> = {
add: {
name: "add",
description:
"Returns a new Date object with a duration object applied. To subtract time, use negative values. Month and year overflow behavior matches <code>addMonth</code> and <code>addYear</code>.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "duration",
type: "Duration",
},
{
name: "dateOverflow",
type: "boolean",
comment: "default: false",
},
],
example: "add",
},
addDay: {
name: "add-day",
description:
Expand Down Expand Up @@ -282,6 +315,138 @@ const fns: Record<
},
],
},
setDayOfMonth: {
name: "set-day-of-month",
description:
"Returns a new Date object with the day of the month set. By default, days beyond the end of the month clamp to the last day; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "day",
type: "number",
},
{
name: "dateOverflow",
type: "boolean",
comment: "default: false",
},
],
},
setHour: {
name: "set-hour",
description:
"Returns a new Date object with the hour set. Values outside 0-23 use the native Date overflow behavior.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "hour",
type: "number",
comment: "0-23",
},
],
},
setMilliseconds: {
name: "set-milliseconds",
description:
"Returns a new Date object with the millisecond value set. Values outside 0-999 use the native Date overflow behavior.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "milliseconds",
type: "number",
comment: "0-999",
},
],
},
setMinutes: {
name: "set-minutes",
description:
"Returns a new Date object with the minute set. Values outside 0-59 use the native Date overflow behavior.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "minute",
type: "number",
comment: "0-59",
},
],
},
setMonth: {
name: "set-month",
description:
"Returns a new Date object with the zero-based month set. By default, invalid days clamp to the last day of the target month; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "month",
type: "number",
comment: "0-11, 0 is January",
},
{
name: "dateOverflow",
type: "boolean",
comment: "default: false",
},
],
},
setSeconds: {
name: "set-seconds",
description:
"Returns a new Date object with the second set. Values outside 0-59 use the native Date overflow behavior.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "second",
type: "number",
comment: "0-59",
},
],
},
setYear: {
name: "set-year",
description:
"Returns a new Date object with the year set. By default, invalid leap days clamp to the last day of the target month; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
return: "Date",
arguments: [
{
name: "date",
type: "string | Date | null",
},
{
name: "year",
type: "number",
},
{
name: "dateOverflow",
type: "boolean",
comment: "default: false",
},
],
},
tzDate: {
name: "tz-date",
description: `Converts an ISO 8601 like string into a Date object with a timezone applied. For example, <code>tzDate('2021-01-01T00:00', 'America/Los_Angeles')</code> will return a Date object representing 2021-01-01 00:00 in L.A.`,
Expand Down Expand Up @@ -383,6 +548,11 @@ const fns: Record<
:arguments="def.arguments"
:return="def.return"
/>
<ObjectReference
v-if="fn === 'add'"
type="Duration"
:properties="durationProperties"
/>
<p v-html="def.description" />
<CodeExample v-if="def.example" :file="def.example" />
<CalloutInfo v-if="def.tip">
Expand Down
17 changes: 17 additions & 0 deletions docs/examples/add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { add } from "@formkit/tempo"

// Add multiple units at once
add("2024-01-01 12:00:00", {
years: 1,
months: 3,
days: 15,
hours: 2,
minutes: 8,
seconds: 40,
})

// Subtract 5 weeks
add("2024-02-05", { weeks: -5 })

// Allow month overflow
add("2024-01-30", { months: 1 }, true)
12 changes: 12 additions & 0 deletions docs/examples/diff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { add, diff } from "@formkit/tempo"

// Get a duration object
diff("2025-04-01 12:00:50", "2024-01-01 12:00:00")

// Skip units you do not want in the result
diff("2025-07-01 12:01:00", "2024-01-01 12:00:00", {
skip: ["years", "minutes"],
})

// Apply a duration to another date
add("2024-01-30", diff("2024-03-01", "2024-01-30"))
41 changes: 41 additions & 0 deletions src/__tests__/add.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vitest"
import { add, date, diff } from "../index"

describe("add", () => {
it("adds multiple duration units", () => {
expect(
add("2024-01-01 12:00:00", {
years: 1,
months: 3,
days: 15,
hours: 2,
minutes: 8,
seconds: 40,
})
).toEqual(date("2025-04-16 14:08:40"))
})

it("allows month overflow when requested", () => {
expect(add("2024-01-30", { months: 1 }, true)).toEqual(date("2024-03-01"))
})

it("adds weeks and milliseconds", () => {
expect(add("2024-02-05 10:00:00.250", { weeks: -5, milliseconds: 100 })).toEqual(
date("2024-01-01 10:00:00.350")
)
})

it("round-trips a positive duration returned by diff", () => {
const start = "2024-01-30"
const end = "2024-03-01"

expect(add(start, diff(end, start))).toEqual(date(end))
})

it("round-trips a negative duration returned by diff", () => {
const start = "2024-01-30"
const end = "2024-03-01"

expect(add(end, diff(start, end))).toEqual(date(start))
})
})
Loading
Loading