@eliasrrosa/tutorhub-public-assets 0.8.0 → 0.8.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.
@@ -1,39 +1,44 @@
1
- import { IDate } from "./Date";
2
- import { ITime } from "./Time";
3
1
  export interface IDateTime {
4
- getJSDateTime: () => Date;
2
+ getJsDateTime: () => Date;
5
3
  /**
6
- * Returns DateTime string with added Brazilian timezone (-03:00) without converting the date or time.
7
- * This function is analogous to ISO8601DateTime.getIsoString(-180)
8
- * @returns an ISO8601 string with Brazilian timezone
9
- */
10
- getBrazilianIsoString: () => string;
11
- /**
12
- * Returns DateTime string with added timezone (eg. +03:00, -01:00, .000Z) without converting the date or time.
13
- * @param timezoneOffsetMinutes defaults to 0.
14
- * Can be derived from the negative return value of Date.getTimezoneOffset()
15
- * @param newDate overrides the date for the output string, but does not change state.
16
- * @param newTime overrides the time for the output string, but does not change state.
17
- * @returns an ISO8601 string with the added timezone.
4
+ * @returns the same date but time is 00:00:00.000
18
5
  */
6
+ toMidnight: () => IDateTime;
19
7
  getIsoString: (opts?: {
20
- timezoneOffsetMinutes?: number;
21
- newDate?: IDate;
22
- newTime?: ITime;
8
+ timezone?: string | number;
23
9
  }) => string;
10
+ /**
11
+ * @returns a time string without timezone like "13:30:00"
12
+ */
13
+ getTimeString: () => string;
14
+ getHoursString: () => string;
15
+ getMinutesString: () => string;
16
+ getSecondsString: () => string;
17
+ getMilisecondsString: () => string;
24
18
  }
25
19
  export declare class ISO8601DateTime implements IDateTime {
26
- private date;
27
- private time;
28
- constructor(opts: {
29
- date: IDate;
30
- time: ITime;
31
- });
32
- getJSDateTime: () => Date;
33
- getBrazilianIsoString: () => string;
34
- getIsoString(opts?: {
35
- timezoneOffsetMinutes?: number;
36
- newDate?: IDate;
37
- newTime?: ITime;
38
- }): string;
20
+ private readonly timeFormatValidator;
21
+ private readonly dateFormatValidator;
22
+ private readonly dateString;
23
+ private readonly timeUnitConverter;
24
+ dateTimePattern: RegExp;
25
+ onlyDatePattern: RegExp;
26
+ constructor(
27
+ /**
28
+ * Accepts ISO8601 date time format with timezone.
29
+ * Eg:. `2025-01-01T00:00:00Z`, `2025-01-01T00:00:00.000Z`,
30
+ * `2025-01-01T00:00:00-03:00`, `2025-01-01T00:00:00+04:00`
31
+ */
32
+ dateString: string);
33
+ private normalizeDateString;
34
+ getTimeString: () => string;
35
+ getHoursString: () => string;
36
+ getMinutesString: () => string;
37
+ getSecondsString: () => string;
38
+ getMilisecondsString: () => string;
39
+ getJsDateTime: () => Date;
40
+ getIsoString: (opts?: {
41
+ timezone?: string | number;
42
+ }) => string;
43
+ toMidnight: () => IDateTime;
39
44
  }
