nl2time 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/parse/en.js +25 -4
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -73,11 +73,19 @@ Cultural/ambiguous semantics are explicit `TimeContext` knobs with CLDR-derived
|
|
|
73
73
|
| Does "last 3 days" include today? | `partialPeriod: 'include' \| 'exclude'` | `include` |
|
|
74
74
|
| "At 4" — am or pm? | — | both candidates, plausibility-ordered |
|
|
75
75
|
|
|
76
|
+
## Install
|
|
77
|
+
|
|
78
|
+
[](https://www.npmjs.com/package/nl2time)
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
npm install nl2time
|
|
82
|
+
```
|
|
83
|
+
|
|
76
84
|
## Status
|
|
77
85
|
|
|
78
|
-
v0.1 — English parsing, en-* describe, core engine with a DST/edge-case battery. Recurrence (`every Tuesday`) is representable in the IR but resolves in v2.
|
|
86
|
+
v0.1 — English parsing, en-* describe, core engine with a DST/edge-case battery, holidays (fixed-date, nth-weekday, computed Easter), business-day spans. Recurrence (`every Tuesday`) is representable in the IR but resolves in v2.
|
|
79
87
|
|
|
80
|
-
**Corpus** ([corpus/](corpus/), runner exported as `nl2time/corpus`): a bidirectional golden set with per-case license provenance — 41 hand-authored NL→time cases (
|
|
88
|
+
**Corpus** ([corpus/](corpus/), runner exported as `nl2time/corpus`): a bidirectional golden set with per-case license provenance — 41 hand-authored NL→time cases (100% passing), a 65-case datetime→NL golden set (100% passing; to our knowledge the first published eval set for humanized time generation), and 693 cases imported from Microsoft Recognizers-Text (MIT) of which **80.7% currently pass** — the coverage baseline the parser climbs against (`npm run eval`, `npm run baselines`; every previously-passing case is a CI regression gate). Most remaining failures are documented divergences from upstream idiosyncrasies rather than parser gaps. See [corpus/ATTRIBUTIONS.md](corpus/ATTRIBUTIONS.md) and [docs/porting.md](docs/porting.md).
|
|
81
89
|
|
|
82
90
|
## Development
|
|
83
91
|
|
package/dist/parse/en.js
CHANGED
|
@@ -125,12 +125,17 @@ function yearAt(tokens, i) {
|
|
|
125
125
|
? t.value
|
|
126
126
|
: undefined;
|
|
127
127
|
}
|
|
128
|
-
/** "in the morning" / "at night" / "tonight" lookahead.
|
|
129
|
-
|
|
128
|
+
/** "in the morning" / "at night" / "this morning" / "tonight" lookahead.
|
|
129
|
+
* Returns period + consumed. "this <period>" binds a preceding bare hour
|
|
130
|
+
* exactly like "in the <period>" ("8 this morning" → 8am): the period
|
|
131
|
+
* supplies the meridiem, and the reference day is the anchor either way.
|
|
132
|
+
* Deliberately NOT "last night": that also shifts the day, which a
|
|
133
|
+
* meridiem-only suffix can't express (#9). */
|
|
134
|
+
function readPeriodSuffix(tokens, i, allowThis = true) {
|
|
130
135
|
let at = i;
|
|
131
136
|
if (word(tokens[at]) === 'in' || word(tokens[at]) === 'at')
|
|
132
137
|
at += 1;
|
|
133
|
-
if (word(tokens[at]) === 'the')
|
|
138
|
+
if (word(tokens[at]) === 'the' || (allowThis && word(tokens[at]) === 'this'))
|
|
134
139
|
at += 1;
|
|
135
140
|
const w = word(tokens[at]);
|
|
136
141
|
if (w === 'tonight')
|
|
@@ -143,6 +148,12 @@ function readPeriodSuffix(tokens, i) {
|
|
|
143
148
|
function meridiemFor(period) {
|
|
144
149
|
return period === 'morning' ? 'am' : 'pm';
|
|
145
150
|
}
|
|
151
|
+
/** Words that license a following bare number as a clock time
|
|
152
|
+
* ("at 8 this morning", "by 5 this afternoon"). */
|
|
153
|
+
const TIME_PREPOSITIONS = new Set([
|
|
154
|
+
'at', 'around', 'about', 'by', 'from', 'until', 'till', 'to',
|
|
155
|
+
'before', 'after', 'since',
|
|
156
|
+
]);
|
|
146
157
|
// --- rules -----------------------------------------------------------------
|
|
147
158
|
/** today / yesterday / tomorrow / tonight / day before yesterday / day after tomorrow */
|
|
148
159
|
const ruleDeicticDay = (tokens, i) => {
|
|
@@ -2353,7 +2364,17 @@ const ruleClockTime = (tokens, i, ctx) => {
|
|
|
2353
2364
|
if (after === "o'clock" || after === 'oclock') {
|
|
2354
2365
|
return withPeriodSuffix({ hour: hn.value, meridiem: 'unknown' }, hn.consumed + 1);
|
|
2355
2366
|
}
|
|
2356
|
-
|
|
2367
|
+
// A BARE number before "this <period>" is only a clock time when the
|
|
2368
|
+
// number isn't already bound by a preceding noun — "8 this morning"
|
|
2369
|
+
// is 8am, but in "building 4 this afternoon" the 4 is a building
|
|
2370
|
+
// number and the period keeps its range reading (Recognizers
|
|
2371
|
+
// rt-dtm-0523). Utterance start or a time-preposition before the
|
|
2372
|
+
// number licenses the binding; an arbitrary preceding word does not.
|
|
2373
|
+
// The in/at forms ("4 in the afternoon") are explicit enough to bind
|
|
2374
|
+
// regardless, as before.
|
|
2375
|
+
const prevWord = word(tokens[i - 1]);
|
|
2376
|
+
const allowThis = i === 0 || prevWord === undefined || TIME_PREPOSITIONS.has(prevWord);
|
|
2377
|
+
const ps = readPeriodSuffix(tokens, i + hn.consumed + mc, allowThis);
|
|
2357
2378
|
if (ps) {
|
|
2358
2379
|
const time = { hour: hn.value, meridiem: meridiemFor(ps.period) };
|
|
2359
2380
|
if (minute !== undefined)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nl2time",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Bidirectional natural language ⇄ date/time: parse expressions like 'last week' into concrete intervals, and describe instants as '9pm last night' — deterministic core, optional LLM assist.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"type": "git",
|
|
20
20
|
"url": "git+https://github.com/AndyFooBlah/nl2time.git"
|
|
21
21
|
},
|
|
22
|
+
"homepage": "https://github.com/AndyFooBlah/nl2time#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/AndyFooBlah/nl2time/issues"
|
|
25
|
+
},
|
|
22
26
|
"scripts": {
|
|
23
27
|
"build": "tsc -p tsconfig.build.json",
|
|
24
28
|
"prepare": "npm run build",
|