chronia

subSeconds

Overview

The subSeconds function subtracts a specified number of seconds from a given date, returning a new Date object. It provides a safe and type-checked way to perform second-level date arithmetic while preserving milliseconds and handling edge cases consistently with Chronia’s validation patterns.

Signature

function subSeconds(date: DateInput, amount: number): Date;

Parameters

Parameter Type Description
date DateInput The base date as a Date object, numeric timestamp, or ISO 8601 string from which to subtract seconds
amount number The number of seconds to subtract (can be negative to add seconds instead)

Return Value

Type Description
Date A new Date object with the specified number of seconds subtracted, or Invalid Date if any input is invalid

Description

The subSeconds function subtracts a specified number of seconds from a date by internally negating the amount and delegating to addSeconds. This ensures consistent behavior and validation across the library. The function validates both the date and amount arguments before processing, returning Invalid Date for any invalid inputs.

Specification

Returns a valid Date when:

Returns Invalid Date when:

Special behaviors:

Behavior Notes

Use Cases

Usage Examples

Time Calculations

import { subSeconds } from "chronia";

// Calculate a time 15 seconds in the past
const now = new Date(2025, 10, 22, 14, 30, 45);
const fifteenSecondsAgo = subSeconds(now, 15);
// Returns: 2025-11-22T14:30:30

// Subtract seconds from a timestamp
const timestamp = 1700000000000; // Numeric timestamp
const earlier = subSeconds(timestamp, 60);
// Returns: Date representing 60 seconds before the timestamp

// Calculate cache expiration (30 seconds ago)
const cacheTime = subSeconds(new Date(), 30);
// Returns: Date representing 30 seconds before current time

Countdown Timers

import { subSeconds } from "chronia";

// Implement a simple countdown
let countdown = new Date(2025, 10, 22, 12, 0, 0);

function tick() {
  countdown = subSeconds(countdown, 1);
  console.log(countdown);
}

// Session timeout calculation
const sessionStart = new Date();
const sessionDuration = 3600; // 1 hour in seconds
const currentTime = new Date();
const elapsed = Math.floor(
  (currentTime.getTime() - sessionStart.getTime()) / 1000,
);
const timeRemaining = subSeconds(sessionStart, elapsed - sessionDuration);

Crossing Boundaries

import { subSeconds } from "chronia";

// Crossing minute boundary
const time1 = new Date(2025, 10, 22, 12, 31, 15);
const result1 = subSeconds(time1, 30);
// Returns: 2025-11-22T12:30:45

// Crossing hour boundary
const time2 = new Date(2025, 10, 22, 13, 0, 10);
const result2 = subSeconds(time2, 20);
// Returns: 2025-11-22T12:59:50

// Crossing day boundary
const time3 = new Date(2025, 10, 23, 0, 0, 30);
const result3 = subSeconds(time3, 60);
// Returns: 2025-11-22T23:59:30

Negative Amounts (Adding Seconds)

import { subSeconds } from "chronia";

// Using negative amount to add seconds
const base = new Date(2025, 10, 22, 12, 30, 30);
const future = subSeconds(base, -15);
// Returns: 2025-11-22T12:30:45 (15 seconds added)

// Equivalent to addSeconds
import { addSeconds } from "chronia";
const same = addSeconds(base, 15);
// Returns: 2025-11-22T12:30:45 (same result)

Fractional Seconds Handling

import { subSeconds } from "chronia";

// Positive fractional amounts are truncated toward zero
const date1 = new Date(2025, 10, 22, 12, 0, 30);
const result1 = subSeconds(date1, 1.9);
// Returns: 2025-11-22T12:00:29 (1.9 truncated to 1)

const result2 = subSeconds(date1, 1.1);
// Returns: 2025-11-22T12:00:29 (1.1 truncated to 1)

// Negative fractional amounts are also truncated toward zero
const result3 = subSeconds(date1, -1.9);
// Returns: 2025-11-22T12:00:31 (-1.9 truncated to -1, so adds 1 second)

Error Handling

import { subSeconds } from "chronia";

// Invalid date input
const invalid1 = subSeconds(new Date("invalid"), 30);
// Returns: Invalid Date

// Invalid amount (NaN)
const invalid2 = subSeconds(new Date(), NaN);
// Returns: Invalid Date

// Invalid amount (Infinity)
const invalid3 = subSeconds(new Date(), Infinity);
// Returns: Invalid Date

// Validate results before use
function safeSubSeconds(date: Date | number, amount: number): Date | null {
  const result = subSeconds(date, amount);
  return isNaN(result.getTime()) ? null : result;
}

Preserving Milliseconds

import { subSeconds } from "chronia";

// Milliseconds are preserved
const dateWithMs = new Date(2025, 10, 22, 12, 30, 45, 750);
const result = subSeconds(dateWithMs, 10);
// Returns: 2025-11-22T12:30:35.750 (milliseconds preserved)

console.log(result.getMilliseconds()); // 750