chrono-node 2.3.2 → 2.3.3

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.
Files changed (42) hide show
  1. package/dist/locales/de/constants.js +1 -1
  2. package/dist/locales/en/constants.js +1 -1
  3. package/dist/locales/en/parsers/ENRelativeDateFormatParser.js +3 -3
  4. package/dist/locales/en/parsers/ENTimeUnitAgoFormatParser.js +1 -1
  5. package/dist/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.js +1 -1
  6. package/dist/locales/en/parsers/ENTimeUnitLaterFormatParser.js +1 -1
  7. package/dist/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
  8. package/dist/locales/fr/constants.js +1 -1
  9. package/dist/locales/fr/parsers/FRTimeUnitAgoFormatParser.js +1 -1
  10. package/dist/locales/fr/parsers/FRTimeUnitRelativeFormatParser.js +1 -1
  11. package/dist/locales/fr/parsers/FRTimeUnitWithinFormatParser.js +1 -1
  12. package/dist/locales/nl/parsers/NLRelativeDateFormatParser.js +3 -3
  13. package/dist/locales/nl/parsers/NLTimeUnitAgoFormatParser.js +1 -1
  14. package/dist/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.js +1 -1
  15. package/dist/locales/nl/parsers/NLTimeUnitLaterFormatParser.js +1 -1
  16. package/dist/locales/nl/parsers/NLTimeUnitWithinFormatParser.js +1 -1
  17. package/dist/results.d.ts +2 -2
  18. package/dist/results.js +10 -7
  19. package/dist/timezone.d.ts +1 -1
  20. package/dist/timezone.js +3 -0
  21. package/package.json +1 -1
  22. package/src/locales/de/constants.ts +1 -1
  23. package/src/locales/en/constants.ts +1 -1
  24. package/src/locales/en/parsers/ENRelativeDateFormatParser.ts +3 -3
  25. package/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts +1 -1
  26. package/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts +1 -1
  27. package/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts +1 -1
  28. package/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +1 -1
  29. package/src/locales/fr/constants.ts +1 -1
  30. package/src/locales/fr/parsers/FRTimeUnitAgoFormatParser.ts +1 -1
  31. package/src/locales/fr/parsers/FRTimeUnitRelativeFormatParser.ts +1 -1
  32. package/src/locales/fr/parsers/FRTimeUnitWithinFormatParser.ts +1 -1
  33. package/src/locales/nl/parsers/NLRelativeDateFormatParser.ts +3 -3
  34. package/src/locales/nl/parsers/NLTimeUnitAgoFormatParser.ts +1 -1
  35. package/src/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.ts +1 -1
  36. package/src/locales/nl/parsers/NLTimeUnitLaterFormatParser.ts +1 -1
  37. package/src/locales/nl/parsers/NLTimeUnitWithinFormatParser.ts +1 -1
  38. package/src/results.ts +11 -8
  39. package/src/timezone.ts +5 -1
  40. package/test/en/en_relative.test.ts +8 -0
  41. package/test/en/negative_cases.test.ts +2 -0
  42. package/test/test_util.ts +5 -2
@@ -100,7 +100,7 @@ exports.TIME_UNIT_DICTIONARY = {
100
100
  year: "year",
101
101
  years: "year",
102
102
  };
