timeago

A library for formatting timestamps as human-readable relative time strings.

This library provides a simple way to convert timestamps into relative time expressions like “5 minutes ago” or “in 2 hours”. It supports multiple locales and allows customization of the reference time.

Basic Usage

import gleam/time/duration
import gleam/time/timestamp
import timeago

// Format a timestamp from 5 minutes ago
let past = timestamp.add(timestamp.system_time(), duration.minutes(-5))
timeago.new() |> timeago.format(past)
// -> "5 minutes ago"

Types

A function that formats relative time strings for a specific language and locale.

Receives tense (past/future), unit (seconds, minutes, etc.), and amount, then returns a formatted string like “5 minutes ago” or “in 2 hours”.

pub type Locale =
  fn(Tense, duration.Unit, Int) -> String

Represents the temporal direction of a time difference.

Used to determine whether a timestamp is in the past or future relative to a reference time.

pub type Tense {
  Past
  Future
}

Constructors

  • Past

    Indicates that the timestamp occurred before the reference time. Results in formatting like “X ago”.

  • Future

    Indicates that the timestamp will occur after the reference time. Results in formatting like “in X”.

Configuration for formatting relative time strings.

Encapsulates the reference time and locale settings used when formatting timestamps. Use the builder pattern with new(), with_now(), and with_locale() to configure instances.

pub opaque type TimeAgo

Values

pub fn en_us(
  tense: Tense,
  unit: duration.Unit,
  amount: Int,
) -> String
pub fn format(
  time_ago: TimeAgo,
  timestamp: timestamp.Timestamp,
) -> String

Formats a timestamp as a human-readable relative time string.

Calculates the difference between the given timestamp and the reference time (set via with_now() or defaulting to the current time), then formats it using the configured locale.

The output automatically adjusts for singular/plural forms and selects appropriate time units based on the magnitude of the difference.

Examples

import gleam/time/duration
import gleam/time/timestamp
import timeago

let now = timestamp.system_time()

// Past times
timeago.new()
|> timeago.format(timestamp.add(now, duration.seconds(-5)))
// -> "5 seconds ago"

timeago.new()
|> timeago.format(timestamp.add(now, duration.minutes(-1)))
// -> "1 minute ago"

// Future times
timeago.new()
|> timeago.format(timestamp.add(now, duration.hours(2)))
// -> "in 2 hours"

timeago.new()
|> timeago.format(timestamp.add(now, duration.days(1)))
// -> "in 1 day"

timeago.new()
|> timeago.format(timestamp.add(now, duration.milliseconds(-500)))
// -> "just now"
pub fn fr(
  tense: Tense,
  unit: duration.Unit,
  amount: Int,
) -> String
pub fn new() -> TimeAgo

Creates a new TimeAgo formatter with default settings.

Uses the current system time as the reference point and the English (US) locale for formatting.

Examples

import gleam/time/duration
import gleam/time/timestamp
import timeago

timeago.new()
|> timeago.format(timestamp.add(timestamp.system_time(), duration.minutes(-5)))
// -> "5 minutes ago"
pub fn with_locale(
  time_ago: TimeAgo,
  locale: fn(Tense, duration.Unit, Int) -> String,
) -> TimeAgo

Sets a custom locale function for formatting output strings.

The locale function determines how relative time is expressed in different languages.

Examples

import gleam/time/duration
import gleam/time/timestamp
import timeago

// Using the built-in French locale
timeago.new()
|> timeago.with_locale(timeago.fr)
|> timeago.format(timestamp.add(timestamp.system_time(), duration.hours(-2)))
// -> "il y a 2 heures"
pub fn with_now(
  time_ago: TimeAgo,
  now: timestamp.Timestamp,
) -> TimeAgo

Sets a custom reference time for calculating relative differences.

By default, TimeAgo uses the current system time when created. This allows you to specify a different reference point for testing, calculating from specific moments, or maintaining consistency across operations.

Examples

import gleam/time/timestamp
import timeago

let assert Ok(reference) = timestamp.parse_rfc3339("2024-01-01T12:00:00Z")
let assert Ok(past) = timestamp.parse_rfc3339("2024-01-01T11:00:00Z")

timeago.new()
|> timeago.with_now(reference)
|> timeago.format(past)
// -> "1 hour ago"
Search Document