mdtg 4.0.0 → 4.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 CHANGED
@@ -46,7 +46,7 @@ formatMDTG(new Date(Date.UTC(2024, 7, 12, 11, 55, 30)), {
46
46
  // "12125530Aaug24"
47
47
  ```
48
48
 
49
- #### `parseMDTG(value)`
49
+ #### `parseMDTG(value, options)`
50
50
 
51
51
  Parses short (`121155Z`), standard (`121155Zaug24`), and extended
52
52
  (`12115530Zaug24`) formats into a `Date`. Short values use the current UTC
@@ -61,16 +61,24 @@ parseMDTG("12115530Zaug24").toISOString(); // "2024-08-12T11:55:30.000Z"
61
61
  parseMDTG("12125530Aaug24").toISOString(); // "2024-08-12T11:55:30.000Z"
62
62
 
63
63
  parseMDTG("121155Z"); // uses the current UTC month and year
64
+
65
+ parseMDTG("121155Z", {
66
+ referenceDate: new Date(Date.UTC(2024, 7, 1)),
67
+ }); // uses August 2024, independent of the system date
64
68
  ```
65
69
 
66
70
  Invalid calendar dates and times, such as `310224Zfeb24` or `126155Z`, throw a
67
71
  `RangeError`. Other invalid values throw an `Error`.
68
72
 
73
+ `referenceDate` is an optional valid `Date` used only for short values that omit
74
+ the month and year. If omitted, the current UTC month and year are used.
75
+
69
76
  #### Format checks
70
77
 
71
78
  `isShortFormat`, `isStandardFormat`, and `isExtendedFormat` check whether a string
72
- matches the structure of the corresponding format. `isMDTG` checks
73
- whether a string matches any of the three formats.
79
+ matches the structure of the corresponding format. `isMDTG` checks whether a
80
+ string matches any of the three structures. These checks do not validate
81
+ calendar dates or times; use `isValidMDTG` when semantic validity is needed.
74
82
 
75
83
  ```js
76
84
  import {
@@ -78,6 +86,7 @@ import {
78
86
  isStandardFormat,
79
87
  isExtendedFormat,
80
88
  isMDTG,
89
+ isValidMDTG,
81
90
  } from "mdtg";
82
91
 
83
92
  isShortFormat("121155Z"); // true
@@ -85,4 +94,9 @@ isStandardFormat("121155Zaug24"); // true
85
94
  isExtendedFormat("12115530Zaug24"); // true
86
95
  isMDTG("121155Zaug24"); // true
87
96
  isMDTG("invalid"); // false
97
+ isMDTG("310224Zfeb24"); // true: structurally valid
98
+ isValidMDTG("310224Zfeb24"); // false: invalid calendar date
88
99
  ```
100
+
101
+ For short values, `isValidMDTG` also accepts the same optional `referenceDate`
102
+ as `parseMDTG`.
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "mdtg",
3
- "version": "4.0.0",
3
+ "version": "4.1.1",
4
4
  "main": "src/index.js",
5
+ "types": "src/index.d.ts",
5
6
  "type": "module",
6
7
  "exports": {
7
- ".": "./src/index.js"
8
+ ".": {
9
+ "types": "./src/index.d.ts",
10
+ "import": "./src/index.js"
11
+ }
8
12
  },
9
13
  "engines": {
10
14
  "node": ">=24.0.0",
@@ -29,10 +33,10 @@
29
33
  "license": "MIT",
30
34
  "description": "This package offers you methods to convert Date Objects to military date time and vice versa",
31
35
  "devDependencies": {
32
- "@biomejs/biome": "2.5.14",
33
- "@vitest/coverage-v8": "5.0.1",
34
- "knip": "6.38.0",
36
+ "@biomejs/biome": "2.5.15",
37
+ "@vitest/coverage-v8": "5.0.3",
38
+ "knip": "6.39.0",
35
39
  "prettier": "3.9.9",
36
- "vitest": "5.0.1"
40
+ "vitest": "5.0.3"
37
41
  }
38
42
  }
package/src/index.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ type MDTGFormat = "short" | "extended" | "standard";
2
+
3
+ declare function formatMDTG(
4
+ date?: Date,
5
+ options?: { form?: MDTGFormat; timezone?: string },
6
+ ): string;
7
+
8
+ declare function isValidMDTG(
9
+ mdtg: string,
10
+ options?: { referenceDate?: Date },
11
+ ): boolean;
12
+ declare function parseMDTG(
13
+ mdtg: string,
14
+ options?: { referenceDate?: Date },
15
+ ): Date;
16
+
17
+ declare function isExtendedFormat(mdtg: string): boolean;
18
+ declare function isMDTG(mdtg: string): boolean;
19
+ declare function isShortFormat(mdtg: string): boolean;
20
+ declare function isStandardFormat(mdtg: string): boolean;
21
+
22
+ export type { MDTGFormat };
23
+
24
+ export {
25
+ formatMDTG,
26
+ isExtendedFormat,
27
+ isMDTG,
28
+ isShortFormat,
29
+ isStandardFormat,
30
+ isValidMDTG,
31
+ parseMDTG,
32
+ };
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { formatMDTG } from "./format.js";
2
- export { parseMDTG } from "./parse.js";
2
+ export { isValidMDTG, parseMDTG } from "./parse.js";
3
3
  export {
4
4
  isExtendedFormat,
5
5
  isMDTG,
package/src/parse.js CHANGED
@@ -1,37 +1,34 @@
1
1
  import { MONTHS, OFFSETS } from "./constants.js";
2
2
  import {
3
3
  isExtendedFormat,
4
+ isMDTG,
4
5
  isShortFormat,
5
6
  isStandardFormat,
7
+ validateDate,
6
8
  validateDateTime,
7
9
  } from "./validation.js";
8
10
 
9
11
  const parseInteger = (input) => Number.parseInt(input, 10);
10
12
 
11
- const parseShort = (value) => {
13
+ const parseShort = (value, referenceDate) => {
12
14
  const day = parseInteger(value.slice(0, 2));
13
15
  const hours = parseInteger(value.slice(2, 4));
14
16
  const minutes = parseInteger(value.slice(4, 6));
15
17
  const timezone = value.slice(6, 7).toUpperCase();
16
- const now = new Date();
18
+ validateDate(referenceDate);
17
19
 
18
20
  validateDateTime({
19
- year: now.getUTCFullYear(),
20
- month: now.getUTCMonth(),
21
+ year: referenceDate.getUTCFullYear(),
22
+ month: referenceDate.getUTCMonth(),
21
23
  day,
22
24
  hours,
23
25
  minutes,
24
26
  });
25
27
 
26
- return new Date(
27
- Date.UTC(
28
- now.getUTCFullYear(),
29
- now.getUTCMonth(),
30
- day,
31
- hours + OFFSETS[timezone],
32
- minutes,
33
- ),
34
- );
28
+ const result = new Date(referenceDate);
29
+ result.setUTCDate(day);
30
+ result.setUTCHours(hours + OFFSETS[timezone], minutes, 0, 0);
31
+ return result;
35
32
  };
36
33
 
37
34
  const parseWithMonth = (value, { hasSeconds, timezoneIndex, monthStart }) => {
@@ -60,8 +57,8 @@ const parseWithMonth = (value, { hasSeconds, timezoneIndex, monthStart }) => {
60
57
  return new Date(Date.UTC(...dateParts));
61
58
  };
62
59
 
63
- export const parseMDTG = (value) => {
64
- if (isShortFormat(value)) return parseShort(value);
60
+ export const parseMDTG = (value, { referenceDate = new Date() } = {}) => {
61
+ if (isShortFormat(value)) return parseShort(value, referenceDate);
65
62
  if (isStandardFormat(value)) {
66
63
  return parseWithMonth(value, {
67
64
  hasSeconds: false,
@@ -79,3 +76,15 @@ export const parseMDTG = (value) => {
79
76
 
80
77
  throw new Error(`Invalid MDTG string "${value}"`);
81
78
  };
79
+
80
+ export const isValidMDTG = (value, options) => {
81
+ if (!isMDTG(value)) return false;
82
+
83
+ try {
84
+ parseMDTG(value, options);
85
+ return true;
86
+ } catch (error) {
87
+ if (error instanceof RangeError) return false;
88
+ throw error;
89
+ }
90
+ };
package/src/validation.js CHANGED
@@ -36,9 +36,9 @@ export const validateDateTime = ({
36
36
  minutes,
37
37
  seconds,
38
38
  }) => {
39
- const candidate = new Date(
40
- Date.UTC(year, month, day, hours, minutes, seconds ?? 0),
41
- );
39
+ const candidate = new Date(0);
40
+ candidate.setUTCFullYear(year, month, day);
41
+ candidate.setUTCHours(hours, minutes, seconds ?? 0, 0);
42
42
 
43
43
  if (
44
44
  candidate.getUTCFullYear() !== year ||