103
- exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`;
103
+ exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?\\b(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`;
104
104
  function parseNumberPattern(match) {
105
105
  const num = match.toLowerCase();
106
106
  if (exports.INTEGER_WORD_DICTIONARY[num] !== undefined) {
@@ -126,7 +126,7 @@ exports.TIME_UNIT_DICTIONARY = {
126
126
  year: "year",
127
127
  years: "year",
128
128
  };
129
- exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?(?:\\s{0,2}few)?|few|several|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
129
+ exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?\\b(?:\\s{0,2}few)?|few|several|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
130
130
  function parseNumberPattern(match) {
131
131
  const num = match.toLowerCase();
132
132
  if (exports.INTEGER_WORD_DICTIONARY[num] !== undefined) {
@@ -22,15 +22,15 @@ class ENRelativeDateFormatParser extends AbstractParserWithWordBoundary_1.Abstra
22
22
  if (modifier == "next") {
23
23
  const timeUnits = {};
24
24
  timeUnits[timeunit] = 1;
25
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
25
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
26
26
  }
27
27
  if (modifier == "last" || modifier == "past") {
28
28
  const timeUnits = {};
29
29
  timeUnits[timeunit] = -1;
30
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
30
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
31
31
  }
32
32
  const components = context.createParsingComponents();
33
- let date = dayjs_1.default(context.refDate);
33
+ let date = dayjs_1.default(context.reference.instant);
34
34
  if (unitWord.match(/week/i)) {
35
35
  date = date.add(-date.get("d"), "d");
36
36
  components.imply("day", date.date());
@@ -17,7 +17,7 @@ class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBoundary_1.Abstrac
17
17
  innerExtract(context, match) {
18
18
  const timeUnits = constants_1.parseTimeUnits(match[1]);
19
19
  const outputTimeUnits = timeunits_1.reverseTimeUnits(timeUnits);
20
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
20
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
21
21
  }
22
22
  }
23
23
  exports.default = ENTimeUnitAgoFormatParser;
@@ -19,7 +19,7 @@ class ENTimeUnitCasualRelativeFormatParser extends AbstractParserWithWordBoundar
19
19
  timeUnits = timeunits_1.reverseTimeUnits(timeUnits);
20
20
  break;
21
21
  }
22
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
22
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
23
23
  }
24
24
  }
25
25
  exports.default = ENTimeUnitCasualRelativeFormatParser;
@@ -16,7 +16,7 @@ class ENTimeUnitLaterFormatParser extends AbstractParserWithWordBoundary_1.Abstr
16
16
  }
17
17
  innerExtract(context, match) {
18
18
  const fragments = constants_1.parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
19
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, fragments);
19
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, fragments);
20
20
  }
21
21
  }
22
22
  exports.default = ENTimeUnitLaterFormatParser;
@@ -12,7 +12,7 @@ class ENTimeUnitWithinFormatParser extends AbstractParserWithWordBoundary_1.Abst
12
12
  }
13
13
  innerExtract(context, match) {
14
14
  const timeUnits = constants_1.parseTimeUnits(match[1]);
15
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
15
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
16
16
  }
17
17
  }
18
18
  exports.default = ENTimeUnitWithinFormatParser;
@@ -98,7 +98,7 @@ exports.TIME_UNIT_DICTIONARY = {
98
98
  "année": "year",
99
99
  "années": "year",
100
100
  };
101
- exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|une?|quelques?|demi-?)`;
101
+ exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|une?\\b|quelques?|demi-?)`;
102
102
  function parseNumberPattern(match) {
103
103
  const num = match.toLowerCase();
104
104
  if (exports.INTEGER_WORD_DICTIONARY[num] !== undefined) {
@@ -14,7 +14,7 @@ class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBoundary_1.Abstrac
14
14
  innerExtract(context, match) {
15
15
  const timeUnits = constants_1.parseTimeUnits(match[1]);
16
16
  const outputTimeUnits = timeunits_1.reverseTimeUnits(timeUnits);
17
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
17
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
18
18
  }
19
19
  }
20
20
  exports.default = FRTimeUnitAgoFormatParser;
@@ -29,7 +29,7 @@ class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBoundary_1.Abstrac
29
29
  if (/derni[eè]re?s?/.test(modifier) || /pass[ée]e?s?/.test(modifier) || /pr[ée]c[ée]dents?/.test(modifier)) {
30
30
  timeUnits = timeunits_1.reverseTimeUnits(timeUnits);
31
31
  }
32
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
32
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
33
33
  }
