whenwords

A relative time formatting library for MoonBit, following the whenwords specification

time
date
formatting
parsing
relative-time
moon add mizchi/whenwords@0.1.3
Download zip
Author
Version
0.1.3
License
MIT
Last updated
6 months ago
Downloads
27
README

#whenwords-mbt

A relative time formatting library for MoonBit.

#Background

This is a MoonBit implementation of whenwords, an experimental "software library with no code" by Drew Breunig.

The original whenwords project contains only specifications (SPEC.md) and tests (tests.yaml) - no implementation code. The idea is that AI coding agents can generate working implementations from specs alone.

This repository demonstrates that the whenwords specification can be successfully implemented in MoonBit by an AI coding agent.

#Installation

moon add mizchi/whenwords

#Usage

// Relative time formatting
@whenwords.timeago(1705190400L, reference=1705276800L) // "1 day ago"
@whenwords.timeago(1705280400L, reference=1705276800L) // "in 1 hour"

// Duration formatting
@whenwords.duration(9000L) // "2 hours, 30 minutes"
@whenwords.duration(9000L, options={ compact: true, max_units: 2 }) // "2h 30m"

// Duration parsing
@whenwords.parse_duration("2h 30m") // 9000
@whenwords.parse_duration("2:30:00") // 9000
@whenwords.parse_duration("2.5 hours") // 9000

// Human-readable dates
@whenwords.human_date(1705190400L, reference=1705276800L) // "Yesterday"
@whenwords.human_date(1705363200L, reference=1705276800L) // "Tomorrow"
@whenwords.human_date(1704844800L, reference=1705276800L) // "Last Wednesday"

// Date ranges
@whenwords.date_range(1705276800L, 1705449600L) // "January 15-17, 2024"

#API

#timeago(timestamp: Int64, reference~: Int64) -> String

Converts a timestamp to a relative time string like "3 hours ago" or "in 2 days".

#duration(seconds: Int64, options~: DurationOptions) -> String

Formats a number of seconds as a human-readable duration.

Options:
  • compact: Bool - Use compact format like "2h 30m" (default: false)
  • max_units: Int - Maximum number of units to display (default: 2)

#parse_duration(input: String) -> Int64 raise ParseDurationError

Parses a duration string into seconds. Supports compact ("2h30m"), verbose ("2 hours 30 minutes"), decimal ("2.5 hours"), and colon ("2:30:00") formats.

#human_date(timestamp: Int64, reference~: Int64) -> String

Returns a contextual date string like "Today", "Yesterday", "Last Tuesday", or "March 5".

#date_range(start: Int64, end: Int64) -> String

Formats a start and end timestamp as a smart date range.

#Testing

moon test

69 tests covering all five functions.

#License

MIT

#Credits

#
ParseDurationError

pub suberror ParseDurationError {
ParseDurationError(String)
}

Error type for parse_duration

#
DurationOptions

pub(all) struct DurationOptions {
compact : Bool
max_units : Int
}

Options for duration formatting

#
DurationOptions::default

#
date_range

fn date_range(start : Int64, end : Int64) -> String

Formats a start and end timestamp as a smart date range

Examples:
  • Same day: "March 5, 2024"
  • Same month: "March 5–7, 2024"
  • Same year: "March 5 – April 7, 2024"
  • Cross-year: "December 28, 2024 – January 3, 2025"

Note: If start > end, they are silently swapped

#
duration

fn duration(seconds : Int64, options? : DurationOptions) -> String

Formats a number of seconds as a human-readable duration

Parameters:
  • seconds: Non-negative number of seconds
  • options: Formatting options (compact mode, max units)

Returns: Human-readable duration string

#
human_date

fn human_date(timestamp : Int64, reference~ : Int64) -> String

Returns a contextual date string like "Today", "Yesterday", "Last Tuesday", or "March 5"

Parameters:
  • timestamp: Unix timestamp in seconds
  • reference: Reference timestamp for comparison

Returns: Human-readable date string

#
parse_duration

fn parse_duration(input : String) -> Int64 raise ParseDurationError

Parses a duration string into seconds

Supported formats:
  • Compact: "2h30m", "2h 30m"
  • Verbose: "2 hours 30 minutes", "2 hours and 30 minutes"
  • Decimal: "2.5 hours", "1.5h"
  • Colon: "2:30" (h:mm), "2:30:00" (h:mm:ss)

Returns: Number of seconds, or error if parsing fails

#
timeago

fn timeago(timestamp : Int64, reference~ : Int64) -> String

Converts a timestamp to a relative time string like "3 hours ago" or "in 2 days"

Parameters:
  • timestamp: Unix timestamp in seconds
  • reference: Reference timestamp (defaults to current context, must be provided)

Returns: Human-readable relative time string

Source Files