wanasit/chrono is a open-source project on GitHub, written primarily in TypeScript. It has 5.3k stars. A natural language date parser in Javascript
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
It is designed to handle most date/time format and extract information from any given text:
Today, Tomorrow, Yesterday, Last Friday, etc
17 August 2013 - 19 August 2013
This Friday from 13:00 - 16.00
5 days ago
2 weeks from now
Sat Aug 17 2013 18:40:39 GMT+0900 (JST)
2014-11-30T08:15:30-05:30
Installation
With npm:
$ npm install --save chrono-node
import * as chrono from 'chrono-node';
chrono.parseDate('An appointment on Sep 12-13');
For Node.js:
const chrono = require('chrono-node');
// or `import chrono from 'chrono-node'` for ECMAScript
What's changed in the v2
For Users
Chrono’s default now handles only international English. While in the previous version, it tried to parse with all known languages.
In addition to English, Chrono supports the following languages: fi, fr, id, it, ja, nl, ru, uk, and vi. We also have partial support for de, es, pt, sv, zh.hans, and zh.hant.
For contributors and advanced users
The project is rewritten in TypeScript
New Parser and Refiner interface
New source code structure. All parsers, refiners, and configuration should be under a locale directory (See. locales/en)
Note: v1.x.x will still be supported for the time being.
Usage
Simply pass a string to functions chrono.parseDate or chrono.parse.
import * as chrono from 'chrono-node';
chrono.parseDate('An appointment on Sep 12-13');
// Fri Sep 12 2014 12:00:00 GMT-0500 (CDT)
chrono.parse('An appointment on Sep 12-13');
/* [{
index: 18,
text: 'Sep 12-13',
start: ...
}] */
For more advanced usage, here is the typescript definition of the parse function:
Today's "Friday" is different from last month's "Friday".
The meaning of the referenced dates depends on when and where they are mentioned.
Chrono lets you define the reference as Date or ParsingReference object:
// (Note: the examples run on JST timezone)
chrono.parseDate('Friday', new Date(2012, 8 - 1, 23));
// Fri Aug 24 2012 12:00:00 GMT+0900 (JST)
chrono.parseDate('Friday', new Date(2012, 8 - 1, 1));
// Fri Aug 03 2012 12:00:00 GMT+0900 (JST)
chrono.parseDate("Friday at 4pm", {
// Wed Jun 09 2021 21:00:00 GMT+0900 (JST)
// = Wed Jun 09 2021 07:00:00 GMT-0500 (CDT)
instant: new Date(1623240000000),
timezone: "CDT",
})
// Sat Jun 12 2021 06:00:00 GMT+0900 (JST)
// = Fri Jun 11 2021 16:00:00 GMT-0500 (CDT)
ParsingReference
instant?: Date The instant when the input is written or mentioned
timezone?: string | number The timezone where the input is written or mentioned.
Support minute-offset (number) and timezone name (e.g. "GMT", "CDT")
Parsing Options
forwardDate (boolean) to assume the results should happen after the reference date (forward into the future)
const referenceDate = new Date(2012, 7, 25);
// Sat Aug 25 2012 00:00:00 GMT+0900 -- The reference date was Saturday
chrono.parseDate('Friday', referenceDate);
// Fri Aug 24 2012 12:00:00 GMT+0900 (JST) -- The day before was Friday
chrono.parseDate('Friday', referenceDate, { forwardDate: true });
// Fri Aug 31 2012 12:00:00 GMT+0900 (JST) -- The following Friday
timezones Override or add custom mappings between timezone abbreviations and offsets. Use this when you want Chrono to parse certain text into a given timezone offset. Chrono supports both unambiguous (normal) timezone mappings and ambigous mappings where the offset is different during and outside of daylight savings.
// Chrono doesn't understand XYZ, so no timezone is parsed
chrono.parse('at 10:00 XYZ', new Date(2023, 3, 20))
// "knownValues": {"hour": 10, "minute": 0}
// Make Chrono parse XYZ as offset GMT-0300 (180 minutes)
chrono.parse('at 10:00 XYZ', new Date(2023, 3, 20), { timezones: { XYZ: -180 } })
// "knownValues": {"hour": 10, "minute": 0, "timezoneOffset": -180}
// Make Chrono parse XYZ as offset GMT-0300 outside of DST, and GMT-0200 during DST. Assume DST is between
import { getLastDayOfMonthTransition } from "timezone";
import { Weekday, Month } from "parsing";
const parseXYZAsAmbiguousTz = {
timezoneOffsetDuringDst: -120,
timezoneOffsetNonDst: -180,
dstStart: (year: number) => getLastWeekdayOfMonth(year, Month.FEBRUARY, Weekday.SUNDAY, 2),
dstEnd: (year: number) => getLastWeekdayOfMonth(year, Month.SEPTEMBER, Weekday.SUNDAY, 3)
};
// Parsing a date which falls within DST
chrono.parse('Jan 1st 2023 at 10:00 XYZ', new Date(2023, 3, 20), { timezones: { XYZ: parseXYZAsAmbiguousTz } })
// "knownValues": {"month": 1, ..., "timezoneOffset": -180}
// Parsing a non-DST date
chrono.parse('Jun 1st 2023 at 10:00 XYZ', new Date(2023, 3, 20), { timezones: { XYZ: parseXYZAsAmbiguousTz } })
// "knownValues": {"month": 6, ..., "timezoneOffset": -120}
Parsed Results and Components
ParsedResult
refDate: Date The reference date of this result
index: number The location within the input text of this result
text: string The text this result that appears in the input
start: ParsedComponents The parsed date components as a ParsedComponents object
end?: ParsedComponents Similar to start
date: () => Date Create a javascript Date
ParsedComponents
get: (c: Component) => number | null Get known or implied value for the component
isCertain: (c: Component) => boolean Check if the component has a known value
date: () => Date Create a javascript Date
For example:
const results = chrono.parse('I have an appointment tomorrow from 10 to 11 AM');
results[0].index; // 22
results[0].text; // 'tomorrow from 10 to 11 AM'
results[0].refDate; // Sat Dec 13 2014 21:50:14 GMT-0600 (CST)
// `start` is Sat Dec 14 2014 10:00:00
results[0].start.get('day'); // 14 (the 14th, the day after refDate)
results[0].start.get('month'); // 12 (or December)
results[0].start.get('hour'); // 10
results[0].start.date(); // Sun Dec 14 2014 10:00:00 GMT-0600 (CST)
...
results[0].end.date(); // Sun Dec 14 2014 11:00:00 GMT-0600 (CST)
Strict vs Casual configuration
Chrono comes with strict mode that parse only formal date patterns.
By default, Chrono is configured to handle only international English.
This differs from the previous version of Chrono that would try all locales by default.
There are several locales supported contributed by multiple developers under ./locales directory.
// default English (US)
chrono.parseDate('6/10/2018');
chrono.en.parseDate('6/10/2018'); // June 10th, 2018
chrono.en.GB.parseDate('6/10/2018'); // October 6th, 2018
chrono.ja.parseDate('昭和64年1月7日');
In addition to English, Chrono supports the following languages: ar, fi, fr, id, it, ja, nl, ru, uk, and vi. We also have partial support for de, es, ko, pt, sv, zh.hans, and zh.hant.
Importing specific locales
Chrono exports all locale options by default for simplicity. However, this can cause issues when using Chrono if you're using a Node.js runtime that was built with the Intl module disabled (with the --without-intl flag), such as:
Invalid regular expression: /* omitted */: Invalid property name in character class
This is because the Intl module is required to handle special characters, such as Cyrillic (ru).
To avoid this, you can specify only the locale(s) you want to import:
// CommonJS (Node.js)
const chrono = require('chrono-node/en')
// ECMAScript
import chrono from 'chrono-node/en'
// TypeScript
// Warning: `moduleResolution` must be set to `node16` or `nodeNext` in tsconfig.json`
import * as chrono from 'chrono-node/en'
Customize Chrono
Chrono’s extraction pipeline configuration consists of parsers: Parser[] and refiners: Refiner[].
First, each parser independently extracts patterns from input text input and create parsing results (ParsingResult).
Then, the parsing results are combined, sorted, and refined with the refiners. In the refining phase, the results can be filtered-out, merged, or attached with additional information.
Parser is a module for low-level pattern-based parsing.
Ideally, each parser should be designed to handle a single specific date format.
User can create a new parser for supporting new date formats or languages
by providing RegExp pattern pattern() and extracting result or components from the RegExp match extract().
Refiner is a higher level module for improving or manipulating the results. User can add a new type of refiner to customize Chrono's results or to add some custom logic to Chrono.
const custom = chrono.casual.clone();
custom.refiners.push({
refine: (context, results) => {
// If there is no AM/PM (meridiem) specified,
// let all time between 1:00 - 4:00 be PM (13.00 - 16.00)
results.forEach((result) => {
if (!result.start.isCertain('meridiem') &&
result.start.get('hour') >= 1 && result.start.get('hour') < 4) {
result.start.assign('meridiem', 1);
result.start.assign('hour', result.start.get('hour') + 12);
}
});
return results;
}
});
// This will be parsed as PM.
// > Tue Dec 16 2014 14:30:00 GMT-0600 (CST)
custom.parseDate("This is at 2.30");
// Unless the 'AM' part is specified
// > Tue Dec 16 2014 02:30:00 GMT-0600 (CST)
custom.parseDate("This is at 2.30 AM");
In the example, the custom refiner assigns PM to parsing results with ambiguous meridiem.
The refine method of the refiner class will be called with parsing results (from parsers or other previous refiners).
The method must return an array of the new results (which, in this case, we modified those results in place).
More documentation
Checkout the Typescript Documentation in the project's Github page.
Development Guides
This guide explains how to set up chrono project for prospective contributors.
# Clone and install library
$ git clone https://github.com/wanasit/chrono.git chrono
$ cd chrono
$ npm install
Parsing date from text is complicated. A small change can have effects on unexpected places.
So, Chrono is a heavily tested library.
Commits that break a test shouldn't be allowed in any condition.
Chrono's unit testing is based-on Jest.
# Run the test
$ npm run test
# Run the test in watch mode
$ npm run watch
Chrono's source files is in src directory.
The built bundle (dist/*) is created by running Webpack via the following command
No homepage URL was recorded for wanasit/chrono in TopGit's last sync. The README tab above frequently contains screenshots and demo links, or check the repository description on GitHub.
Does wanasit/chrono have any tags?
TopGit's last sync did not record any GitHub topics for wanasit/chrono. GitHub topics appear in the right sidebar of a repository page; that's the authoritative place to check.
How active is development on wanasit/chrono?
The most recent commit recorded on wanasit/chrono was 9 days ago, based on the GitHub push timestamp. The repository has 400 forks — one of the better signals of community interest.
How many stars does wanasit/chrono have?
wanasit/chrono has 5.3k GitHub stars — refresh the page for the live number, or check github.com/wanasit/chrono. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is wanasit/chrono open source?
Yes — wanasit/chrono ships under the MIT license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/wanasit/chrono.
Where do I read more about wanasit/chrono?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/wanasit/chrono is the definitive source.
Read full README in the tab above.
Curious whether chrono is right for you?
Let ChatGPT, Claude, or Perplexity look into it — click below and see what AI actually says about chrono.