Usage
Verbatempus turns a JavaScript Date into an English phrase you can read or
say aloud, at four levels of verbosity. No dependencies; runs in Node and the browser;
renders in any IANA time zone.
Install
npm install verbatempus
ES modules
import { format } from 'verbatempus';
format(new Date(2024, 9, 24, 10, 24));
// 'it is twenty four minutes past ten oclock in the morning'
format(new Date(2024, 9, 24, 10, 24), { level: 'terse', parts: 'both' });
// 'it is thursday at quarter after ten'
CommonJS
const { format } = require('verbatempus');
Plain <script>, no build step
The browser bundle defines a global Verbatempus.
<script src="https://cdn.jsdelivr.net/npm/verbatempus@2/dist/verbatempus.iife.js"></script>
<script>
document.body.textContent = Verbatempus.format(new Date(), { level: 'short' });
</script>
To avoid a third-party request, copy dist/verbatempus.iife.js out of the npm
package and serve it yourself. The split-flap and flip-dot displays do this.
Try it
This runs the library in your browser.
format(new Date())
Tokens
Options
format(date?, options?) -> string
date defaults to now. null, a non-Date, or an invalid Date throws.
| option | values | default | |
|---|---|---|---|
level | 'verbose' 'lengthy' 'short' 'terse' | 'verbose' | |
parts | 'time' 'date' 'both' | 'time' | 'both' is one sentence |
timeZone | an IANA name, e.g. 'America/New_York' | local time | an invalid name throws a RangeError |
case | 'lower' 'upper' | 'lower' | |
charset | 'full' 'alpha' | 'full' | 'alpha' keeps A-Z and spaces only |
Unknown option values throw instead of falling back silently.
Time zones
const d = new Date('2024-10-24T23:30:00Z');
format(d, { timeZone: 'UTC' }); // 'it is half past eleven oclock in the evening'
format(d, { timeZone: 'America/New_York' }); // 'it is half past seven oclock in the evening'
format(d, { timeZone: 'Asia/Kolkata' }); // 'it is five oclock in the morning'
Case and charset
For displays that can only show capital letters, such as a split-flap board:
format(d, { level: 'verbose', parts: 'both', case: 'upper', charset: 'alpha' });
// 'IT IS THURSDAY OCTOBER THE TWENTY FOURTH TWENTY TWENTY FOUR AND IT IS TWENTY FOUR
// MINUTES PAST TEN OCLOCK IN THE MORNING'
Levels
Thursday 24 October 2024, 10:24.
| level | time | date |
|---|---|---|
verbose | it is twenty four minutes past ten oclock in the morning | it is thursday october the twenty fourth twenty twenty four |
lengthy | it is twenty four past ten in the morning | it is thursday october twenty fourth |
short | it is almost half past ten am | it is thursday the twenty fourth |
terse | its quarter after ten | it is thursday |
afterfor minutes 1-10,pastfor 11-44, then counting downtothe next hour.- Verbose and lengthy say
a quarter pastanda quarter to;tillappears only toward midnight or noon. midnightandnoonnever takeoclock, a time-of-day suffix, or am/pm.- Short rounds to landmarks (
almost,just about); terse uses six wide bands.
Every phrase at every level, for all 1440 minutes of the day, is checked against a golden fixture in the test suite.
Date and time
parts: 'both' is one sentence: the date, a joiner, then the time without its own
it is. Verbose joins with , and it is; the other levels join with at.
format(d, { level: 'verbose', parts: 'both' });
// 'it is thursday october the twenty fourth twenty twenty four, and it is
// twenty four minutes past ten oclock in the morning'
format(d, { level: 'lengthy', parts: 'both' });
// 'it is thursday october twenty fourth at twenty four past ten in the morning'
formatParts
Same arguments, structured result. Use it when a display needs to lay words out itself.
formatParts(new Date(2024, 9, 24, 10, 24), { level: 'short' });
// {
// text: 'it is almost half past ten am',
// tokens: [
// { type: 'lead', value: 'it is' },
// { type: 'rel', value: 'almost' },
// { type: 'minute', value: 'half' },
// { type: 'rel', value: 'past' },
// { type: 'hour', value: 'ten' },
// { type: 'suffix', value: 'am' },
// ],
// level: 'short',
// parts: 'time',
// maxLength: 39
// }
Token types: lead, minute, rel, hour,
oclock, suffix, weekday, month,
day, year, join. text is always the
tokens read in order, after case and charset.
MAX_LENGTH
The longest phrase, in characters, for each level and parts. Fixed-size displays should size themselves from it.
| level | time | date | both |
|---|---|---|---|
verbose | 61 | 65 | 132 |
lengthy | 46 | 40 | 84 |
short | 39 | 34 | 71 |
terse | 26 | 15 | 41 |
Time covers all 1440 minutes; date covers every calendar day from 2010 to 2099.
Named functions
Thin wrappers over format. level and parts are fixed;
timeZone, case and charset pass through as the second argument.
verboseTime lengthyTime shortTime terseTime
verboseDate lengthyDate shortDate terseDate
verboseDateTime lengthyDateTime shortDateTime terseDateTime
shortDate(new Date(2024, 9, 24)); // 'it is thursday the twenty fourth'
Upgrading from 1.0
- The eight
getVerboseTime()-style functions are removed.verboseTime()already defaults to now. - Import from
'verbatempus', notsrc/verbatempus.js. - Several 1.0 phrasing bugs are fixed, e.g.
shortTimeat 23:45 saidquarter to noon am; it now saysquarter to midnight. - New:
format,formatParts, date-and-time output,timeZone,case,charset,MAX_LENGTH.