{"id":15984783,"url":"https://github.com/jaredreisinger/compromise-dates","last_synced_at":"2025-04-04T20:46:26.322Z","repository":{"id":146778943,"uuid":"387857283","full_name":"JaredReisinger/compromise-dates","owner":"JaredReisinger","description":"temporary repo to expose compromise-dates as a GitHub-installable repo","archived":false,"fork":false,"pushed_at":"2021-07-20T16:55:21.000Z","size":239,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-10T05:26:16.591Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JaredReisinger.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-20T16:51:32.000Z","updated_at":"2021-07-20T16:55:24.000Z","dependencies_parsed_at":"2023-09-01T17:05:30.001Z","dependency_job_id":null,"html_url":"https://github.com/JaredReisinger/compromise-dates","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"f6fdeaae80a48b58f9eb6bcc968eae5cc2d85020"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredReisinger%2Fcompromise-dates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredReisinger%2Fcompromise-dates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredReisinger%2Fcompromise-dates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredReisinger%2Fcompromise-dates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JaredReisinger","download_url":"https://codeload.github.com/JaredReisinger/compromise-dates/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249602,"owners_count":20908211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-08T02:10:31.544Z","updated_at":"2025-04-04T20:46:26.286Z","avatar_url":"https://github.com/JaredReisinger.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://cloud.githubusercontent.com/assets/399657/23590290/ede73772-01aa-11e7-8915-181ef21027bc.png\" /\u003e\n\n  \u003cdiv\u003edate-parsing plugin for \u003ca href=\"https://github.com/spencermountain/compromise/\"\u003ecompromise\u003c/a\u003e\u003c/div\u003e \n\n  \u003c!-- npm version --\u003e\n  \u003ca href=\"https://npmjs.org/package/compromise-dates\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/compromise-dates.svg?style=flat-square\" /\u003e\n  \u003c/a\u003e\n  \n  \u003c!-- file size --\u003e\n  \u003ca href=\"https://unpkg.com/compromise-dates/builds/compromise-dates.min.js\"\u003e\n    \u003cimg src=\"https://badge-size.herokuapp.com/spencermountain/compromise/master/plugins/dates/builds/compromise-dates.min.js\" /\u003e\n  \u003c/a\u003e\n\n  \u003cdiv align=\"center\"\u003e\n    \u003ccode\u003enpm install compromise-dates\u003c/code\u003e\n  \u003c/div\u003e\n  \u003cb\u003e-work-in-Progress-\u003c/b\u003e\n\u003c/div\u003e\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\nThis library is an earnest attempt to get date information out of text, in a clear way -\n\u003cdiv \u003e\n\u003cimg height=\"25px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e- including all informal text formats, and folksy shorthands.\n\u003c/div\u003e\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"15px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\n```js\nconst nlp = require('compromise')\nnlp.extend(require('compromise-dates'))\n\nlet doc = nlp('the second monday of february')\ndoc.dates().get(0)\n/*\n  { start: '2021-02-08T00:00:00.000Z', end: '2021-02-08T23:59:59.999Z'}\n*/\n```\n\n\u003cimg height=\"10px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\u003cimg height=\"15px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221632-b9094000-ffb7-11e9-99e0-b48edd6cdf8a.png\"/\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e• \u003cb\u003e\u003ci\u003eTokenization\u003c/i\u003e\u003c/b\u003e and \u003cb\u003e\u003ci\u003edisambiguation\u003c/i\u003e\u003c/b\u003e with compromise\u003c/i\u003e.\n\u003c/div\u003e\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e• \u003cb\u003e\u003ci\u003eTimezone\u003c/i\u003e\u003c/b\u003e and \u003cb\u003e\u003ci\u003eDST\u003c/i\u003e\u003c/b\u003e reckoning with \u003ca href=\"https://github.com/spencermountain/spacetime\"\u003espacetime \u003csup\u003e[1]\u003c/sup\u003e\u003c/a\u003e\n\u003c/div\u003e\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e• \u003cb\u003e\u003ci\u003eNumber-parsing\u003c/i\u003e\u003c/b\u003e with \u003ci\u003e\u003ca href=\"https://github.com/spencermountain/compromise/tree/master/plugins/numbers\"\u003ecompromise-numbers \u003csup\u003e[1]\u003c/sup\u003e\u003c/a\u003e\u003c/i\u003e\n\u003c/div\u003e\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e• \u003cb\u003e\u003ci\u003eTimezone reconciliation\u003c/i\u003e\u003c/b\u003e with \u003ca href=\"https://github.com/spencermountain/spacetime-informal\"\u003espacetime-informal \u003csup\u003e[1]\u003c/sup\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n\u003cimg height=\"55px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\u003cimg  src=\"https://user-images.githubusercontent.com/399657/109049133-e5156c80-76a5-11eb-9690-e8af1e3764b1.png\" /\u003e\n\n\u003cimg height=\"35px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n\u003ch2\u003e\u003ca href=\"http://compromise.cool/dates/\"\u003eDemo\u003c/a\u003e\u003c/h2\u003e\n\u003c/div\u003e\n\n\u003cimg height=\"15px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n### *Things it does well:*\n\n| `explicit-dates` | \u003csup\u003e*description*\u003c/sup\u003e | `Start`   | `End` |\n| ------------- |:-------------:| -----:| -----:|\n| *march 2nd* | |March 2, 12:00am | March 2, 11:59pm\n| *2 march* | | '' | ''\n| *tues march 2*| | '' | ''\n| *march the second* | \u003csup\u003e*natural-language number*\u003c/sup\u003e | '' | ''\n| *on the 2nd* | \u003csup\u003e*implicit months*\u003c/sup\u003e | '' | ''\n| *tuesday the 2nd* | \u003csup\u003e*date-reckoning*\u003c/sup\u003e | '' | ''\n|\u003cbr/\u003e**`numeric-dates:`**| |\n| *2020/03/02* |\u003csup\u003e*iso formats*\u003c/sup\u003e | '' | ''\n| *2020-03-02* | | '' | ''\n| *03-02-2020* |\u003csup\u003e*british formats*\u003c/sup\u003e | '' | ''\n| *03/02* | | '' | ''\n| *2020.08.13* | \u003csup\u003e*alt-ISO*\u003c/sup\u003e| '' | ''\n|\u003cbr/\u003e**`named-dates:`**| |\n| *today* | | - | -\n| *tomorrow* | | '' | ''\n| *christmas eve* |\u003csup\u003e*calendar-holidays*\u003c/sup\u003e | Dec 24, 12:00am | Dec 24, 11:59pm\n| *easter* |\u003csup\u003e*astronomical holidays*\u003c/sup\u003e | -depends- | -\n| *q1* | | Jan 1, 12:00am | Mar 31, 11:59pm\n|\u003cbr/\u003e**`times:`**| |\n| *2pm* | | '' | ''\n| *2:12pm* | | '' | ''\n| *2:12* | | '' | ''\n| *02:12:00* | \u003csup\u003e*weird iso-times*\u003c/sup\u003e| '' | ''\n| *two oclock* |\u003csup\u003e*written formats*\u003c/sup\u003e | '' | ''\n| *before 1* | | '' | ''\n| *noon* | | '' | ''\n| *at night* | \u003csup\u003e*informal daytimes*\u003c/sup\u003e | '' | ''\n| *in the morning* | | '' | ''\n| *tomorrow evening* | | '' | ''\n|\u003cbr/\u003e**`timezones:`**| |\n| *eastern time* | \u003csup\u003e*informal zone support*\u003c/sup\u003e| '' | '' \n| *est* |\u003csup\u003e*TZ shorthands*\u003c/sup\u003e | '' | '' \n| *peru time* | | '' | '' \n| *..in beirut* | \u003csup\u003e*by location*\u003c/sup\u003e | '' | '' \n| *GMT+9* | \u003csup\u003e*by UTC/GMT offset*\u003c/sup\u003e| '' | '' \n| *-4h* | '' | '' | '' \n| *Canada/Eastern* | \u003csup\u003e*IANA codes*\u003c/sup\u003e| '' | '' \n|\u003cbr/\u003e**`relative durations:`**| |\n| *this march* | | '' | ''\n| *this week* | | '' | ''\n| *this sunday* | | '' | ''\n| *next april* | | '' | ''\n| *this past year* | | '' | ''\n| *second week of march* | | '' | ''\n| *last weekend of march* | | '' | ''\n| *last spring* | | '' | ''\n| *the saturday after next* | | '' | ''\n|\u003cbr/\u003e**`punted dates:`**| |\n| *in seven weeks* | \u003csup\u003e*now+duration*\u003c/sup\u003e| '' | '' \n| *two days after june 6th* | \u003csup\u003e*date+duration*\u003c/sup\u003e| '' | '' \n| *2 weeks from now* | | '' | '' \n| *2 weeks after june* | | '' | '' \n| *2 years, 4 months, and 5 days ago* | \u003csup\u003e*complex durations*\u003c/sup\u003e| '' | '' \n| *a week and a half before* | \u003csup\u003e*written-out numbers*\u003c/sup\u003e| '' | '' \n| *a week friday* | \u003csup\u003e*idiom format*\u003c/sup\u003e| '' | '' \n|\u003cbr/\u003e**`start/end:`**| |\n| *end of the week* | \u003csup\u003e*up-against the ending*\u003c/sup\u003e | '' | '' \n| *start of next year* | \u003csup\u003e*lean-toward starting*\u003c/sup\u003e| '' | '' \n| *middle of q2 last year* |\u003csup\u003e*rough-center calculation*\u003c/sup\u003e | '' | '' \n|\u003cbr/\u003e**`date-ranges:`**| |\n| *between june and july* |\u003csup\u003e*explicit ranges*\u003c/sup\u003e | '' | ''\n| *from today to next haloween* | | '' | ''\n| *aug 1 - aug 31* | \u003csup\u003e*dash-ranges*\u003c/sup\u003e| '' | ''\n| *22-23 February* | | '' | ''\n| *today to next friday* | | '' | ''\n| *during june* | | '' | ''\n| *aug to june 1999* | \u003csup\u003e*shared range info*\u003c/sup\u003e| '' | ''\n| *before [2019]* |\u003csup\u003e*up-to a date*\u003c/sup\u003e | '' | ''\n| *by march* | | '' | ''\n| *after february* | \u003csup\u003e*date-to-infinity*\u003c/sup\u003e| '' | ''\n|\u003cbr/\u003e**`repeating-intervals:`**| |\n| *any wednesday* | \u003csup\u003e*n-repeating dates*\u003c/sup\u003e |  | \n| *any day in June* | \u003csup\u003e*repeating-date in range*\u003c/sup\u003e | June 1 ... | .. June 30\n| *any wednesday this week* | | '' | ''\n| *weekends in July* | \u003csup\u003e*more-complex interval*\u003c/sup\u003e| '' | ''\n| *every weekday until February* | \u003csup\u003e*interval until date*\u003c/sup\u003e| '' | ''\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n### *Things it does awkwardly:*\n| *`hmmm,`* | \u003csup\u003e*description*\u003c/sup\u003e | `Start`   | `End` |\n| ------------- |:-------------:| :-------------:|  :-------------:| \n| *middle of 2019/June* | tries to find the sorta-center | June 15 | '' |\n| *good friday 2025* | tries to reckon astronomically-set holidays| '' | '' |\n| *Oct 22 1975 2am in PST* | historical DST changes (assumes current dates) | '' | '' |\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n### *Things it doesn't do:*\n| *😓,* | \u003csup\u003e*description*\u003c/sup\u003e | `Start`   | `End` |\n| ------------- |:-------------:| :-------------:|  :-------------:| \n| *not this Saturday, but the Saturday after* | self-reference logic | '' | '' |\n| *3 years ago tomorrow* | folksy short-hand  | '' | '' |\n| *2100* | military time formats  | '' | '' |\n| *may 97* | 'bare' 2-digit years  | '' | '' |\n\n\n\u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003c!-- spacer --\u003e\n  \u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221848-11404200-ffb8-11e9-90cd-3adee8d8564f.png\"/\u003e\n\u003c/div\u003e\n\n## API\n\n- **.dates()** - find dates like `June 8th` or `03/03/18`\n  - **.dates().get()** - parsed dates as json\n  - **.dates().json()** - overloaded json output with date metadata\n  - **.dates().format('')** - convert the dates to specific formats\n \n- **.durations()** - find unspecified lengths of time like `two hours and 30mins`\n  - **.durations().get()** - parsed durations as json\n  - **.durations().json()** - overloaded json output with duration metadata\n  - **.durations().normalize()** - turn 3mins into 3 minutes\n \n- **.times()** - find day-times like `three oclock`\n  - **.times().get()** - parsed times as json\n  - **.times().json()** - overloaded json output with time metadata\n  - **.times().normalize()** - turn 3mins into 3 minutes\n\n\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n### Configuration:\n`.dates()` accepts an optional object, that lets you set the context for the date parsing.\n```js\nconst context = {\n  timezone: 'Canada/Eastern', //the default timezone is 'ETC/UTC'\n  today: '2020-02-20', //the implicit, or reference day/year\n  punt: { weeks: 2 }, // the implied duration to use for 'after june 2nd'\n  dayStart: '8:00am',\n  dayEnd: '5:30pm'\n}\n\nnlp('in two days').dates(context).get()\n/*\n  [{ start: '2020-02-22T08:00:00.000+5:00', end: '2020-02-22T17:30:00.000+5:00' }]\n*/\n```\n\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221814-05ed1680-ffb8-11e9-8b6b-c7528d163871.png\"/\u003e\n\u003c/div\u003e\n\n## API\n- **[.dates()](https://observablehq.com/@spencermountain/compromise-dates)** - find dates like `June 8th` or `03/03/18`\n  - **[.dates().get()](https://observablehq.com/@spencermountain/compromise-dates)** - simple start/end json result\n  - **[.dates().json()](https://observablehq.com/@spencermountain/compromise-dates)** - overloaded output with date metadata\n  - **[.dates().format('')](https://observablehq.com/@spencermountain/compromise-dates)** - convert the dates to specific formats\n  - **[.dates().toShortForm()](https://observablehq.com/@spencermountain/compromise-dates)** - convert 'Wednesday' to 'Wed', etc\n  - **[.dates().toLongForm()](https://observablehq.com/@spencermountain/compromise-dates)** - convert 'Feb' to 'February', etc\n- **[.durations()](https://observablehq.com/@spencermountain/compromise-dates)** - `2 weeks` or `5mins`\n  - **[.durations().get()](https://observablehq.com/@spencermountain/compromise-dates)** - return simple json for duration\n  - **[.durations().json()](https://observablehq.com/@spencermountain/compromise-dates)** - overloaded output with duration metadata\n- **[.times()](https://observablehq.com/@spencermountain/compromise-dates)** - `4:30pm` or `half past five`\n  - **[.durations().get()](https://observablehq.com/@spencermountain/compromise-dates)** - return simple json for times\n  - **[.times().json()](https://observablehq.com/@spencermountain/compromise-dates)** - overloaded output with time metadata\n\n\n\n\n\u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n## *Opinions*:\n\n### *Start of week:*\nBy default, weeks start on a Monday, and *'next week'* will run from Monday morning to Sunday night.\nThis can be configued in spacetime, but right now we are not passing-through this config.\n\n### *Implied durations:*\n*'after October'* returns a range starting **Nov 1st**, and ending **2-weeks** after, by default.\nThis can be configured by setting `punt` param in the context object:\n```js\ndoc.dates({punt: { month: 1 }})\n```\n\n### *Future bias:*\n*'May 7th'* will prefer a May 7th in the future.\n\nThe parser will return a past-date though, in the current-month:\n```js\n// from march 2nd\nnlp('feb 30th').dates({today: '2021-02-01'}).get()\n\n```\n\n### *This/Next/Last:*\nnamed-weeks or months eg *'this/next/last week'* are mostly straight-forward.\n\n#### *This monday*\nA bare 'monday' will always refer to itself, or the upcoming monday. \n\n* Saying *'this monday'* on monday, is itself.\n* Saying *'this monday'* on tuesday , is next week.\n\nLikewise, *'this june'* in June, is itself. *'this june'* in any other month, is the nearest June in the future.\n\nFuture versions of this library could look at sentence-tense to help disambiguate these dates - *'i paid on monday'* vs *'i will pay on monday'*.\n\n#### *Last monday*\nIf it's Tuesday, *'last monday'* will not mean yesterday.\n\n* Saying *'last monday'* on a tuesday will be -1 week.\n* Saying *'a week ago monday'* will also work.\n* Saying *'this past monday'* will return yesterday.\n\nFor reference, **Wit.ai** \u0026 **chronic** libraries both return yesterday. **Natty** and **SugarJs** returns -1 week, like we do.\n\n*'last X'* can be less than 7 days backward, if it crosses a week starting-point:\n* Saying *'last friday'* on a monday will be only a few days back.\n\n#### *Next Friday*\nIf it's Tuesday, *'next wednesday'* will not be tomorrow. It will be a week after tomorrow.\n\n* Saying *'next wednesday'* on a tuesday, will be +1 week.\n* Saying *'a week wednesday'* will also be +1 week.\n* Saying *'this coming wednesday'* will be tomorrow.\n\nFor reference, **Wit.ai**, **chronic**, and **Natty** libraries all return tomorrow. **SugarJs** returns +1 week, like we do.\n\n### *Nth Week:*\nThe first week of a month, or a year is the first week *with a thursday in it*. This is a weird, but widely-held standard. I believe it's a military formalism. It cannot be (easily) configued. This means that the start-date for *first week of January* may be a Monday in December, etc.\n\nAs expected, *first monday of January* will always be in January.\n\n### *British/American ambiguity:*\nby default, we use the same interpretation of dates as javascript does - we assume `01/02/2020` is Jan 2nd, (US-version) but allow `13/01/2020` to be Jan 13th (UK-version). This should be possible to configure in the near future.\n\n### *Seasons:*\nBy default, *'this summer'* will return **June 1 - Sept 1**, which is northern hemisphere ISO.\nConfiguring the default hemisphere should be possible in the future.\n\n### *Day times:*\nThere are some hardcoded times for *'lunch time'* and others, but mainly, a day begins at `12:00am` and ends at `11:59pm` - the last millisecond of the day.\n\n### *Invalid dates:*\ncompromise will tag anything that looks like a date, but not validate the dates until they are parsed.\n* *'january 34th 2020'* will return **Jan 31 2020**.\n* *'tomorrow at 2:62pm'* will return just return 'tomorrow'.\n* *'6th week of february* will return the 2nd week of march.\n* Setting an hour that's skipped, or repeated by a DST change will return the closest valid time to the DST change.\n\n### *Inclusive/exclusive ranges:*\n*'between january and march'* will include all of march. This is usually pretty-ambiguous normally.\n\n### *Date greediness:*\nThis library makes no assumptions about the input text, and is careful to avoid false-positive dates.\nIf you know your text is a date, you can crank-up the date-tagger with a [compromise-plugin](https://observablehq.com/@spencermountain/compromise-plugins), like so:\n```js\nnlp.extend(function (Doc, world) {\n  // ambiguous words\n  world.addWords({\n    weds: 'WeekDay',\n    wed: 'WeekDay',\n    sat: 'WeekDay',\n    sun: 'WeekDay',\n  })\n  world.postProcess((doc) =\u003e {\n    // tag '2nd quarter' as a date\n    doc.match('#Ordinal quarter').tag('#Date')\n    // tag '2/2' as a date (not a fraction)\n    doc.match('/[0-9]{1,2}/[0-9]{1,2}/').tag('#Date')\n  })\n})\n```\n\n\n### *Misc:*\n* *'thursday the 16th'* - will set to the 16th, even if it's not thursday\n* *'in a few hours/years'* - in 2 hours/years\n* *'jan 5th 2008 to Jan 6th the following year'* - date-range explicit references\n* assume *'half past 5'* is 5pm\n\n\u003c!-- spacer --\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg height=\"40px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n  \u003chr/\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg height=\"50px\" src=\"https://user-images.githubusercontent.com/399657/68221632-b9094000-ffb7-11e9-99e0-b48edd6cdf8a.png\"/\u003e\n\u003c/div\u003e\n\n### *About:*\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"10px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e1 - \u003cb\u003eRegular-expressions\u003c/b\u003e are too-brittle to parse dates.\n\u003c/div\u003e\n\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e2 - \u003cb\u003eNeural-nets\u003c/b\u003e are too-wonky to parse dates.\n\u003c/div\u003e\n\n\u003cdiv align=\"left\"\u003e\n  \u003cimg height=\"30px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e3 - A \u003cb\u003ecorporation\u003c/b\u003e, or \u003cb\u003estartup\u003c/b\u003e is the wrong place to build a universal date-parser.\n\u003c/div\u003e\n\n\n\u003c!-- spacer --\u003e\n\u003cimg height=\"40px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\nParsing \u003cins\u003e*dates*\u003c/ins\u003e, \u003cins\u003e*times*\u003c/ins\u003e, \u003cins\u003e*durations*\u003c/ins\u003e, and \u003cins\u003e*intervals*\u003c/ins\u003e from natural language can be a solved-problem.\n\nA rule-based, community open-source library - *one based on simple NLP* - is the best way to build a natural language date parser -  commercial, or otherwise - for the frontend, or the backend.\n\nThe *[match-syntax](https://observablehq.com/@spencermountain/compromise-match-syntax)* is effective and easy, *javascript* is prevailing, and the more people who contribute, the better.\n\n\n\u003cimg height=\"40px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\n### See also\n* [Duckling](https://duckling.wit.ai/) - by wit.ai (facebook)\n* [Sugarjs/dates](https://sugarjs.com/dates/) - by Andrew Plummer (js)\n* [Chronic](https://github.com/mojombo/chronic) - by Tom Preston-Werner (Ruby)\n* [SUTime](https://nlp.stanford.edu/software/sutime.shtml) - by Angel Chang, Christopher Manning (Java)\n* [Natty](http://natty.joestelmach.com/) - by Joe Stelmach (Java)\n* [rrule](https://github.com/jakubroztocil/rrule) - repeating date-interval handler (js)\n* [ParseDateTime](https://pypi.org/project/parsedatetime/) by Mike Taylor (Python)\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg height=\"40px\" src=\"https://user-images.githubusercontent.com/399657/68221862-17ceb980-ffb8-11e9-87d4-7b30b6488f16.png\"/\u003e\n\u003c/div\u003e\n\ncompromise-date is sponsored by \u003ca href=\"https://www.simform.com/\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/399657/107404468-4f3de700-6ad4-11eb-9d60-7a90625b57d6.png\" width=\"150px\"/\u003e\u003c/a\u003e\n\n**MIT** licenced\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredreisinger%2Fcompromise-dates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaredreisinger%2Fcompromise-dates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredreisinger%2Fcompromise-dates/lists"}