Calculate the number of weeks and days between now and any other date. Figure out how many weeks have passed since a specific date, or the number of weeks left before something happens in the future.
export const take = [
{ type: "date" },
{
type: "dropdown",
label: "Week starts",
options: [
{ value: 0, label: "Sunday" },
{ value: 1, label: "Monday" },
{ value: 2, label: "Tuesday" },
{ value: 3, label: "Wednesday" },
{ value: 4, label: "Thursday" },
{ value: 5, label: "Friday" },
{ value: 6, label: "Saturday" },
],
},
]
export const make = ([target, offset]) => {
if (!target) return
const day = 1000 * 60 * 60 * 24
const now = Date.now()
const current = new Date(now - (now % day))
const delta = Math.floor((target - current) / day)
const major = Math.floor(Math.abs(delta / 7))
const minor = Math.abs(delta % 7)
const weeks = Math.floor((delta + ((current.getDay() + 7 - offset) % 7)) / 7)
const formatNumber = new Intl.NumberFormat().format
const formatDate = new Intl.DateTimeFormat(undefined, {
year: "numeric",
day: "numeric",
month: "long",
weekday: "long",
era: target.getFullYear() < 1200 ? "short" : undefined,
}).format
const majCount = (n) =>
n > 0 ? `${formatNumber(n)} ${n > 1 ? "weeks" : "week"}` : ""
const minCount = (n) =>
n > 0 ? `${formatNumber(n)} ${n > 1 ? "days" : "day"}` : ""
let value
let detail = formatDate(target)
if (weeks === 0) {
value = "This week"
} else if (weeks === 1) {
value = "Next week"
} else if (weeks === -1) {
value = "Last week"
} else if (weeks > 0) {
value = `${majCount(major)} left`
} else {
value = `${majCount(major)} ago`
}
if (delta === 0) {
detail += " is today!"
} else if (delta === 1) {
detail += " is tomorrow."
} else if (delta === -1) {
detail += " was yesterday."
} else {
const count = [majCount(major), minCount(minor)]
.filter((f) => f)
.join(" and ")
detail += delta > 0 ? ` is in ${count}.` : ` was ${count} ago.`
}
return {
type: "card",
value,
detail,
}
}