34
34
  }
35
35
  exports.default = FRTimeUnitAgoFormatParser;
@@ -9,7 +9,7 @@ class FRTimeUnitWithinFormatParser extends AbstractParserWithWordBoundary_1.Abst
9
9
  }
10
10
  innerExtract(context, match) {
11
11
  const timeUnits = constants_1.parseTimeUnits(match[1]);
12
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
12
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
13
13
  }
14
14
  }
15
15
  exports.default = FRTimeUnitWithinFormatParser;
@@ -23,15 +23,15 @@ class NLRelativeDateFormatParser extends AbstractParserWithWordBoundary_1.Abstra
23
23
  if (modifier == "volgend" || modifier == "volgende" || modifier == "komende") {
24
24
  const timeUnits = {};
25
25
  timeUnits[timeunit] = 1;
26
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
26
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
27
27
  }
28
28
  if (modifier == "afgelopen" || modifier == "vorige") {
29
29
  const timeUnits = {};
30
30
  timeUnits[timeunit] = -1;
31
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
31
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
32
32
  }
33
33
  const components = context.createParsingComponents();
34
- let date = dayjs_1.default(context.refDate);
34
+ let date = dayjs_1.default(context.reference.instant);
35
35
  if (unitWord.match(/week/i)) {
36
36
  date = date.add(-date.get("d"), "d");
37
37
  components.imply("day", date.date());
@@ -17,7 +17,7 @@ class NLTimeUnitAgoFormatParser extends AbstractParserWithWordBoundary_1.Abstrac
17
17
  innerExtract(context, match) {
18
18
  const timeUnits = constants_1.parseTimeUnits(match[1]);
19
19
  const outputTimeUnits = timeunits_1.reverseTimeUnits(timeUnits);
20
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
20
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
21
21
  }
22
22
  }
23
23
  exports.default = NLTimeUnitAgoFormatParser;
@@ -19,7 +19,7 @@ class NLTimeUnitCasualRelativeFormatParser extends AbstractParserWithWordBoundar
19
19
  timeUnits = timeunits_1.reverseTimeUnits(timeUnits);
20
20
  break;
21
21
  }
22
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
22
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
23
23
  }
24
24
  }
25
25
  exports.default = NLTimeUnitCasualRelativeFormatParser;
@@ -16,7 +16,7 @@ class NLTimeUnitLaterFormatParser extends AbstractParserWithWordBoundary_1.Abstr
16
16
  }
17
17
  innerExtract(context, match) {
18
18
  const fragments = constants_1.parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
19
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, fragments);
19
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, fragments);
20
20
  }
21
21
  }
22
22
  exports.default = NLTimeUnitLaterFormatParser;
@@ -9,7 +9,7 @@ class NLTimeUnitWithinFormatParser extends AbstractParserWithWordBoundary_1.Abst
9
9
  }
10
10
  innerExtract(context, match) {
11
11
  const timeUnits = constants_1.parseTimeUnits(match[1]);
12
- return results_1.ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
12
+ return results_1.ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
13
13
  }
14
14
  }
15
15
  exports.default = NLTimeUnitWithinFormatParser;
package/dist/results.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Component, ParsedComponents, ParsedResult, ParsingReference } from "./i
2
2
  import dayjs, { OpUnitType, QUnitType } from "dayjs";
3
3
  export declare class ReferenceWithTimezone {
4
4
  readonly instant: Date;
5
- readonly timezoneOffset: number;
5
+ readonly timezoneOffset?: number;
6
6
  constructor(input?: ParsingReference | Date);
7
7
  }