@@ -1,44 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ISO8601DateTime = void 0;
4
+ const ISO8601DateValidator_1 = require("./ISO8601DateValidator");
5
+ const ISO8601TimeValidator_1 = require("./ISO8601TimeValidator");
6
+ const ISO8601TimezoneParser_1 = require("./ISO8601TimezoneParser");
7
+ const ISO8601TimezoneValidator_1 = require("./ISO8601TimezoneValidator");
8
+ const TimeUnitConverter_1 = require("./TimeUnitConverter");
4
9
  class ISO8601DateTime {
5
- constructor(opts) {
6
- this.getJSDateTime = () => {
7
- return new Date(parseInt(this.date.getYear()), parseInt(this.date.getMonth()) - 1, parseInt(this.date.getDay()), parseInt(this.time.getHoursString()), parseInt(this.time.getMinutesString()), parseInt(this.time.getSecondsString()));
10
+ constructor(
11
+ /**
12
+ * Accepts ISO8601 date time format with timezone.
13
+ * Eg:. `2025-01-01T00:00:00Z`, `2025-01-01T00:00:00.000Z`,
14
+ * `2025-01-01T00:00:00-03:00`, `2025-01-01T00:00:00+04:00`
15
+ */
16
+ dateString) {
17
+ this.timeFormatValidator = new ISO8601TimeValidator_1.ISO8601TimeValidator();
18
+ this.dateFormatValidator = new ISO8601DateValidator_1.ISO8601DateValidator();
19
+ this.timeUnitConverter = new TimeUnitConverter_1.TimeUnitConverter();
20
+ this.dateTimePattern = new RegExp(`^${this.dateFormatValidator.YYYYmmDDpatternString}T(${this.timeFormatValidator.hhMMssPlusNumberedTimezonePatternString}|${this.timeFormatValidator.hhMMssSSSZPatternString}|${this.timeFormatValidator.hhMMssZPatternString})$`);
21
+ this.onlyDatePattern = new RegExp(`^${this.dateFormatValidator.YYYYmmDDpatternString}$`);
22
+ this.getTimeString = () => {
23
+ return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}`;
8
24
  };
9
- this.getBrazilianIsoString = () => {
10
- return this.getIsoString({
11
- timezoneOffsetMinutes: -180,
12
- });
25
+ this.getHoursString = () => {
26
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[0];
13
27
  };
14
- this.date = opts.date;
15
- this.time = opts.time;
28
+ this.getMinutesString = () => {
29
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[1];
30
+ };
31
+ this.getSecondsString = () => {
32
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[2];
33
+ };
34
+ this.getMilisecondsString = () => {
35
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[3];
36
+ };
37
+ this.getJsDateTime = () => {
38
+ return new Date(this.dateString);
39
+ };
40
+ this.getIsoString = (opts) => {
41
+ if (!opts || !(opts === null || opts === void 0 ? void 0 : opts.timezone))
42
+ return this.getJsDateTime().toISOString();
43
+ const parser = new ISO8601TimezoneParser_1.ISO8601TimezoneParser();
44
+ const validator = new ISO8601TimezoneValidator_1.ISO8601TimezoneValidator();
45
+ const timezoneInMinutes = typeof opts.timezone == "string"
46
+ ? parser.toMinutes(opts.timezone)
47
+ : opts.timezone;
48
+ const isValid = validator.formatIsValid(timezoneInMinutes);
49
+ if (!isValid)
50
+ throw new Error("Invalid timezone format.");
51
+ const timezoneInMs = this.timeUnitConverter.minutesToMs(timezoneInMinutes);
52
+ const newDateUtcString = new Date(this.getJsDateTime().getTime() + timezoneInMs).toISOString();
53
+ const newDateUtcStringWithoutTimezone = newDateUtcString.split(".")[0];
54
+ const timezoneString = parser.toString(timezoneInMinutes);
55
+ const newDateWithTimezoneString = `${newDateUtcStringWithoutTimezone}${timezoneString}`;
56
+ return newDateWithTimezoneString;
57
+ };
58
+ this.toMidnight = () => {
59
+ const currentTimeString = this.getTimeString();
60
+ const matches = new RegExp(currentTimeString).exec(this.dateString);
61
+ if (!matches || matches.length < 1)
62
+ throw new Error("Error getting current time string.");
63
+ const datePlusT = this.dateString.slice(0, matches.index);
64
+ const matchedString = matches[0];
65
+ const timezone = this.dateString.slice(matchedString.length + matches.index);
66
+ return new ISO8601DateTime(`${datePlusT}00:00:00${timezone}`);
67
+ };
68
+ const normalizedDateString = this.normalizeDateString(dateString);
69
+ if (!normalizedDateString)
70
+ throw new Error("Date time format invalid.");
71
+ this.dateString = normalizedDateString;
16
72
  }
17
- getIsoString(opts) {
18
- const padLeft = (n) => String(n).padStart(2, "0");
19
- const newDateTime = new ISO8601DateTime({
20
- date: (opts === null || opts === void 0 ? void 0 : opts.newDate) || this.date,
21
- time: (opts === null || opts === void 0 ? void 0 : opts.newTime) || this.time,
22
- });
23
- const jsDate = newDateTime.getJSDateTime();
24
- const year = jsDate.getFullYear();
25
- const month = padLeft(jsDate.getMonth() + 1);
26
- const day = padLeft(jsDate.getDate());
27
- const hour = padLeft(jsDate.getHours());
28
- const minute = padLeft(jsDate.getMinutes());
29
- const second = padLeft(jsDate.getSeconds());
30
- const timezoneOffsetMinutes = (opts === null || opts === void 0 ? void 0 : opts.timezoneOffsetMinutes)
31
- ? opts.timezoneOffsetMinutes
32
- : 0;
33
- const sign = timezoneOffsetMinutes == 0
34
- ? undefined
35
- : timezoneOffsetMinutes < 0
36
- ? "-"
37
- : "+";
38
- const offsetHours = padLeft(Math.floor(Math.abs(timezoneOffsetMinutes) / 60));
39
- const offsetMinutes = padLeft(Math.abs(timezoneOffsetMinutes) % 60);
40
- const timezone = sign ? `${sign}${offsetHours}:${offsetMinutes}` : ".000Z";
41
- return `${year}-${month}-${day}T${hour}:${minute}:${second}${timezone}`;
73
+ normalizeDateString(dateString) {
74
+ if (this.onlyDatePattern.test(dateString)) {
75
+ return `${dateString}T00:00:00Z`;
76
+ }
77
+ if (this.dateTimePattern.test(dateString)) {
78
+ return dateString;
79
+ }
42
80
  }
43
81
  }
44
82
  exports.ISO8601DateTime = ISO8601DateTime;
@@ -1,146 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const ISO8601Date_1 = require("./ISO8601Date");
4
3
  const ISO8601DateTime_1 = require("./ISO8601DateTime");
5
- const ISO8601Time_1 = require("./ISO8601Time");
6
4
  describe("ISO8601DateTime", () => {
7
- describe("ISO8601DateTime getJSDateTime()", () => {
8
- it("Should return a JS Date object.", () => {
9
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
10
- date: new ISO8601Date_1.ISO8601Date("2025-01-01"),
11
- time: new ISO8601Time_1.ISO8601Time("10:00:00"),
12
- });
13
- const jsDateTime = dateTime.getJSDateTime();
14
- expect(jsDateTime).toBeInstanceOf(Date);
5
+ describe("ISO8601DateTime constructor", () => {
6
+ it("Should throw given non ISO8601 format", () => {
7
+ const getDateTime = () => new ISO8601DateTime_1.ISO8601DateTime("abc");
8
+ expect(getDateTime).toThrow();
15
9
  });
16
- it("Should return the same year, month and day when returning UTC date.", () => {
17
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
18
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
19
- time: new ISO8601Time_1.ISO8601Time("00:00:00"),
20
- });
21
- const jsDateTime = dateTime.getJSDateTime();
22
- expect(jsDateTime.getUTCDate()).toBe(2);
23
- expect(jsDateTime.getUTCMonth()).toBe(0);
24
- expect(jsDateTime.getUTCFullYear()).toBe(2025);
25
- });
26
- it("Should return locale date string of same date and time as constructed.", () => {
27
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
28
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
29
- time: new ISO8601Time_1.ISO8601Time("01:02:03"),
30
- });
31
- const jsDateTime = dateTime.getJSDateTime();
32
- expect(jsDateTime.toLocaleDateString("pt-BR")).toBe("02/01/2025");
33
- });
34
- it("Should return ISO string converted to UTC.", () => {
35
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
36
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
37
- time: new ISO8601Time_1.ISO8601Time("01:02:03"),
38
- });
39
- const jsDateTime = dateTime.getJSDateTime();
40
- expect(jsDateTime.toISOString()).toBe("2025-01-02T04:02:03.000Z");
41
- });
42
- });
43
- describe("ISO8601DateTime.getBrazilianIsoString()", () => {
44
- it("Should return ISO string converted to Brazilian time.", () => {
45
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
46
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
47
- time: new ISO8601Time_1.ISO8601Time("01:02:03"),
48
- });
49
- const brazilianIsoString = dateTime.getBrazilianIsoString();
50
- expect(brazilianIsoString).toBe("2025-01-02T01:02:03-03:00");
10
+ it("Should not throw given non ISO8601 format but with no time", () => {
11
+ const getDateTime = () => new ISO8601DateTime_1.ISO8601DateTime("2025-01-01");
12
+ expect(getDateTime).not.toThrow();
51
13
  });
52
14
  });
53
15
  describe("ISO8601DateTime.getIsoString()", () => {
54
- it("Should return ISO UTC string if no arguments.", () => {
55
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
56
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
57
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
58
- });
59
- const utcIsoString = dateTime.getIsoString();
60
- expect(utcIsoString).toBe("2025-01-02T03:01:02.000Z");
61
- });
62
- it("Should return ISO string +01:00 for London timezone.", () => {
63
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
64
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
65
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
66
- });
67
- const isoString = dateTime.getIsoString({ timezoneOffsetMinutes: 60 });
68
- expect(isoString).toBe("2025-01-02T03:01:02+01:00");
69
- });
70
- it("Should return ISO string -05:00 for Chicago DST timezone.", () => {
71
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
72
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
73
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
74
- });
75
- const isoString = dateTime.getIsoString({
76
- timezoneOffsetMinutes: -300,
77
- });
78
- expect(isoString).toBe("2025-01-02T03:01:02-05:00");
16
+ it("Should convert to brazilian timezone properly.", () => {
17
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00Z").getIsoString({
18
+ timezone: "-03:00",
19
+ })).toEqual("2025-01-01T00:00:00-03:00");
20
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00Z").getIsoString({
21
+ timezone: -180,
22
+ })).toEqual("2025-01-01T00:00:00-03:00");
23
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00Z").getIsoString({
24
+ timezone: "-04:00",
25
+ })).toEqual("2024-12-31T23:00:00-04:00");
26
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T00:00:00-03:00").getIsoString({
27
+ timezone: "Z",
28
+ })).toEqual("2025-01-01T03:00:00Z");
29
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T00:00:00-03:00").getIsoString({
30
+ timezone: "-03:00",
31
+ })).toEqual("2025-01-01T00:00:00-03:00");
32
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T00:00:00-03:00").getIsoString({
33
+ timezone: undefined,
34
+ })).toEqual("2025-01-01T03:00:00.000Z");
35
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T00:00:00-03:00").getIsoString({
36
+ timezone: "-02:00",
37
+ })).toEqual("2025-01-01T01:00:00-02:00");
38
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T00:00:00-03:00").getIsoString({
39
+ timezone: "+03:00",
40
+ })).toEqual("2025-01-01T06:00:00+03:00");
41
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01").getIsoString({
42
+ timezone: "+03:00",
43
+ })).toEqual("2025-01-01T03:00:00+03:00");
44
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01").getIsoString({
45
+ timezone: undefined,
46
+ })).toEqual("2025-01-01T00:00:00.000Z");
79
47
  });
80
- it("Should return ISO string -03:00 for Brazilian timezone.", () => {
81
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
82
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
83
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
84
- });
85
- const isoString = dateTime.getIsoString({
86
- timezoneOffsetMinutes: -180,
87
- });
88
- expect(isoString).toBe("2025-01-02T03:01:02-03:00");
89
- });
90
- it("Should return ISO string -03:00 for Brazilian timezone derived from Date.", () => {
91
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
92
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
93
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
94
- });
95
- const isoString = dateTime.getIsoString({
96
- timezoneOffsetMinutes: -new Date().getTimezoneOffset(),
97
- });
98
- expect(isoString).toBe("2025-01-02T03:01:02-03:00");
99
- });
100
- it("Should accept newDate and properly output it.", () => {
101
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
102
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
103
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
104
- });
105
- const isoString = dateTime.getIsoString({
106
- timezoneOffsetMinutes: -new Date().getTimezoneOffset(),
107
- newDate: new ISO8601Date_1.ISO8601Date("2025-01-03"),
108
- });
109
- expect(isoString).toBe("2025-01-03T03:01:02-03:00");
110
- });
111
- it("Should accept newTime and properly output it.", () => {
112
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
113
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
114
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
115
- });
116
- const isoString = dateTime.getIsoString({
117
- timezoneOffsetMinutes: -new Date().getTimezoneOffset(),
118
- newTime: new ISO8601Time_1.ISO8601Time("03:01:03")
119
- });
120
- expect(isoString).toBe("2025-01-02T03:01:03-03:00");
121
- });
122
- it("Should accept newTime and newDate and properly output them.", () => {
123
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
124
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
125
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
126
- });
127
- const isoString = dateTime.getIsoString({
128
- timezoneOffsetMinutes: -new Date().getTimezoneOffset(),
129
- newTime: new ISO8601Time_1.ISO8601Time("03:01:03"),
130
- newDate: new ISO8601Date_1.ISO8601Date("2025-01-03")
131
- });
132
- expect(isoString).toBe("2025-01-03T03:01:03-03:00");
48
+ });
49
+ describe("ISO8601DateTime.toMidnight()", () => {
50
+ it("Should return midnight of the same day.", () => {
51
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00Z").toMidnight().getJsDateTime()).toEqual(new Date("2025-01-01T00:00:00Z"));
52
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00-03:00")
53
+ .toMidnight()
54
+ .getJsDateTime()).toEqual(new Date("2025-01-01T00:00:00-03:00"));
133
55
  });
134
- it("Should accept newTime and newDate and properly output them, even when timezone is UTC.", () => {
135
- const dateTime = new ISO8601DateTime_1.ISO8601DateTime({
136
- date: new ISO8601Date_1.ISO8601Date("2025-01-02"),
137
- time: new ISO8601Time_1.ISO8601Time("03:01:02"),
138
- });
139
- const isoString = dateTime.getIsoString({
140
- newTime: new ISO8601Time_1.ISO8601Time("03:01:03"),
141
- newDate: new ISO8601Date_1.ISO8601Date("2025-01-03")
142
- });
143
- expect(isoString).toBe("2025-01-03T03:01:03.000Z");
56
+ });
57
+ describe("ISO8601DateTime.toMidnight().getIsoString()", () => {
58
+ it("Must take UTC ISO string and return it midnight", () => {
59
+ expect(new ISO8601DateTime_1.ISO8601DateTime("2025-01-01T03:00:00Z")
60
+ .toMidnight()
61
+ .getIsoString()).toEqual("2025-01-01T00:00:00.000Z");
144
62
  });
145
63
  });
146
64
  });
@@ -5,7 +5,8 @@ import { IDateValidator } from "./DateValidator";
5
5
  * @throws on get methods if format is wrong
6
6
  */
7
7
  export declare class ISO8601DateValidator implements IDateValidator {
8
- private YYYYmmDD;
8
+ YYYYmmDDpatternString: string;
9
+ YYYYmmDDpattern: RegExp;
9
10
  /**
10
11
  * Accepted format: YYYY-MM-DD
11
12
  */
@@ -8,16 +8,17 @@ exports.ISO8601DateValidator = void 0;
8
8
  */
9
9
  class ISO8601DateValidator {
10
10
  constructor() {
11
- this.YYYYmmDD = new RegExp("^[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])");
11
+ this.YYYYmmDDpatternString = "[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])";
12
+ this.YYYYmmDDpattern = new RegExp(`^${this.YYYYmmDDpatternString}`);
12
13
  }
13
14
  /**
14
15
  * Accepted format: YYYY-MM-DD
15
16
  */
16
17
  formatIsValid(date) {
17
- return this.YYYYmmDD.test(date);
18
+ return this.YYYYmmDDpattern.test(date);
18
19
  }
19
20
  match(date) {
20
- const matches = date.match(this.YYYYmmDD);
21
+ const matches = date.match(this.YYYYmmDDpattern);
21
22
  if (!matches || matches.length < 1) {
22
23
  return undefined;
23
24
  }
@@ -20,9 +20,12 @@ export declare class ISO8601TimeValidator implements IISO8601TimeValidator {
20
20
  private zAndMillisecondsPatternString;
21
21
  private hhMMssPattern;
22
22
  private hhMMPattern;
23
- private hhMMssPlusNumberedTimezonePattern;
24
- private hhMMssZPattern;
25
- private hhMMssSSSZPattern;
23
+ hhMMssPlusNumberedTimezonePatternString: string;
24
+ hhMMssPlusNumberedTimezonePattern: RegExp;
25
+ hhMMssZPatternString: string;
26
+ hhMMssZPattern: RegExp;
27
+ hhMMssSSSZPatternString: string;
28
+ hhMMssSSSZPattern: RegExp;
26
29
  formatIsValid(time: string): boolean;
27
30
  isHHmmSS(time: string): boolean;
28
31
  isHHmm(time: string): boolean;
@@ -13,9 +13,12 @@ class ISO8601TimeValidator {
13
13
  this.zAndMillisecondsPatternString = `.[0-9]{3}Z`;
14
14
  this.hhMMssPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}$`);
15
15
  this.hhMMPattern = new RegExp(`^${this.upTo23}:${this.upTo59}$`);
16
- this.hhMMssPlusNumberedTimezonePattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}$`);
17
- this.hhMMssZPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}$`);
18
- this.hhMMssSSSZPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}$`);
16
+ this.hhMMssPlusNumberedTimezonePatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}`;
17
+ this.hhMMssPlusNumberedTimezonePattern = new RegExp(`^${this.hhMMssPlusNumberedTimezonePatternString}$`);
18
+ this.hhMMssZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}`;
19
+ this.hhMMssZPattern = new RegExp(`^${this.hhMMssZPatternString}$`);
20
+ this.hhMMssSSSZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}`;
21
+ this.hhMMssSSSZPattern = new RegExp(`^${this.hhMMssSSSZPatternString}$`);
19
22
  this.isHHmmSSPlusNumberedTimezone = (time) => {
20
23
  return this.hhMMssPlusNumberedTimezonePattern.test(time);
21
24
  };
