mdtg 3.2.0 → 4.0.0

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
@@ -11,18 +11,20 @@ npm install mdtg
11
11
  ### Usage
12
12
 
13
13
  ```js
14
- import { parse, formatMDTG } from "mdtg";
14
+ import { formatMDTG, parseMDTG } from "mdtg";
15
15
 
16
- const date = new Date();
16
+ const date = new Date(Date.UTC(2024, 7, 12, 11, 55, 30));
17
17
 
18
- console.log(formatMDTG(date, { form: "short" }));
19
- console.log(formatMDTG(date, { form: "shortened" }));
20
- console.log(formatMDTG(date, { form: "long" }));
18
+ formatMDTG(date, { form: "short" }); // "121155Z"
19
+ formatMDTG(date, { form: "standard" }); // "121155Zaug24"
20
+ formatMDTG(date); // "12115530Zaug24" (extended by default)
21
21
 
22
- console.log(parse("12135530Zaug24"));
23
- console.log(parse("12135530Asep24"));
24
- console.log(parse("121355LOCT24"));
25
- console.log(parse("121355M"));
22
+ // A is UTC+1, so local time is one hour ahead of UTC.
23
+ const value = formatMDTG(date, { timezone: "A" }); // "12125530Aaug24"
24
+ parseMDTG(value).toISOString(); // "2024-08-12T11:55:30.000Z"
25
+
26
+ parseMDTG("121155Zaug24").toISOString(); // "2024-08-12T11:55:00.000Z"
27
+ parseMDTG("121155Z"); // month and year are current UTC month/year
26
28
  ```
27
29
 
28
30
  ### API
@@ -30,23 +32,57 @@ console.log(parse("121355M"));
30
32
  #### `formatMDTG(date, options)`
31
33
 
32
34
  Converts a valid `Date` to a date-time group. `date` defaults to the current
33
- date. `options.form` is `"short"`, `"shortened"`, or `"long"` (the default).
35
+ date. `options.form` is `"short"`, `"standard"`, or `"extended"` (the default).
34
36
  `options.timezone` accepts the NATO time-zone letters `A` through `Z`;
35
- lowercase letters are accepted and unknown values default to `Z`.
37
+ lowercase letters are accepted and unknown values default to `Z`. The timezone
38
+ letter determines the displayed local time; parsing converts it back to a UTC
39
+ `Date`.
36
40
 
37
41
  ```js
38
42
  formatMDTG(new Date(Date.UTC(2024, 7, 12, 11, 55, 30)), {
39
- form: "long",
43
+ form: "extended",
40
44
  timezone: "A",
41
45
  });
42
46
  // "12125530Aaug24"
43
47
  ```
44
48
 
45
- #### `parse(value)`
49
+ #### `parseMDTG(value)`
46
50
 
47
- Parses short (`121155Z`), shortened (`121155Zaug24`), and long
51
+ Parses short (`121155Z`), standard (`121155Zaug24`), and extended
48
52
  (`12115530Zaug24`) formats into a `Date`. Short values use the current UTC
49
- month and year. Years are interpreted as `2000` through `2099`.
53
+ month and year and have no seconds. Years are interpreted as `2000` through
54
+ `2099`.
55
+
56
+ ```js
57
+ import { parseMDTG } from "mdtg";
58
+
59
+ parseMDTG("121155Zaug24").toISOString(); // "2024-08-12T11:55:00.000Z"
60
+ parseMDTG("12115530Zaug24").toISOString(); // "2024-08-12T11:55:30.000Z"
61
+ parseMDTG("12125530Aaug24").toISOString(); // "2024-08-12T11:55:30.000Z"
62
+
63
+ parseMDTG("121155Z"); // uses the current UTC month and year
64
+ ```
50
65
 
51
66
  Invalid calendar dates and times, such as `310224Zfeb24` or `126155Z`, throw a
52
67
  `RangeError`. Other invalid values throw an `Error`.
