The isPast function checks whether a given date is in the past relative to the current time. It provides a simple and reliable way to determine if a date or timestamp occurred before the present moment, with millisecond precision.
function isPast(date: DateInput): boolean;
| Parameter | Type | Description |
|---|---|---|
date |
DateInput |
A Date object, numeric timestamp, or ISO 8601 string to check against the current time |
| Type | Description |
|---|---|
boolean |
Returns true if the date is strictly in the past, false otherwise |
The isPast function determines whether the provided Date object or timestamp represents a time that occurred before the current moment. It uses the internal compareDateTimes helper to perform precise comparison at millisecond granularity, ensuring consistent behavior across the Chronia library.
The function captures the current time using Date.now() at the moment of invocation and compares the provided date against it. The comparison is strict, meaning that if the date equals the current time (same millisecond), it returns false because the date is in the present, not the past.
true when:Date.now()false when:Date.now())Date.now()new Date('invalid'))NaNInfinity-Infinityfalse insteadfalseDate.now()compareDateTimes helperDate | number type, but runtime handles invalid types gracefullyimport { isPast } from "chronia";
interface Session {
token: string;
expiresAt: Date;
}
function isSessionExpired(session: Session): boolean {
return isPast(session.expiresAt);
}
// Check session validity
const session = {
token: "abc123",
expiresAt: new Date("2025-01-14T12:00:00Z"),
};
// If current time is 2025-01-15T12:00:00Z
isSessionExpired(session); // Returns: true (session expired yesterday)
// Using timestamp
const tokenExpiry = Date.now() - 3600000; // 1 hour ago
isPast(tokenExpiry); // Returns: true
import { isPast } from "chronia";
interface Event {
id: string;
title: string;
date: Date;
}
function filterPastEvents(events: Event[]): Event[] {
return events.filter((event) => isPast(event.date));
}
function filterUpcomingEvents(events: Event[]): Event[] {
return events.filter((event) => !isPast(event.date));
}
const events: Event[] = [
{ id: "1", title: "Conference", date: new Date("2025-01-10") },
{ id: "2", title: "Webinar", date: new Date("2025-01-20") },
{ id: "3", title: "Workshop", date: new Date("2025-01-05") },
];
// If current time is 2025-01-15
const pastEvents = filterPastEvents(events);
// Returns: [
// { id: '1', title: 'Conference', date: ... },
// { id: '3', title: 'Workshop', date: ... }
// ]
const upcomingEvents = filterUpcomingEvents(events);
// Returns: [{ id: '2', title: 'Webinar', date: ... }]
import { isPast } from "chronia";
interface Task {
id: string;
title: string;
dueDate: Date;
completed: boolean;
}
function isTaskOverdue(task: Task): boolean {
return !task.completed && isPast(task.dueDate);
}
function getOverdueTasks(tasks: Task[]): Task[] {
return tasks.filter(isTaskOverdue);
}
const tasks: Task[] = [
{
id: "1",
title: "Review PR",
dueDate: new Date("2025-01-14"),
completed: false,
},
{
id: "2",
title: "Write docs",
dueDate: new Date("2025-01-20"),
completed: false,
},
{
id: "3",
title: "Fix bug",
dueDate: new Date("2025-01-10"),
completed: true,
},
];
// If current time is 2025-01-15
const overdue = getOverdueTasks(tasks);
// Returns: [{ id: '1', title: 'Review PR', ... }]
// Task 3 is not overdue because it's completed
// Task 2 is not overdue because deadline hasn't passed
import { isPast } from "chronia";
interface Record {
id: string;
data: unknown;
expiresAt: Date;
}
function shouldArchiveRecord(record: Record): boolean {
// Archive if expiration date has passed
return isPast(record.expiresAt);
}
function partitionRecords(records: Record[]): {
active: Record[];
archived: Record[];
} {
const active: Record[] = [];
const archived: Record[] = [];
for (const record of records) {
if (shouldArchiveRecord(record)) {
archived.push(record);
} else {
active.push(record);
}
}
return { active, archived };
}
// Example usage
const records: Record[] = [
{ id: "1", data: { value: "A" }, expiresAt: new Date("2025-01-10") },
{ id: "2", data: { value: "B" }, expiresAt: new Date("2025-01-20") },
];
// If current time is 2025-01-15
const { active, archived } = partitionRecords(records);
// active: [{ id: '2', ... }]
// archived: [{ id: '1', ... }]
import { isPast } from "chronia";
function isAdult(birthDate: Date): boolean {
// Calculate date 18 years ago from today
const eighteenYearsAgo = new Date();
eighteenYearsAgo.setFullYear(eighteenYearsAgo.getFullYear() - 18);
// Person is adult if birth date is before 18 years ago
return isPast(eighteenYearsAgo)
? birthDate.getTime() <= eighteenYearsAgo.getTime()
: false;
}
function canRegister(birthDate: Date | string): {
allowed: boolean;
reason: string;
} {
// Parse if string provided
const date = typeof birthDate === "string" ? new Date(birthDate) : birthDate;
// Validate date
if (!isPast(date)) {
return {
allowed: false,
reason: "Birth date cannot be in the future or present",
};
}
// Check age requirement
if (!isAdult(date)) {
return { allowed: false, reason: "Must be 18 years or older to register" };
}
return { allowed: true, reason: "Eligible" };
}
// Valid birth date in the past
canRegister(new Date("2000-01-01"));
// Returns: { allowed: true, reason: 'Eligible' }
// Future date (invalid)
canRegister(new Date("2030-01-01"));
// Returns: { allowed: false, reason: 'Birth date cannot be in the future or present' }
// Too young
canRegister(new Date("2020-01-01"));
// Returns: { allowed: false, reason: 'Must be 18 years or older to register' }
import { isPast } from "chronia";
type EventStatus = "completed" | "in-progress" | "upcoming";
interface ScheduledEvent {
title: string;
startTime: Date;
endTime: Date;
}
function getEventStatus(event: ScheduledEvent): EventStatus {
const now = Date.now();
if (isPast(event.endTime)) {
return "completed";
}
if (isPast(event.startTime)) {
return "in-progress";
}
return "upcoming";
}
function getStatusColor(status: EventStatus): string {
switch (status) {
case "completed":
return "gray";
case "in-progress":
return "green";
case "upcoming":
return "blue";
}
}
// Example usage
const meeting: ScheduledEvent = {
title: "Team Standup",
startTime: new Date("2025-01-15T10:00:00Z"),
endTime: new Date("2025-01-15T10:30:00Z"),
};
// If current time is 2025-01-15T10:15:00Z
const status = getEventStatus(meeting); // Returns: 'in-progress'
const color = getStatusColor(status); // Returns: 'green'
// If current time is 2025-01-15T11:00:00Z
const statusLater = getEventStatus(meeting); // Returns: 'completed'
const colorLater = getStatusColor(statusLater); // Returns: 'gray'
import { isPast } from "chronia";
// Invalid Date - returns false instead of throwing
isPast(new Date("invalid")); // Returns: false
// NaN timestamp - handled gracefully
isPast(NaN); // Returns: false
// Infinity - handled gracefully
isPast(Infinity); // Returns: false
isPast(-Infinity); // Returns: false
// Current moment - returns false (not in the past)
isPast(Date.now()); // Returns: false
// 1 millisecond ago - returns true
isPast(Date.now() - 1); // Returns: true
// 1 millisecond in future - returns false
isPast(Date.now() + 1); // Returns: false
// Defensive usage with validation
function processExpiredData(expiryDate: Date | number): void {
if (isPast(expiryDate)) {
console.log("Data has expired, archiving...");
// Safe to proceed - we know it's past
} else {
console.log("Data is still valid");
}
}
// Even with invalid input, no exceptions thrown
processExpiredData(new Date("malformed")); // Logs: 'Data is still valid'
processExpiredData(NaN); // Logs: 'Data is still valid'