8
8
  export declare class ParsingComponents implements ParsedComponents {
@@ -29,7 +29,7 @@ export declare class ParsingComponents implements ParsedComponents {
29
29
  date(): Date;
30
30
  private dateWithoutTimezoneAdjustment;
31
31
  private getSystemTimezoneAdjustmentMinute;
32
- static createRelativeFromRefInstant(refInstant: Date, fragments: {
32
+ static createRelativeFromReference(reference: ReferenceWithTimezone, fragments: {
33
33
  [c in OpUnitType | QUnitType]?: number;
34
34
  }): ParsingComponents;
35
35
  }
package/dist/results.js CHANGED
@@ -11,7 +11,7 @@ const timezone_1 = require("./timezone");
11
11
  dayjs_1.default.extend(quarterOfYear_1.default);
12
12
  class ReferenceWithTimezone {
13
13
  constructor(input) {
14
- var _a, _b;
14
+ var _a;
15
15
  input = input !== null && input !== void 0 ? input : new Date();
16
16
  if (input instanceof Date) {
17
17
  this.instant = input;
@@ -19,7 +19,7 @@ class ReferenceWithTimezone {
19
19
  }
20
20
  else {
21
21
  this.instant = (_a = input.instant) !== null && _a !== void 0 ? _a : new Date();
22
- this.timezoneOffset = timezone_1.toTimezoneOffset((_b = input.timezone) !== null && _b !== void 0 ? _b : -this.instant.getTimezoneOffset());
22
+ this.timezoneOffset = timezone_1.toTimezoneOffset(input.timezone);
23
23
  }
24
24
  }
25
25
  }
@@ -133,21 +133,24 @@ class ParsingComponents {
133
133
  const targetTimezoneOffset = (_a = this.get("timezoneOffset")) !== null && _a !== void 0 ? _a : this.reference.timezoneOffset;
134
134
  return currentTimezoneOffset - targetTimezoneOffset;
135
135
  }
136
- static createRelativeFromRefInstant(refInstant, fragments) {
137
- let date = dayjs_1.default(refInstant);
136
+ static createRelativeFromReference(reference, fragments) {
137
+ let date = dayjs_1.default(reference.instant);
138
138
  for (const key in fragments) {
139
139
  date = date.add(fragments[key], key);
140
140
  }
141
- const reference = new ReferenceWithTimezone(refInstant);
142
141
  const components = new ParsingComponents(reference);
143
142
  if (fragments["hour"] || fragments["minute"] || fragments["second"]) {
144
143
  dayjs_2.assignSimilarTime(components, date);
145
144
  dayjs_2.assignSimilarDate(components, date);
146
- components.assign("timezoneOffset", -refInstant.getTimezoneOffset());
145
+ if (reference.timezoneOffset !== null) {
146
+ components.assign("timezoneOffset", -reference.instant.getTimezoneOffset());
147
+ }
147
148
  }
148
149
  else {
149
150
  dayjs_2.implySimilarTime(components, date);
150
- components.imply("timezoneOffset", -refInstant.getTimezoneOffset());
151
+ if (reference.timezoneOffset !== null) {
152
+ components.imply("timezoneOffset", -reference.instant.getTimezoneOffset());
153
+ }
151
154
  if (fragments["d"]) {
152
155
  components.assign("day", date.date());
153
156
  components.assign("month", date.month() + 1);
@@ -191,4 +191,4 @@ export declare const TIMEZONE_ABBR_MAP: {
191
191
  YEKST: number;
192
192
  YEKT: number;
193
193
  };
194
- export declare function toTimezoneOffset(timezoneInput: string | number): number;
194
+ export declare function toTimezoneOffset(timezoneInput: string | number): number | null;
package/dist/timezone.js CHANGED
@@ -196,6 +196,9 @@ exports.TIMEZONE_ABBR_MAP = {
196
196
  };
197
197
  function toTimezoneOffset(timezoneInput) {
198
198
  var _a;
199
+ if (timezoneInput === null) {
200
+ return null;
201
+ }
199
202
  if (typeof timezoneInput === "number") {
200
203
  return timezoneInput;
201
204
  }
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "preset": "ts-jest"
16
16
  },
17
17
  "license": "MIT",
18
- "version": "2.3.2",
18
+ "version": "2.3.3",
19
19
  "directories": {
20
20
  "source": "./src",
21
21
  "test": "./test"
@@ -108,7 +108,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
108
108
 
109
109
  export const NUMBER_PATTERN = `(?:${matchAnyPattern(
110
110
  INTEGER_WORD_DICTIONARY
111
- )}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`;
111
+ )}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?\\b(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`;
112
112
 
113
113
  export function parseNumberPattern(match: string): number {
114
114
  const num = match.toLowerCase();
@@ -162,7 +162,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
162
162
 
163
163
  export const NUMBER_PATTERN = `(?:${matchAnyPattern(
164
164
  INTEGER_WORD_DICTIONARY
165
- )}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?(?:\\s{0,2}few)?|few|several|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
165
+ )}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?\\b(?:\\s{0,2}few)?|few|several|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
166
166
 
167
167
  export function parseNumberPattern(match: string): number {
168
168
  const num = match.toLowerCase();
@@ -26,17 +26,17 @@ export default class ENRelativeDateFormatParser extends AbstractParserWithWordBo
26
26
  if (modifier == "next") {
27
27
  const timeUnits = {};
28
28
  timeUnits[timeunit] = 1;
29
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
29
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
30
30
  }
31
31
 
32
32
  if (modifier == "last" || modifier == "past") {
33
33
  const timeUnits = {};
34
34
  timeUnits[timeunit] = -1;
35
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
35
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
36
36
  }
37
37
 
38
38
  const components = context.createParsingComponents();
39
- let date = dayjs(context.refDate);
39
+ let date = dayjs(context.reference.instant);
40
40
 
41
41
  // This week
42
42
  if (unitWord.match(/week/i)) {
@@ -20,6 +20,6 @@ export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBou
20
20
  const timeUnits = parseTimeUnits(match[1]);
21
21
  const outputTimeUnits = reverseTimeUnits(timeUnits);
22
22
 
23
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
23
+ return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
24
24
  }
25
25
  }
@@ -22,6 +22,6 @@ export default class ENTimeUnitCasualRelativeFormatParser extends AbstractParser
22
22
  break;
23
23
  }
24
24
 
25
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
25
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
26
26
  }
27
27
  }
@@ -22,6 +22,6 @@ export default class ENTimeUnitLaterFormatParser extends AbstractParserWithWordB
22
22
 
23
23
  innerExtract(context: ParsingContext, match: RegExpMatchArray) {
24
24
  const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
25
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, fragments);
25
+ return ParsingComponents.createRelativeFromReference(context.reference, fragments);
26
26
  }
27
27
  }
@@ -21,6 +21,6 @@ export default class ENTimeUnitWithinFormatParser extends AbstractParserWithWord
21
21
 
22
22
  innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
23
23
  const timeUnits = parseTimeUnits(match[1]);
24
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
24
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
25
25
  }
26
26
  }