@@ -0,0 +1,20 @@
1
+ export interface ITimeUnitConverter {
2
+ msToSeconds: (n: number) => number;
3
+ msToMinutes: (n: number) => number;
4
+ msToHours: (n: number) => number;
5
+ msToDays: (n: number) => number;
6
+ daysToMs: (n: number) => number;
7
+ hoursToMs: (n: number) => number;
8
+ minutesToMs: (n: number) => number;
9
+ secondsToMs: (n: number) => number;
10
+ }
11
+ export declare class TimeUnitConverter implements ITimeUnitConverter {
12
+ msToSeconds: (n: number) => number;
13
+ msToMinutes: (n: number) => number;
14
+ msToHours: (n: number) => number;
15
+ msToDays: (n: number) => number;
16
+ daysToMs: (n: number) => number;
17
+ hoursToMs: (n: number) => number;
18
+ minutesToMs: (n: number) => number;
19
+ secondsToMs: (n: number) => number;
20
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimeUnitConverter = void 0;
4
+ class TimeUnitConverter {
5
+ constructor() {
6
+ this.msToSeconds = (n) => n / 1000;
7
+ this.msToMinutes = (n) => n / (1000 * 60);
8
+ this.msToHours = (n) => n / (1000 * 60 * 60);
9
+ this.msToDays = (n) => n / (1000 * 60 * 60 * 24);
10
+ this.daysToMs = (n) => n * 24 * 60 * 60 * 1000;
11
+ this.hoursToMs = (n) => n * 60 * 60 * 1000;
12
+ this.minutesToMs = (n) => n * 60 * 1000;
13
+ this.secondsToMs = (n) => n * 1000;
14
+ }
15
+ }
16
+ exports.TimeUnitConverter = TimeUnitConverter;
17
+ ;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const TimeUnitConverter_1 = require("./TimeUnitConverter");
4
+ describe("TimeUnitConverter", () => {
5
+ const converter = new TimeUnitConverter_1.TimeUnitConverter();
6
+ describe("msToSeconds", () => {
7
+ it("should convert ms to seconds", () => {
8
+ expect(converter.msToSeconds(2000)).toBe(2);
9
+ });
10
+ it("should convert ms to seconds and round up", () => {
11
+ const result = converter.msToSeconds(2500);
12
+ expect(Math.ceil(result)).toBe(3);
13
+ });
14
+ it("should convert ms to seconds and round down", () => {
15
+ expect(Math.floor(converter.msToSeconds(2500))).toBe(2);
16
+ expect(Math.floor(converter.msToSeconds(2999))).toBe(2);
17
+ });
18
+ });
19
+ describe("msToMinutes", () => {
20
+ it("should convert ms to minutes", () => {
21
+ expect(converter.msToMinutes(120000)).toBe(2);
22
+ });
23
+ it("should convert ms to minutes and round up", () => {
24
+ const result = converter.msToMinutes(125000);
25
+ expect(Math.ceil(result)).toBe(3);
26
+ });
27
+ it("should convert ms to minutes and round down", () => {
28
+ const result = converter.msToMinutes(125000);
29
+ expect(Math.floor(result)).toBe(2);
30
+ });
31
+ });
32
+ describe("msToHours", () => {
33
+ it("should convert ms to hours", () => {
34
+ expect(converter.msToHours(7200000)).toBe(2);
35
+ });
36
+ it("should convert ms to hours and round up", () => {
37
+ const result = converter.msToHours(8100000);
38
+ expect(Math.ceil(result)).toBe(3);
39
+ });
40
+ it("should convert ms to hours and round down", () => {
41
+ const result = converter.msToHours(8100000);
42
+ expect(Math.floor(result)).toBe(2);
43
+ });
44
+ });
45
+ describe("msToDays", () => {
46
+ it("should convert ms to days", () => {
47
+ expect(converter.msToDays(172800000)).toBe(2);
48
+ });
49
+ it("should convert ms to days and round up", () => {
50
+ const result = converter.msToDays(190000000);
51
+ expect(Math.ceil(result)).toBe(3);
52
+ });
53
+ it("should convert ms to days and round down", () => {
54
+ const result = converter.msToDays(190000000);
55
+ expect(Math.floor(result)).toBe(2);
56
+ });
57
+ });
58
+ describe("daysToMs", () => {
59
+ it("should convert days to ms", () => {
60
+ expect(converter.daysToMs(2)).toBe(172800000);
61
+ });
62
+ it("should convert days to ms and round up", () => {
63
+ const result = converter.daysToMs(2.4);
64
+ expect(Math.ceil(result)).toBe(207360000);
65
+ });
66
+ it("should convert days to ms and round down", () => {
67
+ const result = converter.daysToMs(2.4);
68
+ expect(Math.floor(result)).toBe(207359999);
69
+ });
70
+ });
71
+ describe("hoursToMs", () => {
72
+ it("should convert hours to ms", () => {
73
+ expect(converter.hoursToMs(2)).toBe(7200000);
74
+ });
75
+ it("should convert hours to ms and round up", () => {
76
+ const result = converter.hoursToMs(2.5);
77
+ expect(Math.ceil(result)).toBe(9000000);
78
+ });
79
+ it("should convert hours to ms and round down", () => {
80
+ const result = converter.hoursToMs(2.5);
81
+ expect(Math.floor(result)).toBe(9000000);
82
+ });
83
+ });
84
+ describe("minutesToMs", () => {
85
+ it("should convert minutes to ms", () => {
86
+ expect(converter.minutesToMs(2)).toBe(120000);
87
+ });
88
+ it("should convert minutes to ms and round up", () => {
89
+ const result = converter.minutesToMs(2.5);
90
+ expect(Math.ceil(result)).toBe(150000);
91
+ });
92
+ it("should convert minutes to ms and round down", () => {
93
+ const result = converter.minutesToMs(2.5);
94
+ expect(Math.floor(result)).toBe(150000);
95
+ });
96
+ });
97
+ describe("secondsToMs", () => {
98
+ it("should convert seconds to ms", () => {
99
+ expect(converter.secondsToMs(2)).toBe(2000);
100
+ });
101
+ it("should convert seconds to ms and round up", () => {
102
+ const result = converter.secondsToMs(2.5);
103
+ expect(Math.ceil(result)).toBe(2500);
104
+ });
105
+ it("should convert seconds to ms and round down", () => {
106
+ const result = converter.secondsToMs(2.5);
107
+ expect(Math.floor(result)).toBe(2500);
108
+ });
109
+ });
110
+ });
package/dist/index.cjs CHANGED
@@ -58,18 +58,17 @@ module.exports = __toCommonJS(index_exports);
58
58
  // src/domain/entities/ISO8601DateValidator.ts
59
59
  var ISO8601DateValidator = class {
60
60
  constructor() {
61
- this.YYYYmmDD = new RegExp(
62
- "^[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])"
63
- );
61
+ this.YYYYmmDDpatternString = "[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])";
62
+ this.YYYYmmDDpattern = new RegExp(`^${this.YYYYmmDDpatternString}`);
64
63
  }
65
64
  /**
66
65
  * Accepted format: YYYY-MM-DD
67
66
  */
68
67
  formatIsValid(date) {
69
- return this.YYYYmmDD.test(date);
68
+ return this.YYYYmmDDpattern.test(date);
70
69
  }
71
70
  match(date) {
72
- const matches = date.match(this.YYYYmmDD);
71
+ const matches = date.match(this.YYYYmmDDpattern);
73
72
  if (!matches || matches.length < 1) {
74
73
  return void 0;
75
74
  }
@@ -177,51 +176,6 @@ _ISO8601Date.jsDateTimeToDate = (dateTime, opts) => {
177
176
  };
178
177
  var ISO8601Date = _ISO8601Date;
179
178
 
180
- // src/domain/entities/ISO8601DateTime.ts
181
- var ISO8601DateTime = class _ISO8601DateTime {
182
- constructor(opts) {
183
- this.getJSDateTime = () => {
184
- return new Date(
185
- parseInt(this.date.getYear()),
186
- parseInt(this.date.getMonth()) - 1,
187
- parseInt(this.date.getDay()),
188
- parseInt(this.time.getHoursString()),
189
- parseInt(this.time.getMinutesString()),
190
- parseInt(this.time.getSecondsString())
191
- );
192
- };
193
- this.getBrazilianIsoString = () => {
194
- return this.getIsoString({
195
- timezoneOffsetMinutes: -180
196
- });
197
- };
198
- this.date = opts.date;
199
- this.time = opts.time;
200
- }
201
- getIsoString(opts) {
202
- const padLeft = (n) => String(n).padStart(2, "0");
203
- const newDateTime = new _ISO8601DateTime({
204
- date: (opts == null ? void 0 : opts.newDate) || this.date,
205
- time: (opts == null ? void 0 : opts.newTime) || this.time
206
- });
207
- const jsDate = newDateTime.getJSDateTime();
208
- const year = jsDate.getFullYear();
209
- const month = padLeft(jsDate.getMonth() + 1);
210
- const day = padLeft(jsDate.getDate());
211
- const hour = padLeft(jsDate.getHours());
212
- const minute = padLeft(jsDate.getMinutes());
213
- const second = padLeft(jsDate.getSeconds());
214
- const timezoneOffsetMinutes = (opts == null ? void 0 : opts.timezoneOffsetMinutes) ? opts.timezoneOffsetMinutes : 0;
215
- const sign = timezoneOffsetMinutes == 0 ? void 0 : timezoneOffsetMinutes < 0 ? "-" : "+";
216
- const offsetHours = padLeft(
217
- Math.floor(Math.abs(timezoneOffsetMinutes) / 60)
218
- );
219
- const offsetMinutes = padLeft(Math.abs(timezoneOffsetMinutes) % 60);
220
- const timezone = sign ? `${sign}${offsetHours}:${offsetMinutes}` : ".000Z";
221
- return `${year}-${month}-${day}T${hour}:${minute}:${second}${timezone}`;
222
- }
223
- };
224
-
225
179
  // src/domain/entities/ISO8601TimeValidator.ts
226
180
  var ISO8601TimeValidator = class {
227
181
  constructor() {
@@ -230,22 +184,23 @@ var ISO8601TimeValidator = class {
230
184
  this.upTo11 = "(0[0-9]|1[0-2])";
231
185
  this.upTo13 = "(0[0-9]|1[0-4])";
232
186
  this.numberedTimezonePatternString = `(\\+(${this.upTo11}:${this.upTo59}|12:00)|\\-(${this.upTo13}:${this.upTo59}|14:00))`;
233
- this.numberedTimezonePattern = new RegExp(`^${this.numberedTimezonePatternString}$`);
187
+ this.numberedTimezonePattern = new RegExp(
188
+ `^${this.numberedTimezonePatternString}$`
189
+ );
234
190
  this.zTimezonePatternString = "Z";
235
191
  this.zAndMillisecondsPatternString = `.[0-9]{3}Z`;
236
192
  this.hhMMssPattern = new RegExp(
237
193
  `^${this.upTo23}:${this.upTo59}:${this.upTo59}$`
238
194
  );
239
195
  this.hhMMPattern = new RegExp(`^${this.upTo23}:${this.upTo59}$`);
196
+ this.hhMMssPlusNumberedTimezonePatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}`;
240
197
  this.hhMMssPlusNumberedTimezonePattern = new RegExp(
241
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}$`
242
- );
243
- this.hhMMssZPattern = new RegExp(
244
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}$`
245
- );
246
- this.hhMMssSSSZPattern = new RegExp(
247
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}$`
198
+ `^${this.hhMMssPlusNumberedTimezonePatternString}$`
248
199
  );
200
+ this.hhMMssZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}`;
201
+ this.hhMMssZPattern = new RegExp(`^${this.hhMMssZPatternString}$`);
202
+ this.hhMMssSSSZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}`;
203
+ this.hhMMssSSSZPattern = new RegExp(`^${this.hhMMssSSSZPatternString}$`);
249
204
  this.isHHmmSSPlusNumberedTimezone = (time) => {
250
205
  return this.hhMMssPlusNumberedTimezonePattern.test(time);
251
206
  };
@@ -398,6 +353,89 @@ var ISO8601TimezoneParser = class {
398
353
  }
399
354
  };
400
355
 
356
+ // src/domain/entities/TimeUnitConverter.ts
357
+ var TimeUnitConverter = class {
358
+ constructor() {
359
+ this.msToSeconds = (n) => n / 1e3;
360
+ this.msToMinutes = (n) => n / (1e3 * 60);
361
+ this.msToHours = (n) => n / (1e3 * 60 * 60);
362
+ this.msToDays = (n) => n / (1e3 * 60 * 60 * 24);
363
+ this.daysToMs = (n) => n * 24 * 60 * 60 * 1e3;
364
+ this.hoursToMs = (n) => n * 60 * 60 * 1e3;
365
+ this.minutesToMs = (n) => n * 60 * 1e3;
366
+ this.secondsToMs = (n) => n * 1e3;
367
+ }
368
+ };
369
+
370
+ // src/domain/entities/ISO8601DateTime.ts
371
+ var ISO8601DateTime = class _ISO8601DateTime {
372
+ constructor(dateString) {
373
+ this.timeFormatValidator = new ISO8601TimeValidator();
374
+ this.dateFormatValidator = new ISO8601DateValidator();
375
+ this.timeUnitConverter = new TimeUnitConverter();
376
+ this.dateTimePattern = new RegExp(
377
+ `^${this.dateFormatValidator.YYYYmmDDpatternString}T(${this.timeFormatValidator.hhMMssPlusNumberedTimezonePatternString}|${this.timeFormatValidator.hhMMssSSSZPatternString}|${this.timeFormatValidator.hhMMssZPatternString})$`
378
+ );
379
+ this.onlyDatePattern = new RegExp(
380
+ `^${this.dateFormatValidator.YYYYmmDDpatternString}$`
381
+ );
382
+ this.getTimeString = () => {
383
+ return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}`;
384
+ };
385
+ this.getHoursString = () => {
386
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[0];
387
+ };
388
+ this.getMinutesString = () => {
389
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[1];
390
+ };
391
+ this.getSecondsString = () => {
392
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[2];
393
+ };
394
+ this.getMilisecondsString = () => {
395
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[3];
396
+ };
397
+ this.getJsDateTime = () => {
398
+ return new Date(this.dateString);
399
+ };
400
+ this.getIsoString = (opts) => {
401
+ if (!opts || !(opts == null ? void 0 : opts.timezone)) return this.getJsDateTime().toISOString();
402
+ const parser = new ISO8601TimezoneParser();
403
+ const validator = new ISO8601TimezoneValidator();
404
+ const timezoneInMinutes = typeof opts.timezone == "string" ? parser.toMinutes(opts.timezone) : opts.timezone;
405
+ const isValid = validator.formatIsValid(timezoneInMinutes);
406
+ if (!isValid) throw new Error("Invalid timezone format.");
407
+ const timezoneInMs = this.timeUnitConverter.minutesToMs(timezoneInMinutes);
408
+ const newDateUtcString = new Date(
409
+ this.getJsDateTime().getTime() + timezoneInMs
410
+ ).toISOString();
411
+ const newDateUtcStringWithoutTimezone = newDateUtcString.split(".")[0];
412
+ const timezoneString = parser.toString(timezoneInMinutes);
413
+ const newDateWithTimezoneString = `${newDateUtcStringWithoutTimezone}${timezoneString}`;
414
+ return newDateWithTimezoneString;
415
+ };
416
+ this.toMidnight = () => {
417
+ const currentTimeString = this.getTimeString();
418
+ const matches = new RegExp(currentTimeString).exec(this.dateString);
419
+ if (!matches || matches.length < 1) throw new Error("Error getting current time string.");
420
+ const datePlusT = this.dateString.slice(0, matches.index);
421
+ const matchedString = matches[0];
422
+ const timezone = this.dateString.slice(matchedString.length + matches.index);
423
+ return new _ISO8601DateTime(`${datePlusT}00:00:00${timezone}`);
424
+ };
425
+ const normalizedDateString = this.normalizeDateString(dateString);
426
+ if (!normalizedDateString) throw new Error("Date time format invalid.");
427
+ this.dateString = normalizedDateString;
428
+ }
429
+ normalizeDateString(dateString) {
430
+ if (this.onlyDatePattern.test(dateString)) {
431
+ return `${dateString}T00:00:00Z`;
432
+ }
433
+ if (this.dateTimePattern.test(dateString)) {
434
+ return dateString;
435
+ }
436
+ }
437
+ };
438
+
401
439
  // src/domain/entities/ISO8601Timezone.ts
402
440
  var ISO8601Timezone = class {
403
441
  constructor(originalTimezoneString) {
package/dist/index.js CHANGED
@@ -22,18 +22,17 @@ var __async = (__this, __arguments, generator) => {
22
22
  // src/domain/entities/ISO8601DateValidator.ts
23
23
  var ISO8601DateValidator = class {
24
24
  constructor() {
25
- this.YYYYmmDD = new RegExp(
26
- "^[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])"
27
- );
25
+ this.YYYYmmDDpatternString = "[0-9]{4}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2][0-9]|[3][0-1])";
26
+ this.YYYYmmDDpattern = new RegExp(`^${this.YYYYmmDDpatternString}`);
28
27
  }
29
28
  /**
30
29
  * Accepted format: YYYY-MM-DD
31
30
  */
32
31
  formatIsValid(date) {
33
- return this.YYYYmmDD.test(date);
32
+ return this.YYYYmmDDpattern.test(date);
34
33
  }
35
34
  match(date) {
36
- const matches = date.match(this.YYYYmmDD);
35
+ const matches = date.match(this.YYYYmmDDpattern);
37
36
  if (!matches || matches.length < 1) {
38
37
  return void 0;
39
38
  }
@@ -141,51 +140,6 @@ _ISO8601Date.jsDateTimeToDate = (dateTime, opts) => {
141
140
  };
142
141
  var ISO8601Date = _ISO8601Date;
143
142
 
144
- // src/domain/entities/ISO8601DateTime.ts
145
- var ISO8601DateTime = class _ISO8601DateTime {
146
- constructor(opts) {
147
- this.getJSDateTime = () => {
148
- return new Date(
149
- parseInt(this.date.getYear()),
150
- parseInt(this.date.getMonth()) - 1,
151
- parseInt(this.date.getDay()),
152
- parseInt(this.time.getHoursString()),
153
- parseInt(this.time.getMinutesString()),
154
- parseInt(this.time.getSecondsString())
155
- );
156
- };
157
- this.getBrazilianIsoString = () => {
158
- return this.getIsoString({
159
- timezoneOffsetMinutes: -180
160
- });
161
- };
162
- this.date = opts.date;
163
- this.time = opts.time;
164
- }
165
- getIsoString(opts) {
166
- const padLeft = (n) => String(n).padStart(2, "0");
167
- const newDateTime = new _ISO8601DateTime({
168
- date: (opts == null ? void 0 : opts.newDate) || this.date,
169
- time: (opts == null ? void 0 : opts.newTime) || this.time
170
- });
171
- const jsDate = newDateTime.getJSDateTime();
172
- const year = jsDate.getFullYear();
173
- const month = padLeft(jsDate.getMonth() + 1);
174
- const day = padLeft(jsDate.getDate());
175
- const hour = padLeft(jsDate.getHours());
176
- const minute = padLeft(jsDate.getMinutes());
177
- const second = padLeft(jsDate.getSeconds());
178
- const timezoneOffsetMinutes = (opts == null ? void 0 : opts.timezoneOffsetMinutes) ? opts.timezoneOffsetMinutes : 0;
179
- const sign = timezoneOffsetMinutes == 0 ? void 0 : timezoneOffsetMinutes < 0 ? "-" : "+";
180
- const offsetHours = padLeft(
181
- Math.floor(Math.abs(timezoneOffsetMinutes) / 60)
182
- );
183
- const offsetMinutes = padLeft(Math.abs(timezoneOffsetMinutes) % 60);
184
- const timezone = sign ? `${sign}${offsetHours}:${offsetMinutes}` : ".000Z";
185
- return `${year}-${month}-${day}T${hour}:${minute}:${second}${timezone}`;
186
- }
187
- };
188
-
189
143
  // src/domain/entities/ISO8601TimeValidator.ts
190
144
  var ISO8601TimeValidator = class {
191
145
  constructor() {
@@ -194,22 +148,23 @@ var ISO8601TimeValidator = class {
194
148
  this.upTo11 = "(0[0-9]|1[0-2])";
195
149
  this.upTo13 = "(0[0-9]|1[0-4])";
196
150
  this.numberedTimezonePatternString = `(\\+(${this.upTo11}:${this.upTo59}|12:00)|\\-(${this.upTo13}:${this.upTo59}|14:00))`;
197
- this.numberedTimezonePattern = new RegExp(`^${this.numberedTimezonePatternString}$`);
151
+ this.numberedTimezonePattern = new RegExp(
152
+ `^${this.numberedTimezonePatternString}$`
153
+ );
198
154
  this.zTimezonePatternString = "Z";
199
155
  this.zAndMillisecondsPatternString = `.[0-9]{3}Z`;
200
156
  this.hhMMssPattern = new RegExp(
201
157
  `^${this.upTo23}:${this.upTo59}:${this.upTo59}$`
202
158
  );
203
159
  this.hhMMPattern = new RegExp(`^${this.upTo23}:${this.upTo59}$`);
160
+ this.hhMMssPlusNumberedTimezonePatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}`;
204
161
  this.hhMMssPlusNumberedTimezonePattern = new RegExp(
205
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.numberedTimezonePatternString}$`
206
- );
207
- this.hhMMssZPattern = new RegExp(
208
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}$`
209
- );
210
- this.hhMMssSSSZPattern = new RegExp(
211
- `^${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}$`
162
+ `^${this.hhMMssPlusNumberedTimezonePatternString}$`
212
163
  );
164
+ this.hhMMssZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zTimezonePatternString}`;
165
+ this.hhMMssZPattern = new RegExp(`^${this.hhMMssZPatternString}$`);
166
+ this.hhMMssSSSZPatternString = `${this.upTo23}:${this.upTo59}:${this.upTo59}${this.zAndMillisecondsPatternString}`;
167
+ this.hhMMssSSSZPattern = new RegExp(`^${this.hhMMssSSSZPatternString}$`);
213
168
  this.isHHmmSSPlusNumberedTimezone = (time) => {
214
169
  return this.hhMMssPlusNumberedTimezonePattern.test(time);
215
170
  };
@@ -362,6 +317,89 @@ var ISO8601TimezoneParser = class {
362
317
  }
363
318
  };
364
319
 
320
+ // src/domain/entities/TimeUnitConverter.ts
321
+ var TimeUnitConverter = class {
322
+ constructor() {
323
+ this.msToSeconds = (n) => n / 1e3;
324
+ this.msToMinutes = (n) => n / (1e3 * 60);
325
+ this.msToHours = (n) => n / (1e3 * 60 * 60);
326
+ this.msToDays = (n) => n / (1e3 * 60 * 60 * 24);
327
+ this.daysToMs = (n) => n * 24 * 60 * 60 * 1e3;
328
+ this.hoursToMs = (n) => n * 60 * 60 * 1e3;
329
+ this.minutesToMs = (n) => n * 60 * 1e3;
330
+ this.secondsToMs = (n) => n * 1e3;
331
+ }
332
+ };
333
+
334
+ // src/domain/entities/ISO8601DateTime.ts
335
+ var ISO8601DateTime = class _ISO8601DateTime {
336
+ constructor(dateString) {
337
+ this.timeFormatValidator = new ISO8601TimeValidator();
338
+ this.dateFormatValidator = new ISO8601DateValidator();
339
+ this.timeUnitConverter = new TimeUnitConverter();
340
+ this.dateTimePattern = new RegExp(
341
+ `^${this.dateFormatValidator.YYYYmmDDpatternString}T(${this.timeFormatValidator.hhMMssPlusNumberedTimezonePatternString}|${this.timeFormatValidator.hhMMssSSSZPatternString}|${this.timeFormatValidator.hhMMssZPatternString})$`
342
+ );
343
+ this.onlyDatePattern = new RegExp(
344
+ `^${this.dateFormatValidator.YYYYmmDDpatternString}$`
345
+ );
346
+ this.getTimeString = () => {
347
+ return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}`;
348
+ };
349
+ this.getHoursString = () => {
350
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[0];
351
+ };
352
+ this.getMinutesString = () => {
353
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[1];
354
+ };
355
+ this.getSecondsString = () => {
356
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[2];
357
+ };
358
+ this.getMilisecondsString = () => {
359
+ return this.dateString.split("T")[1].slice(0, 8).split(":")[3];
360
+ };
361
+ this.getJsDateTime = () => {
362
+ return new Date(this.dateString);
363
+ };
364
+ this.getIsoString = (opts) => {
365
+ if (!opts || !(opts == null ? void 0 : opts.timezone)) return this.getJsDateTime().toISOString();
366
+ const parser = new ISO8601TimezoneParser();
367
+ const validator = new ISO8601TimezoneValidator();
368
+ const timezoneInMinutes = typeof opts.timezone == "string" ? parser.toMinutes(opts.timezone) : opts.timezone;
369
+ const isValid = validator.formatIsValid(timezoneInMinutes);
370
+ if (!isValid) throw new Error("Invalid timezone format.");
371
+ const timezoneInMs = this.timeUnitConverter.minutesToMs(timezoneInMinutes);
372
+ const newDateUtcString = new Date(
373
+ this.getJsDateTime().getTime() + timezoneInMs
374
+ ).toISOString();
375
+ const newDateUtcStringWithoutTimezone = newDateUtcString.split(".")[0];
376
+ const timezoneString = parser.toString(timezoneInMinutes);
377
+ const newDateWithTimezoneString = `${newDateUtcStringWithoutTimezone}${timezoneString}`;
378
+ return newDateWithTimezoneString;
379
+ };
380
+ this.toMidnight = () => {
381
+ const currentTimeString = this.getTimeString();
382
+ const matches = new RegExp(currentTimeString).exec(this.dateString);
383
+ if (!matches || matches.length < 1) throw new Error("Error getting current time string.");
384
+ const datePlusT = this.dateString.slice(0, matches.index);
385
+ const matchedString = matches[0];
386
+ const timezone = this.dateString.slice(matchedString.length + matches.index);
387
+ return new _ISO8601DateTime(`${datePlusT}00:00:00${timezone}`);
388
+ };
389
+ const normalizedDateString = this.normalizeDateString(dateString);
390
+ if (!normalizedDateString) throw new Error("Date time format invalid.");
391
+ this.dateString = normalizedDateString;
392
+ }
393
+ normalizeDateString(dateString) {
394
+ if (this.onlyDatePattern.test(dateString)) {
395
+ return `${dateString}T00:00:00Z`;
396
+ }
397
+ if (this.dateTimePattern.test(dateString)) {
398
+ return dateString;
399
+ }
400
+ }
401
+ };
402
+
365
403
  // src/domain/entities/ISO8601Timezone.ts
366
404
  var ISO8601Timezone = class {
367
405
  constructor(originalTimezoneString) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eliasrrosa/tutorhub-public-assets",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Assets, mainly interfaces, to be shared among different Tutorhub apps.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",