Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

timeSinceUntil

Returns the time difference between two dates in absolute or directional mode. If since is true, it returns time elapsed from the past date to now. If since is false, it returns time remaining from now to a future date.

TypeScript
Copied!
1/**
2 * Returns the time difference between two dates in absolute or directional mode.
3 * If `since` is true, it returns time elapsed from the past date to now.
4 * If `since` is false, it returns time remaining from now to a future date.
5 *
6 * If the direction doesn't match the dates, returns all zeros.
7 *
8 * @param date - The target date for comparison.
9 * @param since - Whether to measure time since or until the date.
10 * @returns An object with time components (days, hours, etc.).
11 */
12export function timeSinceUntil(
13  date: Date,
14  since: boolean
15): {
16  days: number;
17  hours: number;
18  minutes: number;
19  seconds: number;
20  milliseconds: number;
21} {
22  const now = new Date();
23  const diff = (since ? now.getTime() - date.getTime() : date.getTime() - now.getTime());
24
25  if (diff <= 0) {
26    return { days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 };
27  }
28
29  const msInSecond = 1000;
30  const msInMinute = msInSecond * 60;
31  const msInHour = msInMinute * 60;
32  const msInDay = msInHour * 24;
33
34  let remaining = diff;
35
36  const days = Math.floor(remaining / msInDay);
37  remaining %= msInDay;
38
39  const hours = Math.floor(remaining / msInHour);
40  remaining %= msInHour;
41
42  const minutes = Math.floor(remaining / msInMinute);
43  remaining %= msInMinute;
44
45  const seconds = Math.floor(remaining / msInSecond);
46  const milliseconds = remaining % msInSecond;
47
48  return { days, hours, minutes, seconds, milliseconds };
49}
  • Bidirectional Support

    Handles both "time since" and "time until" modes with a single flag, making the function flexible for various temporal comparisons.

  • Comprehensive Output

    Returns detailed breakdowns into days, hours, minutes, seconds, and milliseconds, suitable for both display and logic.

  • Zero-Safe Output

    Automatically returns all-zero fields if the time direction is invalid or the event is in the past/future as applicable — reducing edge-case bugs.

  • Readable and Self-Contained

    Uses clear constants and modular logic for converting milliseconds into time units, improving readability and maintainability.

Tests | Examples

TypeScript
Copied!
1test('timeSinceUntil - time since 1d 2h 30m 20s 500ms ago', () => {
2  const now = new Date();
3  const past = new Date(now.getTime() -
4    1 * 24 * 60 * 60 * 1000 -    // 1 day
5    2 * 60 * 60 * 1000 -         // 2 hours
6    30 * 60 * 1000 -             // 30 minutes
7    20 * 1000 -                  // 20 seconds
8    500                         // 500 ms
9  );
10
11  const result = timeSinceUntil(past, true);
12
13  expect(result.days).toBe(1);
14  expect(result.hours).toBe(2);
15  expect(result.minutes).toBe(30);
16  expect(result.seconds).toBe(20);
17  expect(result.milliseconds).toBeGreaterThanOrEqual(490);
18  expect(result.milliseconds).toBeLessThanOrEqual(510);
19});
20
21test('timeSinceUntil - future date with "since" returns all zeros', () => {
22  const future = new Date(Date.now() + 5000);
23  expect(timeSinceUntil(future, true)).toEqual({
24    days: 0,
25    hours: 0,
26    minutes: 0,
27    seconds: 0,
28    milliseconds: 0,
29  });
30});
31
32test('timeSinceUntil - time until 1h 5m 20s 300ms from now', () => {
33  const future = new Date(Date.now() +
34    1 * 60 * 60 * 1000 +         // 1 hour
35    5 * 60 * 1000 +              // 5 minutes
36    20 * 1000 +                  // 20 seconds
37    300                         // 300 ms
38  );
39
40  const result = timeSinceUntil(future, false);
41
42  expect(result.days).toBe(0);
43  expect(result.hours).toBe(1);
44  expect(result.minutes).toBe(5);
45  expect(result.seconds).toBe(20);
46  expect(result.milliseconds).toBeGreaterThanOrEqual(290);
47  expect(result.milliseconds).toBeLessThanOrEqual(310);
48});

Common Use Cases

  • Countdown Timers

    Display how much time is left until an event (e.g. deadlines, launches, reminders).

  • Elapsed Time Display

    Show how long ago something occurred (e.g. "last synced 3 hours ago").

  • Session or Trial Tracking

    Calculate time remaining in sessions or trials to determine usage limits or expiration.

  • Event Progress Dashboards

    Power time-based UI elements showing progression toward or since milestones.

  • Animation or Transition Timing

    Use granular time breakdowns to trigger UI updates or timed transitions.

Codebase: Utilities -> Dates -> timeSinceUntil | Yevhen Klymentiev