Skip to content

useDateCountdown

Counts down towards a future Date. The remaining time is always computed against the real current date, so it never drifts — pausing only freezes the displayed values, and resuming jumps to the actual remaining time. If you need a countdown that "holds" its remaining time while paused, use useNumberCountdown.

Demo

0
Years
0
Months
0
Days
0
Hours
0
Minutes
0
Seconds
0
Milliseconds

Usage

vue
<script setup>
import { useDateCountdown } from "vue-countdown-composable";

const { days, hours, minutes, seconds, isRunning, start, pause, resume, stop } =
  useDateCountdown({
    onFinish: () => console.log("Happy launch day! 🎉"),
  });

// count down towards a future date, updating every second
start(new Date("2040-08-13"));
</script>

<template>
  <div>{{ days }}d {{ hours }}h {{ minutes }}m {{ seconds }}s</div>
</template>

API

Options

useDateCountdown(options?) accepts an optional options object:

NameTypeDescription
onFinish() => voidCalled once when a started countdown reaches zero. Not called on stop() or when start receives a past date.

Returned values

All values are read-only and reactive.

NameTypeDescription
millisecondsComputedRef<number>Remaining milliseconds (0–999)
secondsComputedRef<number>Remaining seconds (0–59)
minutesComputedRef<number>Remaining minutes (0–59)
hoursComputedRef<number>Remaining hours (0–23)
daysComputedRef<number>Remaining days (0–29)
monthsComputedRef<number>Remaining months (0–11), approximated as 30 days
yearsComputedRef<number>Remaining years, approximated as 12 × 30-day months
isRunningReadonly<Ref<boolean>>Whether the countdown is currently ticking

Months and years are approximations

A duration has no calendar context, so months are treated as 30 days and years as 12 of those months.

Methods

NameSignatureDescription
start(date: Date, updateInterval?: number) => voidStart counting down towards date, updating every updateInterval ms (default 1000; invalid values warn and fall back). Calling it again restarts. A date not in the future — or an invalid one — results in a finished (all zeros) countdown.
pause() => voidFreeze the displayed values.
resume() => voidResume a paused countdown. It jumps to the actual remaining time; if the date passed while paused, it finishes at zeros. No-op if already running or stopped.
stop() => voidStop the countdown and reset all values to zero. A stopped countdown cannot be resumed — call start again.

Cleanup

The interval is cleared automatically when the owning component (or effectScope) is disposed — no manual cleanup needed.

Released under the MIT License.