Convert seconds or Date objects into human-readable relative time strings
Human-Readable Timestamp
A utility to convert seconds or a Date object into a human-readable relative time string.
Table of Contents
Introduction
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.
Installation
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
Usage
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);
Options
The humanReadableTimestamp function accepts two parameters:
input: A number representing seconds or a Date object.options: An optional configuration object to customize the output.
Configuration Options
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.
Features
- Relative Time Calculation: Convert seconds or Date objects into relative time strings.
- Customization: Customize the output with various options such as unit labels, thresholds, suffixes, and localization.
- Abbreviation: Option to abbreviate unit labels.
- Verbose Mode: Option for verbose output.
Dependencies
This utility does not have any external dependencies.
Tests
The module includes a comprehensive test suite to ensure functionality and reliability.
Test Setup
To run the tests, you will need to have a testing framework installed, such as Deno.
Test Cases
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"); }); });
Contributors
- Sabry Awad - Initial work
License
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";
Import directly with a jsr specifier
import * as human_readable_timestamp from "jsr:@blaze/human-readable-timestamp";
Add Package
pnpm i jsr:@blaze/human-readable-timestamp
pnpm dlx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
Add Package
yarn add jsr:@blaze/human-readable-timestamp
yarn dlx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";
Add Package
vlt install jsr:@blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@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
bunx jsr add @blaze/human-readable-timestamp
Import symbol
import * as human_readable_timestamp from "@blaze/human-readable-timestamp";