68
+
69
+ #### Format checks
70
+
71
+ `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.
74
+
75
+ ```js
76
+ import {
77
+ isShortFormat,
78
+ isStandardFormat,
79
+ isExtendedFormat,
80
+ isMDTG,
81
+ } from "mdtg";
82
+
83
+ isShortFormat("121155Z"); // true
84
+ isStandardFormat("121155Zaug24"); // true
85
+ isExtendedFormat("12115530Zaug24"); // true
86
+ isMDTG("121155Zaug24"); // true
87
+ isMDTG("invalid"); // false
88
+ ```
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "mdtg",
3
- "version": "3.2.0",
3
+ "version": "4.0.0",
4
4
  "main": "src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./src/index.js"
8
8
  },
9
9
  "engines": {
10
- "node": ">=22.0.0",
10
+ "node": ">=24.0.0",
11
11
  "npm": ">=10.0.0"
12
12
  },
13
13
  "scripts": {
@@ -16,6 +16,7 @@
16
16
  "format": "biome check .",
17
17
  "prelint": "npm run format && npm run prettier",
18
18
  "lint": "biome lint .",
19
+ "knip": "knip",
19
20
  "prettier": "prettier **/*.yml",
20
21
  "test": "vitest run"
21
22
  },
@@ -30,7 +31,8 @@
30
31
  "devDependencies": {
31
32
  "@biomejs/biome": "2.5.14",
32
33
  "@vitest/coverage-v8": "5.0.1",
33
- "prettier": "3.9.8",
34
+ "knip": "6.38.0",
35
+ "prettier": "3.9.9",
34
36
  "vitest": "5.0.1"
35
37
  }
36
38
  }
package/src/constants.js CHANGED
@@ -43,13 +43,13 @@ export const OFFSETS = Object.freeze({
43
43
  });
44
44
 
45
45
  export const SHORT_FORMAT_REGEX = /^[0-9]{6}[A-Z]$/;
46
- export const SHORTENED_FORMAT_REGEX =
46
+ export const STANDARD_FORMAT_REGEX =
47
47
  /^[0-9]{6}[A-Z](jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[0-9]{2}$/i;
48
- export const LONG_FORMAT_REGEX =
48
+ export const EXTENDED_FORMAT_REGEX =
49
49
  /^[0-9]{8}[A-Z](jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[0-9]{2}$/i;
50
50
 
51
51
  export const FORM = Object.freeze({
52
52
  SHORT: "short",
53
- SHORTENED: "shortened",
54
- LONG: "long",
53
+ STANDARD: "standard",
54
+ EXTENDED: "extended",
55
55
  });
package/src/format.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { FORM, MONTHS, OFFSETS } from "./constants.js";
2
2
  import {
3
- isLongFormat,
4
- isShortenedFormat,
3
+ isExtendedFormat,
5
4
  isShortFormat,
5
+ isStandardFormat,
6
6
  validateDate,
7
7
  validateTimezone,
8
8
  } from "./validation.js";
@@ -25,7 +25,7 @@ const buildShort = (date, timezone) => {
25
25
  return result;
26
26
  };
27
27
 
28
- const buildLong = (date, timezone) => {
28
+ const buildExtended = (date, timezone) => {
29
29
  const result = [
30
30
  date.getUTCDate(),
31
31
  date.getUTCHours(),
@@ -40,22 +40,22 @@ const buildLong = (date, timezone) => {
40
40
  )
41
41
  .join("");
42
42
 
43
- if (!isLongFormat(result)) {
44
- throw new Error("Failed to build long MDTG");
43
+ if (!isExtendedFormat(result)) {
44
+ throw new Error("Failed to build extended MDTG");
45
45
  }
46
46
 
47
47
  return result;
48
48
  };
49
49
 
50
- const buildShortened = (date, timezone) => {
50
+ const buildStandard = (date, timezone) => {
51
51
  const result = [
52
52
  buildShort(date, timezone),
53
53
  MONTHS[date.getUTCMonth()],
54
54
  normalizeNumber(date.getUTCFullYear() % 100),
55
55
  ].join("");
56
56
 
57
- if (!isShortenedFormat(result)) {
58
- throw new Error("Failed to build shortened MDTG");
57
+ if (!isStandardFormat(result)) {
58
+ throw new Error("Failed to build standard MDTG");
59
59
  }
60
60
 
61
61
  return result;
@@ -63,7 +63,7 @@ const buildShortened = (date, timezone) => {
63
63
 
64
64
  export const formatMDTG = (
65
65
  date = new Date(),
66
- { form = FORM.LONG, timezone: timezoneInput = "Z" } = {},
66
+ { form = FORM.EXTENDED, timezone: timezoneInput = "Z" } = {},
67
67
  ) => {
68
68
  validateDate(date);
69
69
 
@@ -73,9 +73,9 @@ export const formatMDTG = (
73
73
  switch (form) {
74
74
  case FORM.SHORT:
75
75
  return buildShort(adjustedDate, timezone);
76
- case FORM.SHORTENED:
77
- return buildShortened(adjustedDate, timezone);
76
+ case FORM.STANDARD:
77
+ return buildStandard(adjustedDate, timezone);
78
78
  default:
79
- return buildLong(adjustedDate, timezone);
79
+ return buildExtended(adjustedDate, timezone);
80
80
  }
81
81
  };
package/src/index.js CHANGED
@@ -1,8 +1,8 @@
1
- export { FORM } from "./constants.js";
2
1
  export { formatMDTG } from "./format.js";
3
- export { parse } from "./parse.js";
2
+ export { parseMDTG } from "./parse.js";
4
3
  export {
5
- isLongFormat,
6
- isShortenedFormat,
4
+ isExtendedFormat,
5
+ isMDTG,
7
6
  isShortFormat,
7
+ isStandardFormat,
8
8
  } from "./validation.js";
package/src/parse.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { MONTHS, OFFSETS } from "./constants.js";
2
2
  import {
3
- isLongFormat,
4
- isShortenedFormat,
3
+ isExtendedFormat,
5
4
  isShortFormat,
5
+ isStandardFormat,
6
6
  validateDateTime,
7
7
  } from "./validation.js";
8
8
 
@@ -60,16 +60,16 @@ const parseWithMonth = (value, { hasSeconds, timezoneIndex, monthStart }) => {
60
60
  return new Date(Date.UTC(...dateParts));
61
61
  };
62
62
 
63
- export const parse = (value) => {
63
+ export const parseMDTG = (value) => {
64
64
  if (isShortFormat(value)) return parseShort(value);
65
- if (isShortenedFormat(value)) {
65
+ if (isStandardFormat(value)) {
66
66
  return parseWithMonth(value, {
67
67
  hasSeconds: false,
68
68
  timezoneIndex: 6,
69
69
  monthStart: 7,
70
70
  });
71
71
  }
72
- if (isLongFormat(value)) {
72
+ if (isExtendedFormat(value)) {
73
73
  return parseWithMonth(value, {
74
74
  hasSeconds: true,
75
75
  timezoneIndex: 8,
package/src/validation.js CHANGED
@@ -1,18 +1,21 @@
1
1
  import {
2
- LONG_FORMAT_REGEX,
2
+ EXTENDED_FORMAT_REGEX,
3
3
  OFFSETS,
4
4
  SHORT_FORMAT_REGEX,
5
- SHORTENED_FORMAT_REGEX,
5
+ STANDARD_FORMAT_REGEX,
6
6
  } from "./constants.js";
7
7
 
8
8
  export const isShortFormat = (value) =>
9
9
  typeof value === "string" && SHORT_FORMAT_REGEX.test(value);
10
10
 
11
- export const isShortenedFormat = (value) =>
12
- typeof value === "string" && SHORTENED_FORMAT_REGEX.test(value);
11
+ export const isStandardFormat = (value) =>
12
+ typeof value === "string" && STANDARD_FORMAT_REGEX.test(value);
13
13
 
14
- export const isLongFormat = (value) =>
15
- typeof value === "string" && LONG_FORMAT_REGEX.test(value);
14
+ export const isExtendedFormat = (value) =>
15
+ typeof value === "string" && EXTENDED_FORMAT_REGEX.test(value);
16
+
17
+ export const isMDTG = (value) =>
18
+ isShortFormat(value) || isStandardFormat(value) || isExtendedFormat(value);
16
19
 
17
20
  export const validateDate = (date) => {
18
21
  if (!(date instanceof Date) || Number.isNaN(date.getTime())) {