@eliasrrosa/tutorhub-public-assets 0.0.9 → 0.0.11
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/dist/domain/entities/ISO8601DateTime.js +1 -1
- package/dist/domain/entities/ISO8601Time.d.ts +20 -10
- package/dist/domain/entities/ISO8601Time.js +62 -25
- package/dist/domain/entities/ISO8601Time.test.js +105 -14
- package/dist/domain/entities/ISO8601TimeValidator.d.ts +7 -0
- package/dist/domain/entities/ISO8601TimeValidator.js +9 -3
- package/dist/domain/entities/ISO8601Timezone.d.ts +12 -0
- package/dist/domain/entities/ISO8601Timezone.js +13 -0
- package/dist/domain/entities/ISO8601Timezone.test.d.ts +1 -0
- package/dist/domain/entities/ISO8601Timezone.test.js +11 -0
- package/dist/domain/entities/ISO8601TimezoneConverter.d.ts +19 -0
- package/dist/domain/entities/ISO8601TimezoneConverter.js +28 -0
- package/dist/domain/entities/ISO8601TimezoneConverter.test.d.ts +1 -0
- package/dist/domain/entities/ISO8601TimezoneConverter.test.js +50 -0
- package/dist/domain/entities/ISO8601TimezoneParser.d.ts +17 -0
- package/dist/domain/entities/ISO8601TimezoneParser.js +47 -0
- package/dist/domain/entities/ISO8601TimezoneParser.test.d.ts +1 -0
- package/dist/domain/entities/ISO8601TimezoneParser.test.js +87 -0
- package/dist/domain/entities/ISO8601TimezoneSelector.d.ts +32 -0
- package/dist/domain/entities/ISO8601TimezoneSelector.js +61 -0
- package/dist/domain/entities/ISO8601TimezoneSelector.test.d.ts +1 -0
- package/dist/domain/entities/ISO8601TimezoneSelector.test.js +151 -0
- package/dist/domain/entities/ISO8601TimezoneValidator.d.ts +22 -0
- package/dist/domain/entities/ISO8601TimezoneValidator.js +37 -0
- package/dist/domain/entities/ISO8601TimezoneValidator.test.d.ts +1 -0
- package/dist/domain/entities/ISO8601TimezoneValidator.test.js +65 -0
- package/dist/domain/entities/Time.d.ts +26 -7
- package/dist/domain/entities/TimeSlot.d.ts +3 -2
- package/dist/domain/entities/UserUnavailableTime.d.ts +7 -6
- package/dist/domain/entities/UserUnavailableTime.js +3 -2
- package/dist/domain/entities/UserUnavailableTime.test.js +28 -6
- package/dist/index.cjs +241 -31
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ exports.ISO8601DateTime = void 0;
|
|
|
4
4
|
class ISO8601DateTime {
|
|
5
5
|
constructor(opts) {
|
|
6
6
|
this.getJSDateTime = () => {
|
|
7
|
-
return new Date(parseInt(this.date.getYear()), parseInt(this.date.getMonth()) - 1, parseInt(this.date.getDay()), parseInt(this.time.
|
|
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()));
|
|
8
8
|
};
|
|
9
9
|
this.getBrazilianIsoString = () => {
|
|
10
10
|
return this.getIsoString({
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { IISO8601TimeValidator } from "./ISO8601TimeValidator";
|
|
2
|
+
import { IISO8601Timezone } from "./ISO8601Timezone";
|
|
3
|
+
import { IISO8601TimezoneConverter } from "./ISO8601TimezoneConverter";
|
|
4
|
+
import { IISO8601TimezoneParser } from "./ISO8601TimezoneParser";
|
|
2
5
|
import { ITime } from "./Time";
|
|
3
6
|
/**
|
|
4
7
|
* Interface for interacting with ISO8601 time formats.
|
|
@@ -8,21 +11,28 @@ import { ITime } from "./Time";
|
|
|
8
11
|
* @throws if any method is called with a different format
|
|
9
12
|
*/
|
|
10
13
|
export declare class ISO8601Time implements ITime {
|
|
11
|
-
readonly
|
|
12
|
-
readonly
|
|
13
|
-
readonly
|
|
14
|
+
readonly originalTimeString: string;
|
|
15
|
+
readonly timeValidator: IISO8601TimeValidator;
|
|
16
|
+
readonly converter: IISO8601TimezoneConverter;
|
|
17
|
+
readonly parser: IISO8601TimezoneParser;
|
|
14
18
|
/**
|
|
15
19
|
* Throws if format is invalid.
|
|
16
|
-
* Accepted formats: HH:MM:SS and HH:MM.
|
|
20
|
+
* Accepted formats: HH:MM:SS, HH:MM, HH:MM:SS(+|-)HH:MM, HH:MM:SS.sssZ and HH:MM:SSZ.
|
|
17
21
|
*/
|
|
18
22
|
constructor(value?: string);
|
|
19
23
|
private validateFormatOrThrow;
|
|
20
|
-
|
|
21
|
-
format?: "HH:MM" | "HH:MM:SS";
|
|
24
|
+
getTimeString(opts?: {
|
|
25
|
+
format?: "HH:MM" | "HH:MM:SS" | "HH:MM:SS(+|-)HH:MM";
|
|
26
|
+
convertToTimezone?: string | number;
|
|
22
27
|
}): string;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
getMinutesString(): string;
|
|
29
|
+
getHoursString(): string;
|
|
30
|
+
getSecondsString(): string;
|
|
26
31
|
static getNow(): string;
|
|
27
|
-
|
|
32
|
+
getNowTimeString: typeof ISO8601Time.getNow;
|
|
33
|
+
getTimezone: () => IISO8601Timezone;
|
|
34
|
+
addHours: (hours: number) => ITime;
|
|
35
|
+
addMinutes: (minutes: number) => ITime;
|
|
36
|
+
addTimezone: (timezone: string | number) => ITime;
|
|
37
|
+
getTimezoneString(): string;
|
|
28
38
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ISO8601Time = void 0;
|
|
4
4
|
const ISO8601TimeValidator_1 = require("./ISO8601TimeValidator");
|
|
5
|
+
const ISO8601Timezone_1 = require("./ISO8601Timezone");
|
|
6
|
+
const ISO8601TimezoneConverter_1 = require("./ISO8601TimezoneConverter");
|
|
7
|
+
const ISO8601TimezoneParser_1 = require("./ISO8601TimezoneParser");
|
|
5
8
|
/**
|
|
6
9
|
* Interface for interacting with ISO8601 time formats.
|
|
7
10
|
* Accepted formats: HH:MM:SS, HH:MM, HH:MM:SSZ, HH:MM:SS.sssZ and HH:MM:SS(+|-)HH:MM.
|
|
@@ -12,49 +15,80 @@ const ISO8601TimeValidator_1 = require("./ISO8601TimeValidator");
|
|
|
12
15
|
class ISO8601Time {
|
|
13
16
|
/**
|
|
14
17
|
* Throws if format is invalid.
|
|
15
|
-
* Accepted formats: HH:MM:SS and HH:MM.
|
|
18
|
+
* Accepted formats: HH:MM:SS, HH:MM, HH:MM:SS(+|-)HH:MM, HH:MM:SS.sssZ and HH:MM:SSZ.
|
|
16
19
|
*/
|
|
17
20
|
constructor(value) {
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
+
this.timeValidator = new ISO8601TimeValidator_1.ISO8601TimeValidator();
|
|
22
|
+
this.converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
23
|
+
this.parser = new ISO8601TimezoneParser_1.ISO8601TimezoneParser();
|
|
24
|
+
this.getNowTimeString = ISO8601Time.getNow;
|
|
25
|
+
this.getTimezone = () => {
|
|
26
|
+
return new ISO8601Timezone_1.ISO8601Timezone(this.originalTimeString);
|
|
27
|
+
};
|
|
28
|
+
this.addHours = (hours) => {
|
|
29
|
+
let targetHour = parseInt(this.getHoursString()) + hours;
|
|
30
|
+
while (targetHour >= 24) {
|
|
31
|
+
targetHour = targetHour - 24;
|
|
32
|
+
}
|
|
33
|
+
while (targetHour < 0) {
|
|
34
|
+
targetHour = 24 + targetHour;
|
|
35
|
+
}
|
|
36
|
+
const targetHourString = targetHour >= 0
|
|
37
|
+
? targetHour.toString().padStart(2, "0")
|
|
38
|
+
: `-${Math.abs(targetHour).toString().padStart(2, "0")}`;
|
|
39
|
+
const targetTimeString = `${targetHourString}:${this.getMinutesString()}:${this.getSecondsString()}${this.getTimezone().selector.getTimezoneString(this.originalTimeString)}`;
|
|
40
|
+
return new ISO8601Time(targetTimeString);
|
|
41
|
+
};
|
|
42
|
+
this.addMinutes = (minutes) => {
|
|
43
|
+
const minutesToAddFromZeroMinutes = minutes + parseInt(this.getMinutesString());
|
|
44
|
+
const hoursToAdd = Math.floor(minutesToAddFromZeroMinutes / 60);
|
|
45
|
+
const targetMinutes = minutesToAddFromZeroMinutes - hoursToAdd * 60;
|
|
46
|
+
const timeWithAddedHours = new ISO8601Time(this.originalTimeString).addHours(hoursToAdd);
|
|
47
|
+
const targetMinutesString = targetMinutes.toString().padStart(2, "0");
|
|
48
|
+
return new ISO8601Time(`${timeWithAddedHours.getHoursString()}:${targetMinutesString}:${timeWithAddedHours.getSecondsString()}${timeWithAddedHours
|
|
49
|
+
.getTimezone()
|
|
50
|
+
.selector.getTimezoneString(timeWithAddedHours.originalTimeString)}`);
|
|
51
|
+
};
|
|
52
|
+
this.addTimezone = (timezone) => {
|
|
53
|
+
const newTimezone = typeof timezone == "number" ? this.parser.toString(timezone) : timezone;
|
|
54
|
+
return new ISO8601Time(`${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}${newTimezone}`);
|
|
55
|
+
};
|
|
56
|
+
this.originalTimeString = value ? value : this.getNowTimeString();
|
|
21
57
|
this.validateFormatOrThrow();
|
|
22
58
|
}
|
|
23
59
|
validateFormatOrThrow() {
|
|
24
|
-
if (!this.
|
|
60
|
+
if (!this.timeValidator.formatIsValid(this.originalTimeString))
|
|
25
61
|
throw new Error("Time format must be ISO8601.");
|
|
26
62
|
}
|
|
27
|
-
|
|
63
|
+
getTimeString(opts) {
|
|
28
64
|
this.validateFormatOrThrow();
|
|
29
|
-
if ((opts === null || opts === void 0 ? void 0 : opts.format) == "HH:MM"
|
|
30
|
-
return this.
|
|
65
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.format) == "HH:MM") {
|
|
66
|
+
return `${this.getHoursString()}:${this.getMinutesString()}`;
|
|
31
67
|
}
|
|
32
|
-
if ((
|
|
33
|
-
this.
|
|
34
|
-
return this.value;
|
|
68
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.format) == "HH:MM:SS") {
|
|
69
|
+
return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}`;
|
|
35
70
|
}
|
|
36
|
-
if ((opts === null || opts === void 0 ? void 0 : opts.format) == "HH:MM
|
|
37
|
-
|
|
71
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.format) == "HH:MM:SS(+|-)HH:MM") {
|
|
72
|
+
const timezone = new ISO8601Timezone_1.ISO8601Timezone(this.originalTimeString);
|
|
73
|
+
return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}${timezone.selector.getTimezoneString(this.originalTimeString)}`;
|
|
38
74
|
}
|
|
39
|
-
|
|
40
|
-
this.validator.isHHmm(this.value)) {
|
|
41
|
-
return `${this.getHours()}:${this.getMinutes()}:${this.getSeconds()}`;
|
|
42
|
-
}
|
|
43
|
-
throw new Error("Time format is invalid.");
|
|
75
|
+
return `${this.getHoursString()}:${this.getMinutesString()}:${this.getSecondsString()}`;
|
|
44
76
|
}
|
|
45
|
-
|
|
77
|
+
getMinutesString() {
|
|
46
78
|
this.validateFormatOrThrow();
|
|
47
|
-
return this.
|
|
79
|
+
return this.originalTimeString.split(":")[1];
|
|
48
80
|
}
|
|
49
|
-
|
|
81
|
+
getHoursString() {
|
|
50
82
|
this.validateFormatOrThrow();
|
|
51
|
-
return this.
|
|
83
|
+
return this.originalTimeString.split(":")[0];
|
|
52
84
|
}
|
|
53
|
-
|
|
85
|
+
getSecondsString() {
|
|
54
86
|
this.validateFormatOrThrow();
|
|
55
|
-
const seconds = this.
|
|
87
|
+
const seconds = this.originalTimeString.split(":")[2];
|
|
88
|
+
const secondsFirstDigit = seconds === null || seconds === void 0 ? void 0 : seconds.split("")[0];
|
|
89
|
+
const secondsSecondDigit = seconds === null || seconds === void 0 ? void 0 : seconds.split("")[1];
|
|
56
90
|
if (seconds)
|
|
57
|
-
return
|
|
91
|
+
return `${secondsFirstDigit}${secondsSecondDigit}`;
|
|
58
92
|
return "00";
|
|
59
93
|
}
|
|
60
94
|
static getNow() {
|
|
@@ -64,5 +98,8 @@ class ISO8601Time {
|
|
|
64
98
|
const seconds = nowDate.getSeconds().toString().padStart(2, "0");
|
|
65
99
|
return `${hours}:${minutes}:${seconds}`;
|
|
66
100
|
}
|
|
101
|
+
getTimezoneString() {
|
|
102
|
+
return this.getTimezone().selector.getTimezoneString(this.originalTimeString);
|
|
103
|
+
}
|
|
67
104
|
}
|
|
68
105
|
exports.ISO8601Time = ISO8601Time;
|
|
@@ -18,7 +18,7 @@ describe("ISO8601Time", () => {
|
|
|
18
18
|
});
|
|
19
19
|
it("Should construct with now time when receiving no arguments.", () => {
|
|
20
20
|
const time = new ISO8601Time_1.ISO8601Time();
|
|
21
|
-
expect(time.
|
|
21
|
+
expect(time.originalTimeString).toBe("23:00:00");
|
|
22
22
|
});
|
|
23
23
|
it("Should throw given irregular time format", () => {
|
|
24
24
|
const time = () => new ISO8601Time_1.ISO8601Time("000:00:10");
|
|
@@ -69,55 +69,146 @@ describe("ISO8601Time", () => {
|
|
|
69
69
|
describe("ISO8601Time.getHours()", () => {
|
|
70
70
|
it("Should return hours when valid", () => {
|
|
71
71
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
72
|
-
expect(time.
|
|
72
|
+
expect(time.getHoursString()).toBe("00");
|
|
73
73
|
const time2 = new ISO8601Time_1.ISO8601Time("00:01:02");
|
|
74
|
-
expect(time2.
|
|
74
|
+
expect(time2.getHoursString()).toBe("00");
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
describe("ISO8601Time.getMinutes()", () => {
|
|
78
78
|
it("Should return minutes when valid", () => {
|
|
79
79
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
80
|
-
expect(time.
|
|
80
|
+
expect(time.getMinutesString()).toBe("01");
|
|
81
81
|
const time2 = new ISO8601Time_1.ISO8601Time("00:01:02");
|
|
82
|
-
expect(time2.
|
|
82
|
+
expect(time2.getMinutesString()).toBe("01");
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
describe("ISO8601Time.getSeconds()", () => {
|
|
86
86
|
it("Should return seconds when valid", () => {
|
|
87
87
|
const time2 = new ISO8601Time_1.ISO8601Time("00:01:02");
|
|
88
|
-
expect(time2.
|
|
88
|
+
expect(time2.getSecondsString()).toBe("02");
|
|
89
89
|
});
|
|
90
90
|
it("Should return 00 when seconds are not present.", () => {
|
|
91
91
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
92
|
-
expect(time.
|
|
92
|
+
expect(time.getSecondsString()).toBe("00");
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
describe("ISO8601Time.getTime()", () => {
|
|
96
96
|
it("Should return time when valid", () => {
|
|
97
97
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
98
|
-
expect(time.
|
|
98
|
+
expect(time.getTimeString()).toBe("00:01:00");
|
|
99
99
|
const time2 = new ISO8601Time_1.ISO8601Time("00:01:02");
|
|
100
|
-
expect(time2.
|
|
100
|
+
expect(time2.getTimeString()).toBe("00:01:02");
|
|
101
101
|
});
|
|
102
102
|
it("Should return HH:MM if format argument is passed", () => {
|
|
103
103
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
104
|
-
expect(time.
|
|
104
|
+
expect(time.getTimeString({ format: "HH:MM" })).toBe("00:01");
|
|
105
105
|
});
|
|
106
106
|
it("Should return HH:MM if format argument is passed and time format is HH:MM:SS", () => {
|
|
107
107
|
const time = new ISO8601Time_1.ISO8601Time("00:01:10");
|
|
108
|
-
expect(time.
|
|
108
|
+
expect(time.getTimeString({ format: "HH:MM" })).toBe("00:01");
|
|
109
109
|
});
|
|
110
110
|
it("Should return HH:MM:SS by default", () => {
|
|
111
111
|
const time = new ISO8601Time_1.ISO8601Time("00:01:10");
|
|
112
|
-
expect(time.
|
|
112
|
+
expect(time.getTimeString()).toBe("00:01:10");
|
|
113
113
|
});
|
|
114
114
|
it("Should return HH:MM:SS by default even if format is HH:MM", () => {
|
|
115
115
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
116
|
-
expect(time.
|
|
116
|
+
expect(time.getTimeString()).toBe("00:01:00");
|
|
117
117
|
});
|
|
118
118
|
it("Should return HH:MM:SS given format argument", () => {
|
|
119
119
|
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
120
|
-
expect(time.
|
|
120
|
+
expect(time.getTimeString({ format: "HH:MM:SS" })).toBe("00:01:00");
|
|
121
|
+
});
|
|
122
|
+
it("Should return HH:MM:SS(+|-)HH:MM given format argument, defaulting to Z given no timezone.", () => {
|
|
123
|
+
const time = new ISO8601Time_1.ISO8601Time("00:01");
|
|
124
|
+
expect(time.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toBe("00:01:00Z");
|
|
125
|
+
});
|
|
126
|
+
it("Should return HH:MM:SS(+|-)HH:MM given format argument.", () => {
|
|
127
|
+
const time = new ISO8601Time_1.ISO8601Time("00:01:00+03:00");
|
|
128
|
+
expect(time.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toBe("00:01:00+03:00");
|
|
129
|
+
});
|
|
130
|
+
it("Should return HH:MM:SSZ given format argument and UTC timezone.", () => {
|
|
131
|
+
const time = new ISO8601Time_1.ISO8601Time("00:01:00Z");
|
|
132
|
+
expect(time.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toBe("00:01:00Z");
|
|
133
|
+
});
|
|
134
|
+
it("Should return HH:MM:SSZ given format argument and UTC timezone with milliseconds.", () => {
|
|
135
|
+
const time = new ISO8601Time_1.ISO8601Time("00:01:00.222Z");
|
|
136
|
+
expect(time.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toBe("00:01:00Z");
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe("ISO8601Time.addHours()", () => {
|
|
140
|
+
it("Should change from 21 to 22 when adding 1", () => {
|
|
141
|
+
const time = new ISO8601Time_1.ISO8601Time("21:00:00");
|
|
142
|
+
expect(time.addHours(1).getHoursString()).toEqual("22");
|
|
143
|
+
});
|
|
144
|
+
it("Should change from 21 to 00 when adding 3", () => {
|
|
145
|
+
const time = new ISO8601Time_1.ISO8601Time("21:00:00");
|
|
146
|
+
expect(time.addHours(3).getHoursString()).toEqual("00");
|
|
147
|
+
});
|
|
148
|
+
it("Should change from 21 to 22 when adding 25", () => {
|
|
149
|
+
const time = new ISO8601Time_1.ISO8601Time("21:00:00");
|
|
150
|
+
expect(time.addHours(25).getHoursString()).toEqual("22");
|
|
151
|
+
});
|
|
152
|
+
it("Should change from 23 to 22 when adding -1", () => {
|
|
153
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
154
|
+
expect(time.addHours(-1).getHoursString()).toEqual("22");
|
|
155
|
+
});
|
|
156
|
+
it("Should change from 00 to 23 when adding -1", () => {
|
|
157
|
+
const time = new ISO8601Time_1.ISO8601Time("00:00:00");
|
|
158
|
+
expect(time.addHours(-1).getHoursString()).toEqual("23");
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe("ISO8601Time.addMinutes()", () => {
|
|
162
|
+
it("Should change from 00 to 50 when adding 50", () => {
|
|
163
|
+
const time = new ISO8601Time_1.ISO8601Time("21:00:00");
|
|
164
|
+
expect(time.addMinutes(50).getMinutesString()).toEqual("50");
|
|
165
|
+
expect(time.addMinutes(50).getHoursString()).toEqual("21");
|
|
166
|
+
});
|
|
167
|
+
it("Should change from 00 to 01 when adding 61", () => {
|
|
168
|
+
const time = new ISO8601Time_1.ISO8601Time("21:00:00");
|
|
169
|
+
expect(time.addMinutes(61).getMinutesString()).toEqual("01");
|
|
170
|
+
expect(time.addMinutes(61).getHoursString()).toEqual("22");
|
|
171
|
+
});
|
|
172
|
+
it("Should change from 50 to 00 when adding 10", () => {
|
|
173
|
+
const time = new ISO8601Time_1.ISO8601Time("21:50:00");
|
|
174
|
+
expect(time.addMinutes(10).getMinutesString()).toEqual("00");
|
|
175
|
+
expect(time.addMinutes(10).getHoursString()).toEqual("22");
|
|
176
|
+
});
|
|
177
|
+
it("Should change from 00 to 10 when adding 610", () => {
|
|
178
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
179
|
+
expect(time.addMinutes(610).getMinutesString()).toEqual("10");
|
|
180
|
+
expect(time.addMinutes(610).getHoursString()).toEqual("09");
|
|
181
|
+
});
|
|
182
|
+
it("Should change from 00 to 50 when adding -10", () => {
|
|
183
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
184
|
+
expect(time.addMinutes(-10).getMinutesString()).toEqual("50");
|
|
185
|
+
expect(time.addMinutes(-10).getHoursString()).toEqual("22");
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe("ISO8601Time.addTimezone()", () => {
|
|
189
|
+
it("Should add a timezone using a number without converting it", () => {
|
|
190
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
191
|
+
expect(time.addTimezone(-180).getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("23:00:00-03:00");
|
|
192
|
+
expect(time.addTimezone(-180).getTimezoneString()).toEqual("-03:00");
|
|
193
|
+
});
|
|
194
|
+
it("Should add a timezone using a string without converting it", () => {
|
|
195
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
196
|
+
expect(time
|
|
197
|
+
.addTimezone("-03:00")
|
|
198
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("23:00:00-03:00");
|
|
199
|
+
expect(time.addTimezone("-03:00").getTimezoneString()).toEqual("-03:00");
|
|
200
|
+
});
|
|
201
|
+
it("Should add a timezone using a positive number without converting it", () => {
|
|
202
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
203
|
+
expect(time.addTimezone(180).getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("23:00:00+03:00");
|
|
204
|
+
expect(time.addTimezone(180).getTimezoneString()).toEqual("+03:00");
|
|
205
|
+
});
|
|
206
|
+
it("Should add a timezone using a positive timezone string without converting it", () => {
|
|
207
|
+
const time = new ISO8601Time_1.ISO8601Time("23:00:00");
|
|
208
|
+
expect(time
|
|
209
|
+
.addTimezone("+03:00")
|
|
210
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("23:00:00+03:00");
|
|
211
|
+
expect(time.addTimezone("+03:00").getTimezoneString()).toEqual("+03:00");
|
|
121
212
|
});
|
|
122
213
|
});
|
|
123
214
|
});
|
|
@@ -7,10 +7,17 @@ export interface IISO8601TimeValidator extends ITimeValidator {
|
|
|
7
7
|
isHHmmSSZ: (time: string) => boolean;
|
|
8
8
|
/** Accepted formats: `HH:MM:SS`, `HH:MM`, `HH:MM:SSZ`, `HH:MM:SS.sssZ` and `HH:MM:SS(+|-)HH:MM`. */
|
|
9
9
|
formatIsValid: (time: string) => boolean;
|
|
10
|
+
numberedTimezonePattern: RegExp;
|
|
10
11
|
}
|
|
11
12
|
export declare class ISO8601TimeValidator implements IISO8601TimeValidator {
|
|
12
13
|
private upTo23;
|
|
13
14
|
private upTo59;
|
|
15
|
+
private upTo11;
|
|
16
|
+
private upTo13;
|
|
17
|
+
numberedTimezonePatternString: string;
|
|
18
|
+
numberedTimezonePattern: RegExp;
|
|
19
|
+
private zTimezonePatternString;
|
|
20
|
+
private zAndMillisecondsPatternString;
|
|
14
21
|
private hhMMssPattern;
|
|
15
22
|
private hhMMPattern;
|
|
16
23
|
private hhMMssPlusNumberedTimezonePattern;
|
|
@@ -5,11 +5,17 @@ class ISO8601TimeValidator {
|
|
|
5
5
|
constructor() {
|
|
6
6
|
this.upTo23 = "([0-1][0-9]|[2][0-3])";
|
|
7
7
|
this.upTo59 = "[0-5][0-9]";
|
|
8
|
+
this.upTo11 = "(0[0-9]|1[0-2])";
|
|
9
|
+
this.upTo13 = "(0[0-9]|1[0-4])";
|
|
10
|
+
this.numberedTimezonePatternString = `(\\+(${this.upTo11}:${this.upTo59}|12:00)|\\-(${this.upTo13}:${this.upTo59}|14:00))`;
|
|
11
|
+
this.numberedTimezonePattern = new RegExp(`^${this.numberedTimezonePatternString}$`);
|
|
12
|
+
this.zTimezonePatternString = "Z";
|
|
13
|
+
this.zAndMillisecondsPatternString = `.[0-9]{3}Z`;
|
|
8
14
|
this.hhMMssPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}$`);
|
|
9
15
|
this.hhMMPattern = new RegExp(`^${this.upTo23}:${this.upTo59}$`);
|
|
10
|
-
this.hhMMssPlusNumberedTimezonePattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}
|
|
11
|
-
this.hhMMssZPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${this.upTo59}
|
|
12
|
-
this.hhMMssSSSZPattern = new RegExp(`^${this.upTo23}:${this.upTo59}:${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}$`);
|
|
13
19
|
this.isHHmmSSPlusNumberedTimezone = (time) => {
|
|
14
20
|
return this.hhMMssPlusNumberedTimezonePattern.test(time);
|
|
15
21
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IISO8601TimezoneParser, ISO8601TimezoneParser } from "./ISO8601TimezoneParser";
|
|
2
|
+
import { IISO8601TimezoneSelector, ISO8601TimezoneSelector } from "./ISO8601TimezoneSelector";
|
|
3
|
+
export interface IISO8601Timezone {
|
|
4
|
+
selector: IISO8601TimezoneSelector;
|
|
5
|
+
parser: IISO8601TimezoneParser;
|
|
6
|
+
}
|
|
7
|
+
export declare class ISO8601Timezone implements IISO8601Timezone {
|
|
8
|
+
readonly originalTimezoneString: string;
|
|
9
|
+
selector: ISO8601TimezoneSelector;
|
|
10
|
+
parser: ISO8601TimezoneParser;
|
|
11
|
+
constructor(originalTimezoneString?: string);
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ISO8601Timezone = void 0;
|
|
4
|
+
const ISO8601TimezoneParser_1 = require("./ISO8601TimezoneParser");
|
|
5
|
+
const ISO8601TimezoneSelector_1 = require("./ISO8601TimezoneSelector");
|
|
6
|
+
class ISO8601Timezone {
|
|
7
|
+
constructor(originalTimezoneString) {
|
|
8
|
+
this.selector = new ISO8601TimezoneSelector_1.ISO8601TimezoneSelector();
|
|
9
|
+
this.parser = new ISO8601TimezoneParser_1.ISO8601TimezoneParser();
|
|
10
|
+
this.originalTimezoneString = originalTimezoneString || "Z";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ISO8601Timezone = ISO8601Timezone;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ISO8601Timezone_1 = require("./ISO8601Timezone");
|
|
4
|
+
describe("ISO8601Timezone", () => {
|
|
5
|
+
describe("ISO8601Timezone constructor", () => {
|
|
6
|
+
it("Should be instantiable without arguments", () => {
|
|
7
|
+
const timezone = new ISO8601Timezone_1.ISO8601Timezone();
|
|
8
|
+
expect(timezone).toBeDefined();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ITime } from "./Time";
|
|
2
|
+
export interface IISO8601TimezoneConverter {
|
|
3
|
+
/**
|
|
4
|
+
* Converts an ISO8601 time, like `00:00:00` or `00:00:00+03:00` to a target timezone.
|
|
5
|
+
* If no timezone is present on the time string, it is considered UTC.
|
|
6
|
+
*/
|
|
7
|
+
convertTo: (opts: {
|
|
8
|
+
time: ITime;
|
|
9
|
+
targetTimezone: string | number;
|
|
10
|
+
}) => ITime;
|
|
11
|
+
}
|
|
12
|
+
export declare class ISO8601TimezoneConverter implements IISO8601TimezoneConverter {
|
|
13
|
+
private timezoneParser;
|
|
14
|
+
private timezoneValidator;
|
|
15
|
+
convertTo: (opts: {
|
|
16
|
+
time: ITime;
|
|
17
|
+
targetTimezone: string | number;
|
|
18
|
+
}) => ITime;
|
|
19
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ISO8601TimezoneConverter = void 0;
|
|
4
|
+
const ISO8601TimezoneParser_1 = require("./ISO8601TimezoneParser");
|
|
5
|
+
const ISO8601TimezoneValidator_1 = require("./ISO8601TimezoneValidator");
|
|
6
|
+
class ISO8601TimezoneConverter {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.timezoneParser = new ISO8601TimezoneParser_1.ISO8601TimezoneParser();
|
|
9
|
+
this.timezoneValidator = new ISO8601TimezoneValidator_1.ISO8601TimezoneValidator();
|
|
10
|
+
this.convertTo = (opts) => {
|
|
11
|
+
if (!this.timezoneValidator.formatIsValid(opts.targetTimezone)) {
|
|
12
|
+
throw new Error("Timezone format is invalid, could not convert.");
|
|
13
|
+
}
|
|
14
|
+
const originalTimezoneInMinutes = opts.time
|
|
15
|
+
.getTimezone()
|
|
16
|
+
.parser.toMinutes(opts.time.originalTimeString);
|
|
17
|
+
const targetTimezoneInMinutes = typeof opts.targetTimezone == "number"
|
|
18
|
+
? opts.targetTimezone
|
|
19
|
+
: this.timezoneParser.toMinutes(opts.targetTimezone);
|
|
20
|
+
const timezoneOffsetMinutes = targetTimezoneInMinutes - originalTimezoneInMinutes;
|
|
21
|
+
const hoursOffset = Math.floor(timezoneOffsetMinutes / 60);
|
|
22
|
+
const minutesOffset = timezoneOffsetMinutes - hoursOffset * 60;
|
|
23
|
+
const targetTime = opts.time.addHours(hoursOffset).addMinutes(minutesOffset).addTimezone(opts.targetTimezone);
|
|
24
|
+
return targetTime;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.ISO8601TimezoneConverter = ISO8601TimezoneConverter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ISO8601Time_1 = require("./ISO8601Time");
|
|
4
|
+
const ISO8601TimezoneConverter_1 = require("./ISO8601TimezoneConverter");
|
|
5
|
+
describe("ISO8601TimezoneConverter", () => {
|
|
6
|
+
describe("ISO8601TimezoneConverter constructor", () => {
|
|
7
|
+
it("Should be instantiable without arguments", () => {
|
|
8
|
+
const converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
9
|
+
expect(converter).toBeDefined();
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe("ISO8601TimezoneConverter.convertTo", () => {
|
|
13
|
+
it("Should convert UTC to Brazilian time", () => {
|
|
14
|
+
const converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
15
|
+
expect(converter
|
|
16
|
+
.convertTo({
|
|
17
|
+
time: new ISO8601Time_1.ISO8601Time("12:00:00"),
|
|
18
|
+
targetTimezone: -180,
|
|
19
|
+
})
|
|
20
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("09:00:00-03:00");
|
|
21
|
+
});
|
|
22
|
+
it("Should convert Brazilian time to UTC", () => {
|
|
23
|
+
const converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
24
|
+
expect(converter
|
|
25
|
+
.convertTo({
|
|
26
|
+
time: new ISO8601Time_1.ISO8601Time("09:00:00-03:00"),
|
|
27
|
+
targetTimezone: 0,
|
|
28
|
+
})
|
|
29
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("12:00:00Z");
|
|
30
|
+
});
|
|
31
|
+
it("Should convert to positive timezones", () => {
|
|
32
|
+
const converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
33
|
+
expect(converter
|
|
34
|
+
.convertTo({
|
|
35
|
+
time: new ISO8601Time_1.ISO8601Time("12:00:00"),
|
|
36
|
+
targetTimezone: 180,
|
|
37
|
+
})
|
|
38
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("15:00:00+03:00");
|
|
39
|
+
});
|
|
40
|
+
it("Should convert timezones even when days would change", () => {
|
|
41
|
+
const converter = new ISO8601TimezoneConverter_1.ISO8601TimezoneConverter();
|
|
42
|
+
expect(converter
|
|
43
|
+
.convertTo({
|
|
44
|
+
time: new ISO8601Time_1.ISO8601Time("01:00:00"),
|
|
45
|
+
targetTimezone: -180,
|
|
46
|
+
})
|
|
47
|
+
.getTimeString({ format: "HH:MM:SS(+|-)HH:MM" })).toEqual("22:00:00-03:00");
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface IISO8601TimezoneParser {
|
|
2
|
+
/**
|
|
3
|
+
* Takes a number from -840 to 720 and converts it to a timezone string eg:. `+03:00`, `-02:00`, `Z`,
|
|
4
|
+
*/
|
|
5
|
+
toString: (timezoneInMinutes: number) => string;
|
|
6
|
+
/**
|
|
7
|
+
* Takes a string, eg:. `+03:00`, `-02:00`, `Z` and returns a number representing the quantity of minutes
|
|
8
|
+
* from UTC.
|
|
9
|
+
*/
|
|
10
|
+
toMinutes: (timezone: string) => number;
|
|
11
|
+
}
|
|
12
|
+
export declare class ISO8601TimezoneParser implements IISO8601TimezoneParser {
|
|
13
|
+
private timezoneValidator;
|
|
14
|
+
private timezoneSelector;
|
|
15
|
+
toMinutes: (timezone: string) => number;
|
|
16
|
+
toString: (timezoneInMinutes: number) => string;
|
|
17
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ISO8601TimezoneParser = void 0;
|
|
4
|
+
const ISO8601TimezoneSelector_1 = require("./ISO8601TimezoneSelector");
|
|
5
|
+
const ISO8601TimezoneValidator_1 = require("./ISO8601TimezoneValidator");
|
|
6
|
+
class ISO8601TimezoneParser {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.timezoneValidator = new ISO8601TimezoneValidator_1.ISO8601TimezoneValidator();
|
|
9
|
+
this.timezoneSelector = new ISO8601TimezoneSelector_1.ISO8601TimezoneSelector();
|
|
10
|
+
this.toMinutes = (timezone) => {
|
|
11
|
+
if (this.timezoneValidator.timezoneIsZ(timezone) ||
|
|
12
|
+
this.timezoneValidator.timezoneIsZandMilliseconds(timezone)) {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
if (this.timezoneValidator.timezoneIsNumbered(timezone)) {
|
|
16
|
+
const minutesString = this.timezoneSelector.getMinutesString(timezone);
|
|
17
|
+
const hoursString = this.timezoneSelector.getHoursString(timezone);
|
|
18
|
+
if (minutesString == undefined || hoursString == undefined) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
const minutes = parseInt(minutesString);
|
|
22
|
+
const hours = parseInt(hoursString);
|
|
23
|
+
const sign = this.timezoneSelector.getTimezoneSign(timezone);
|
|
24
|
+
return sign == undefined
|
|
25
|
+
? 0
|
|
26
|
+
: sign == "+"
|
|
27
|
+
? minutes + hours * 60
|
|
28
|
+
: -(minutes + hours * 60);
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
};
|
|
32
|
+
this.toString = (timezoneInMinutes) => {
|
|
33
|
+
if (this.timezoneValidator.timezoneNumberIsValid(timezoneInMinutes)) {
|
|
34
|
+
if (timezoneInMinutes == 0)
|
|
35
|
+
return "Z";
|
|
36
|
+
const hours = Math.floor(Math.abs(timezoneInMinutes / 60));
|
|
37
|
+
const minutes = Math.abs(Math.abs(timezoneInMinutes) - hours * 60);
|
|
38
|
+
const hoursString = hours.toString().padStart(2, "0");
|
|
39
|
+
const minutesString = minutes.toString().padStart(2, "0");
|
|
40
|
+
const symbol = timezoneInMinutes > 0 ? "+" : "-";
|
|
41
|
+
return `${symbol}${hoursString}:${minutesString}`;
|
|
42
|
+
}
|
|
43
|
+
return "Z";
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ISO8601TimezoneParser = ISO8601TimezoneParser;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|