Skip to content

feat(datetime): add format_distance_to_now function #6615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion datetime/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"./format": "./format.ts",
"./is-leap": "./is_leap.ts",
"./parse": "./parse.ts",
"./week-of-year": "./week_of_year.ts"
"./week-of-year": "./week_of_year.ts",
"./format-distance-to-now": "./format_distance_to_now.ts"
}
}
42 changes: 42 additions & 0 deletions datetime/format_distance_to_now.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2018-2025 the Deno authors. MIT license.
import { difference } from "./difference.ts";

/**
* Formats a given date as a relative time string (e.g., "3 minutes ago").
*
* @param date - The date to compare with the current time.
* @returns A string representing the relative time difference.
* @example Basic usage
* ```ts
* import { format-distance-to-now } from "@std/datetime/format-distance-to-now";
* import { assertEquals } from "@std/assert";
*
* const now = new Date();
* const past = new Date(now.getTime() - 2 * 60 * 60 * 1000); // 2 hours ago
* const result = formatDistanceToNow(past);
*
* assertEquals(result, "2 hours ago");
* ```
*/
export function formatDistanceToNow(date: Date): string {
const now = new Date();
const diff = difference(date, now);

if (diff.years && diff.years > 0) {
return `${diff.years} year${diff.years === 1 ? "" : "s"} ago`;
} else if (diff.months && diff.months > 0) {
return `${diff.months} month${diff.months === 1 ? "" : "s"} ago`;
} else if (diff.weeks && diff.weeks > 0) {
return `${diff.weeks} week${diff.weeks === 1 ? "" : "s"} ago`;
} else if (diff.days && diff.days > 0) {
return `${diff.days} day${diff.days === 1 ? "" : "s"} ago`;
} else if (diff.hours && diff.hours > 0) {
return `${diff.hours} hour${diff.hours === 1 ? "" : "s"} ago`;
} else if (diff.minutes && diff.minutes > 0) {
return `${diff.minutes} minute${diff.minutes === 1 ? "" : "s"} ago`;
} else if (diff.seconds && diff.seconds > 0) {
return `${diff.seconds} second${diff.seconds === 1 ? "" : "s"} ago`;
} else {
return "just now";
}
}
103 changes: 103 additions & 0 deletions datetime/format_distance_to_now_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2018-2025 the Deno authors. MIT license.
import { assertEquals } from "jsr:@std/assert";
import { formatDistanceToNow } from "./format_distance_to_now.ts";

Deno.test("formats seconds ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 30 * 1000); // 30 seconds ago
const result = formatDistanceToNow(past);
assertEquals(result, "30 seconds ago");
});

Deno.test("formats seconds ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 1 * 1000); // 1 seconds ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 second ago");
});

Deno.test("formats minute ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 1 * 60 * 1000); // 1 minute ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 minute ago");
});

Deno.test("formats minutes ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 5 * 60 * 1000); // 5 minutes ago
const result = formatDistanceToNow(past);
assertEquals(result, "5 minutes ago");
});

Deno.test("formats hour ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 1 * 60 * 60 * 1000); // 1 hour ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 hour ago");
});

Deno.test("formats hours ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 2 * 60 * 60 * 1000); // 2 hours ago
const result = formatDistanceToNow(past);
assertEquals(result, "2 hours ago");
});

Deno.test("formats day ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 1 * 24 * 60 * 60 * 1000); // 1 day ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 day ago");
});

Deno.test("formats days ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 3 * 24 * 60 * 60 * 1000); // 3 days ago
const result = formatDistanceToNow(past);
assertEquals(result, "3 days ago");
});

Deno.test("formats week ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 1 * 7 * 24 * 60 * 60 * 1000); // 1 week ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 week ago");
});

Deno.test("formats weeks ago", () => {
const now = new Date();
const past = new Date(now.getTime() - 2 * 7 * 24 * 60 * 60 * 1000); // 2 weeks ago
const result = formatDistanceToNow(past);
assertEquals(result, "2 weeks ago");
});

Deno.test("formats months ago", () => {
const now = new Date();
const past = new Date(now);
past.setMonth(now.getMonth() - 1); // 1 month ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 month ago");
});

Deno.test("formats year ago", () => {
const now = new Date();
const past = new Date(now);
past.setFullYear(now.getFullYear() - 1); // 1 year ago
const result = formatDistanceToNow(past);
assertEquals(result, "1 year ago");
});

Deno.test("formats years ago", () => {
const now = new Date();
const past = new Date(now);
past.setFullYear(now.getFullYear() - 2); // 2 years ago
const result = formatDistanceToNow(past);
assertEquals(result, "2 years ago");
});

Deno.test("formats just now", () => {
const now = new Date();
const result = formatDistanceToNow(now);
assertEquals(result, "just now");
});
Loading