freepbx-stats/timeSpan.js
2025-09-20 19:19:07 +02:00

129 lines
3.5 KiB
JavaScript

/**
* Represents a timespan with a start and end time.
*/
export class TimeSpan {
// constructors
constructor(start = Date.now(), end = Date.now()) {
if (start > end) {
throw new Error("Start time must be less than or equal to end time.");
}
this.start = start;
this.end = end;
}
static fromDates(startDate, endDate) {
return new TimeSpan(startDate, endDate);
}
static fromMillis(millis) {
return new TimeSpan(0, millis);
}
static fromSeconds(seconds) {
return TimeSpan.fromMillis(seconds * 1000);
}
// methods
get totalMillis() {
return this.end - this.start;
}
get millis() {
return Math.floor((this.totalMillis) % 1000);
}
get totalSeconds() {
return Math.floor(this.totalMillis / 1000);
}
get seconds() {
return Math.floor((this.totalMillis) / 1000 % 60);
}
get totalMinutes() {
return Math.floor(this.totalMillis / 1000 / 60);
}
get minutes() {
return Math.floor(this.totalMillis / 1000 / 60 % 60);
}
get totalHours() {
return Math.floor(this.totalMillis / 1000 / 60 / 60);
}
get hours() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 % 24);
}
get totalDays() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24);
}
get days() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 % 30.44); // Average days in a month
}
get weekDays() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 % 7);
}
get totalWeeks() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 7);
}
get weeks() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 7 % 4.345); // Average weeks in a month
}
get totalMonths() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 30.44); // Average days in a month
}
get months() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 30.44 % 12); // Average days in a month
}
get totalYears() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 365.25); // Average days in a year
}
get years() {
return Math.floor(this.totalMillis / 1000 / 60 / 60 / 24 / 365.25 % 1); // Average days in a year
}
toString(includeWeeks = true, includeMillis = true) {
const parts = [];
if (this.totalYears >= 1) parts.push(`${this.totalYears} years`);
if (this.totalMonths >= 1) parts.push(`${this.months} months`);
if (includeWeeks && this.totalWeeks >= 1) parts.push(`${this.weeks} weeks`);
if (this.totalDays >= 1) parts.push(`${includeWeeks ? this.weekDays : this.days} days`);
if (this.totalHours >= 1) parts.push(`${this.hours} hours`);
if (this.totalMinutes >= 1) parts.push(`${this.minutes} minutes`);
if (this.totalSeconds >= 1) parts.push(`${this.seconds} seconds`);
if (includeMillis) parts.push(`${this.millis} milliseconds`);
return parts.join(", ");
}
toShortString(includeWeeks = true, includeMillis = true, withSpaces = false) {
const parts = [];
if (this.totalYears >= 1) parts.push(`${this.totalYears}y`);
if (this.totalMonths >= 1) parts.push(`${this.months}mo`);
if (includeWeeks && this.totalWeeks >= 1) parts.push(`${this.weeks}w`);
if (this.totalDays >= 1) parts.push(`${includeWeeks ? this.weekDays : this.days}d`);
if (this.totalHours >= 1) parts.push(`${this.hours}h`);
if (this.totalMinutes >= 1) parts.push(`${this.minutes}m`);
if (this.totalSeconds >= 1) parts.push(`${this.seconds}s`);
if (includeMillis) parts.push(`${this.millis}ms`);
return parts.join(withSpaces ? " " : "");
}
get startDate() {
return new Date(this.start);
}
get endDate() {
return new Date(this.end);
}
}