@@ -105,7 +105,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType | QUnitType } =
105
105
 
106
106
  export const NUMBER_PATTERN = `(?:${matchAnyPattern(
107
107
  INTEGER_WORD_DICTIONARY
108
- )}|[0-9]+|[0-9]+\\.[0-9]+|une?|quelques?|demi-?)`;
108
+ )}|[0-9]+|[0-9]+\\.[0-9]+|une?\\b|quelques?|demi-?)`;
109
109
 
110
110
  export function parseNumberPattern(match: string): number {
111
111
  const num = match.toLowerCase();
@@ -17,6 +17,6 @@ export default class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBou
17
17
  const timeUnits = parseTimeUnits(match[1]);
18
18
  const outputTimeUnits = reverseTimeUnits(timeUnits);
19
19
 
20
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
20
+ return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
21
21
  }
22
22
  }
@@ -38,6 +38,6 @@ export default class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBou
38
38
  timeUnits = reverseTimeUnits(timeUnits);
39
39
  }
40
40
 
41
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
41
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
42
42
  }
43
43
  }
@@ -10,6 +10,6 @@ export default class FRTimeUnitWithinFormatParser extends AbstractParserWithWord
10
10
 
11
11
  innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
12
12
  const timeUnits = parseTimeUnits(match[1]);
13
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
13
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
14
14
  }
15
15
  }
@@ -27,17 +27,17 @@ export default class NLRelativeDateFormatParser extends AbstractParserWithWordBo
27
27
  if (modifier == "volgend" || modifier == "volgende" || modifier == "komende") {
28
28
  const timeUnits = {};
29
29
  timeUnits[timeunit] = 1;
30
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
30
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
31
31
  }
32
32
 
33
33
  if (modifier == "afgelopen" || modifier == "vorige") {
34
34
  const timeUnits = {};
35
35
  timeUnits[timeunit] = -1;
36
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
36
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
37
37
  }
38
38
 
39
39
  const components = context.createParsingComponents();
40
- let date = dayjs(context.refDate);
40
+ let date = dayjs(context.reference.instant);
41
41
 
42
42
  // This week
43
43
  if (unitWord.match(/week/i)) {
@@ -21,6 +21,6 @@ export default class NLTimeUnitAgoFormatParser extends AbstractParserWithWordBou
21
21
  const timeUnits = parseTimeUnits(match[1]);
22
22
  const outputTimeUnits = reverseTimeUnits(timeUnits);
23
23
 
24
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, outputTimeUnits);
24
+ return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
25
25
  }
26
26
  }
@@ -22,6 +22,6 @@ export default class NLTimeUnitCasualRelativeFormatParser extends AbstractParser
22
22
  break;
23
23
  }
24
24
 
25
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
25
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
26
26
  }
27
27
  }
@@ -22,6 +22,6 @@ export default class NLTimeUnitLaterFormatParser extends AbstractParserWithWordB
22
22
 
23
23
  innerExtract(context: ParsingContext, match: RegExpMatchArray) {
24
24
  const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
25
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, fragments);
25
+ return ParsingComponents.createRelativeFromReference(context.reference, fragments);
26
26
  }
27
27
  }
@@ -10,6 +10,6 @@ export default class NLTimeUnitWithinFormatParser extends AbstractParserWithWord
10
10
 
11
11
  innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
12
12
  const timeUnits = parseTimeUnits(match[1]);
13
- return ParsingComponents.createRelativeFromRefInstant(context.refDate, timeUnits);
13
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
14
14
  }
15
15
  }
package/src/results.ts CHANGED
@@ -8,7 +8,7 @@ dayjs.extend(quarterOfYear);
8
8
 
9
9
  export class ReferenceWithTimezone {
10
10
  readonly instant: Date;
11
- readonly timezoneOffset: number;
11
+ readonly timezoneOffset?: number;
12
12
 
13
13
  constructor(input?: ParsingReference | Date) {
14
14
  input = input ?? new Date();
@@ -17,7 +17,7 @@ export class ReferenceWithTimezone {
17
17
  this.timezoneOffset = -input.getTimezoneOffset();
18
18
  } else {
19
19
  this.instant = input.instant ?? new Date();
20
- this.timezoneOffset = toTimezoneOffset(input.timezone ?? -this.instant.getTimezoneOffset());
20
+ this.timezoneOffset = toTimezoneOffset(input.timezone);
21
21
  }
22
22
  }
23
23
  }
@@ -167,24 +167,27 @@ export class ParsingComponents implements ParsedComponents {
167
167
  return currentTimezoneOffset - targetTimezoneOffset;
168
168
  }
169
169
 
170
- static createRelativeFromRefInstant(
171
- refInstant: Date,
170
+ static createRelativeFromReference(
171
+ reference: ReferenceWithTimezone,
172
172
  fragments: { [c in OpUnitType | QUnitType]?: number }
173
173
  ): ParsingComponents {
174
- let date = dayjs(refInstant);
174
+ let date = dayjs(reference.instant);
175
175
  for (const key in fragments) {
176
176
  date = date.add(fragments[key as OpUnitType], key as OpUnitType);
177
177
  }
178
178
 
179
- const reference = new ReferenceWithTimezone(refInstant);
180
179
  const components = new ParsingComponents(reference);
181
180
  if (fragments["hour"] || fragments["minute"] || fragments["second"]) {
182
181
  assignSimilarTime(components, date);
183
182
  assignSimilarDate(components, date);
184
- components.assign("timezoneOffset", -refInstant.getTimezoneOffset());
183
+ if (reference.timezoneOffset !== null) {
184
+ components.assign("timezoneOffset", -reference.instant.getTimezoneOffset());
185
+ }
185
186
  } else {
186
187
  implySimilarTime(components, date);
187
- components.imply("timezoneOffset", -refInstant.getTimezoneOffset());
188
+ if (reference.timezoneOffset !== null) {
189
+ components.imply("timezoneOffset", -reference.instant.getTimezoneOffset());
190
+ }
188
191
 
189
192
  if (fragments["d"]) {
190
193
  components.assign("day", date.date());
package/src/timezone.ts CHANGED
@@ -192,7 +192,11 @@ export const TIMEZONE_ABBR_MAP = {
192
192
  YEKT: 360,
193
193
  };
194
194
 
195
- export function toTimezoneOffset(timezoneInput: string | number): number {
195
+ export function toTimezoneOffset(timezoneInput: string | number): number | null {
196
+ if (timezoneInput === null) {
197
+ return null;
198
+ }
199
+
196
200
  if (typeof timezoneInput === "number") {
197
201
  return timezoneInput;
198
202
  }
@@ -230,4 +230,12 @@ test("Test - Relative date components' certainty and imply timezone", () => {
230
230
  expect(result).toBeDate(new Date("Sun Nov 29 2020 13:34:13 GMT+0900 (Japan Standard Time)"));
231
231
  expect(result).toBeDate(new Date("Sun Nov 29 2020 5:34:13 GMT+0100"));
232
232
  }
233
+
234
+ {
235
+ const text = "in 20 minutes";
236
+ const result = chrono.parse(text, { instant: refDate, timezone: null })[0] as ParsingResult;
237
+
238
+ expect(result.text).toBe(text);
239
+ expect(result.start.isCertain("timezoneOffset")).toBe(false);
240
+ }
233
241
  });
@@ -21,6 +21,8 @@ test("Test - Skip random non-date patterns", function () {
21
21
  testUnexpectedResult(chrono, "Total: $1,194.09 [image: View Reservation");
22
22
 
23
23
  testUnexpectedResult(chrono, "at 6.5 kilograms");
24
+
25
+ testUnexpectedResult(chrono, "ah that is unusual", null, { forwardDate: true });
24
26
  });
25
27
 
26
28
  test("Test - URLs % encoded", function () {
package/test/test_util.ts CHANGED
@@ -61,10 +61,13 @@ export function testWithExpectedDate(chrono: ChronoLike, text: string, expectedD
61
61
  });
62
62
  }
63
63
 
64
- export function testUnexpectedResult(chrono: ChronoLike, text: string, refDate?: Date) {
64
+ export function testUnexpectedResult(chrono: ChronoLike, text: string, refDate?: Date, options?: ParsingOption) {
65
65
  const debugHandler = new BufferedDebugHandler();
66
+ options = options || {};
67
+ options.debug = debugHandler;
68
+
66
69
  try {
67
- const results = chrono.parse(text, refDate, { debug: debugHandler });
70
+ const results = chrono.parse(text, refDate, options);
68
71
  expect(results).toHaveLength(0);
69
72
  } catch (e) {
70
73
  debugHandler.executeBufferedBlocks();