171 lines
4.5 KiB
JavaScript
171 lines
4.5 KiB
JavaScript
export class Time {
|
|
constructor(obj) {
|
|
this.hour = obj.hour ?? 0;
|
|
this.minute = obj.minute ?? 0;
|
|
this.second = obj.second ?? 0;
|
|
}
|
|
|
|
static fromInputValue(str) {
|
|
const parts = str.split(':');
|
|
return new Time({hour: parts[0], minute: parts[1], second: parts[2]});
|
|
}
|
|
|
|
asJsonObject() {
|
|
let res = {}
|
|
if (this.hour !== 0) res.hour = this.hour;
|
|
if (this.minute !== 0) res.minute = this.minute;
|
|
if (this.second !== 0) res.second = this.second;
|
|
return res;
|
|
}
|
|
|
|
cmp(other) {
|
|
if (this.hour < other.hour) return -1;
|
|
if (this.hour > other.hour) return 1;
|
|
if (this.minute < other.minute) return -1;
|
|
if (this.minute > other.minute) return 1;
|
|
if (this.second < other.second) return -1;
|
|
if (this.second > other.second) return 1;
|
|
return 0;
|
|
}
|
|
|
|
get durationSinceMidnight() {
|
|
return new TimeRange({start_time: new Time({}), end_time: this}).duration;
|
|
}
|
|
|
|
plus(duration) {
|
|
const total = this.durationSinceMidnight.total_seconds
|
|
+ duration.total_seconds;
|
|
const second = total % 60;
|
|
const minute = Math.floor(total / 60) % 60;
|
|
const hour = Math.floor(total / 60 / 60) % 24;
|
|
return new Time({hour, minute, second});
|
|
}
|
|
|
|
// TODO Just ignoring seconds?
|
|
to12HourString() {
|
|
let hour = this.hour % 12;
|
|
if (hour === 0) hour = 12;
|
|
return hour + ':' + this.minute.toString().padStart(2, '0');
|
|
}
|
|
|
|
get inputValue() {
|
|
return this.hour.toString().padStart(2, '0') + ':'
|
|
+ this.minute.toString().padStart(2, '0') + ':'
|
|
+ this.second.toString().padStart(2, '0');
|
|
}
|
|
}
|
|
|
|
export class Duration {
|
|
constructor(obj) {
|
|
if (obj.total_seconds) {
|
|
this.total_seconds = obj.total_seconds;
|
|
this.hour = Math.floor(obj.total_seconds / 60 / 60);
|
|
this.minute = Math.floor(obj.total_seconds / 60) % 60;
|
|
this.second = obj.total_seconds % 60;
|
|
} else {
|
|
this.hour = obj.hour ?? 0;
|
|
this.minute = obj.minute ?? 0;
|
|
this.second = obj.second ?? 0;
|
|
this.total_seconds = ((this.hour * 60) + this.minute) * 60 + this.second;
|
|
}
|
|
}
|
|
|
|
asJsonObject() {
|
|
let res = {}
|
|
if (this.hour !== 0) res.hour = this.hour;
|
|
if (this.minute !== 0) res.minute = this.minute;
|
|
if (this.second !== 0) res.second = this.second;
|
|
return res;
|
|
}
|
|
|
|
dividedBy(other) {
|
|
return this.total_seconds / other.total_seconds;
|
|
}
|
|
|
|
times(num) {
|
|
const total = this.total_seconds * num;
|
|
const second = total % 60;
|
|
const minute = Math.floor(total / 60) % 60;
|
|
const hour = Math.floor(total / 60 / 60);
|
|
return new Duration({hour, minute, second});
|
|
}
|
|
|
|
toString() {
|
|
let res = "";
|
|
if (this.hour) {
|
|
res += this.hour + (this.hour === 1 ? " hour" : " hours ");
|
|
}
|
|
if (this.minute) {
|
|
res += this.minute + (this.minute === 1 ? " minute" : " minutes ");
|
|
}
|
|
if (this.second) {
|
|
res += this.second + (this.second === 1 ? " second" : " seconds");
|
|
}
|
|
|
|
return this.total_seconds === 0 ? "0 seconds" : res.trimEnd();
|
|
}
|
|
|
|
get inputValue() {
|
|
return new Time({}).plus(this).inputValue;
|
|
}
|
|
}
|
|
|
|
export class TimeRange {
|
|
constructor(args) {
|
|
this.start_time = args.start_time;
|
|
this.end_time = args.end_time;
|
|
}
|
|
|
|
get duration() {
|
|
return new Duration({
|
|
'total_seconds': 60 * 60 * (this.end_time.hour - this.start_time.hour)
|
|
+ 60 * (this.end_time.minute - this.start_time.minute)
|
|
+ this.end_time.second - this.start_time.second,
|
|
});
|
|
}
|
|
|
|
overlaps(other) {
|
|
return (other.start_time.cmp(this.start_time) <= 0
|
|
&& this.start_time.cmp(other.end_time) < 0)
|
|
|| (this.start_time.cmp(other.start_time) <= 0
|
|
&& other.start_time.cmp(this.end_time) < 0);
|
|
}
|
|
}
|
|
|
|
const dayDictionary = {
|
|
'M': 'Monday',
|
|
'T': 'Tuesday',
|
|
'W': 'Wednesday',
|
|
'R': 'Thursday',
|
|
'F': 'Friday',
|
|
'S': 'Saturday',
|
|
'U': 'Sunday',
|
|
};
|
|
|
|
export function DayString(day) {
|
|
return dayDictionary[day];
|
|
}
|
|
|
|
export const allDays = Object.keys(dayDictionary);
|
|
|
|
export function clearChildren(el) {
|
|
while (el.firstChild) el.removeChild(el.lastChild);
|
|
}
|
|
|
|
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
|
|
export function setDifference(setA, setB) {
|
|
const _difference = new Set(setA);
|
|
for (const elem of setB) {
|
|
_difference.delete(elem);
|
|
}
|
|
return _difference;
|
|
}
|
|
|
|
export function setEqual(setA, setB) {
|
|
if (!(setA instanceof Set)) setA = new Set(setA);
|
|
if (!(setB instanceof Set)) setB = new Set(setB);
|
|
|
|
if (setA.size != setB.size) return false;
|
|
return setDifference(setA, setB).size === 0;
|
|
}
|