A utility to convert seconds or a Date object into a human-readable relative time string.
This utility provides a function to transform seconds or Date objects into human-readable relative time strings, such as "3 hours ago" or "2 days from now". It is highly customizable, allowing for various formatting and localization options.
To install the package, you can use any of the commands below:
npx jsr add @blaze/human-readable-timestamp # or yarn dlx jsr add @blaze/human-readable-timestamp # or pnpm dlx jsr add @blaze/human-readable-timestamp # or bunx jsr add @blaze/human-readable-timestamp
import { humanReadableTimestamp } from "@blaze/human-readable-timestamp"; // Example usage with default options const timestamp = humanReadableTimestamp(new Date(Date.now() - 3600 * 1000)); // "1 hour ago" console.log(timestamp);
The humanReadableTimestamp
function accepts two parameters:
input
: A number representing seconds or a Date object.options
: An optional configuration object to customize the output.maxUnits
(number): Maximum number of time units to display. Default is 1.pastSuffix
(string): Suffix for past times. Default is "ago".futureSuffix
(string): Suffix for future times. Default is "from now".localize
(boolean): Whether to localize the output string. Default is false.verbose
(boolean): Whether to use verbose mode (e.g., "about 3 hours"). Default is false.customUnits
(Partial<Record<TimeUnit, string>>): Custom time unit labels.thresholds
(Partial<Record<TimeUnit, number>>): Custom thresholds for switching units.abbreviate
(boolean): Whether to use abbreviated unit labels (e.g., "hr" instead of "hour"). Default is false.customFormatter
(function): Custom function to format the output string.This utility does not have any external dependencies.
The module includes a comprehensive test suite to ensure functionality and reliability.
To run the tests, you will need to have a testing framework installed, such as Deno.
Below are examples of the test cases included in the test suite:
import { assertEquals } from "jsr:@std/assert"; import { describe, it } from "jsr:@std/testing/bdd"; import { humanReadableTimestamp } from "./mod.ts"; describe("humanReadableTimestamp", () => { it("handles basic cases", () => { assertEquals(humanReadableTimestamp(30), "30 seconds ago"); assertEquals(humanReadableTimestamp(60), "1 minute ago"); assertEquals(humanReadableTimestamp(3600), "1 hour ago"); assertEquals(humanReadableTimestamp(86400), "1 day ago"); assertEquals(humanReadableTimestamp(604800), "1 week ago"); assertEquals(humanReadableTimestamp(2592000), "1 month ago"); assertEquals(humanReadableTimestamp(31536000), "1 year ago"); }); it("handles future timestamps", () => { assertEquals(humanReadableTimestamp(-30), "30 seconds from now"); assertEquals(humanReadableTimestamp(-3600), "1 hour from now"); }); it("handles multiple units", () => { assertEquals( humanReadableTimestamp(3661, { maxUnits: 2 }), "1 hour, 1 minute ago" ); assertEquals( humanReadableTimestamp(3661, { maxUnits: 3 }), "1 hour, 1 minute, 1 second ago" ); }); it("respects maxUnits option", () => { assertEquals(humanReadableTimestamp(3661, { maxUnits: 1 }), "1 hour ago"); assertEquals( humanReadableTimestamp(3661, { maxUnits: 2 }), "1 hour, 1 minute ago" ); }); it("handles custom suffixes", () => { assertEquals( humanReadableTimestamp(60, { pastSuffix: "in the past" }), "1 minute in the past" ); assertEquals( humanReadableTimestamp(-60, { futureSuffix: "in the future" }), "1 minute in the future" ); }); it("handles localization", () => { assertEquals( humanReadableTimestamp(1500, { localize: true }), "25 minutes ago" ); // Note: This test might fail in different locales }); it("handles verbose mode", () => { assertEquals( humanReadableTimestamp(60, { verbose: true }), "about 1 minute ago" ); }); it("handles custom units", () => { assertEquals( humanReadableTimestamp(60, { customUnits: { minute: "min" } }), "1 min ago" ); }); it("handles custom thresholds", () => { assertEquals( humanReadableTimestamp(44, { thresholds: { minute: 0.75 } }), "44 seconds ago" ); assertEquals( humanReadableTimestamp(45, { thresholds: { minute: 0.75 } }), "1 minute ago" ); }); it("handles abbreviations", () => { assertEquals( humanReadableTimestamp(3661, { abbreviate: true, maxUnits: 2 }), "1 hr, 1 min ago" ); }); it("handles custom formatter", () => { const customFormatter = (units: string[], suffix: string) => `It's been ${units.join(" and ")} ${suffix}`; assertEquals( humanReadableTimestamp(3661, { maxUnits: 2, customFormatter, }), "It's been 1 hour and 1 minute ago" ); }); it("handles Date objects", () => { const now = new Date(); const oneHourAgo = new Date(now.getTime() - 3600000); assertEquals(humanReadableTimestamp(oneHourAgo), "1 hour ago"); }); it("throws error for invalid input", () => { try { humanReadableTimestamp("invalid" as unknown as number); throw new Error("Should have thrown an error"); } catch (error) { assertEquals( error.message, "Invalid input: input must be a number representing seconds or a Date object." ); } }); it("handles zero seconds", () => { assertEquals(humanReadableTimestamp(0), "0 seconds ago"); }); it("handles very large numbers", () => { assertEquals(humanReadableTimestamp(1e10), "317 years ago"); }); });
This project is licensed under the MIT License. See the LICENSE file for details.
Add Package
deno add jsr:@blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
---- OR ----
Import directly with a jsr specifier
import * as human_readable_timestamp from "jsr:@blaze/human-readable-timestamp";
Add Package
npx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
Add Package
yarn dlx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
Add Package
pnpm dlx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
Add Package
bunx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";