diff options
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/shared/date-helper.ts | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/gui/src/shared/date-helper.ts b/gui/src/shared/date-helper.ts new file mode 100644 index 0000000000..0011ed8fc2 --- /dev/null +++ b/gui/src/shared/date-helper.ts @@ -0,0 +1,121 @@ +import { sprintf } from 'sprintf-js'; +import { messages } from './gettext'; + +export type DateType = Date | string; + +export enum DateComponent { + day, + hour, + minute, +} + +export function dateByAddingComponent(date: DateType, component: DateComponent, value: number) { + const modifiedDate = new Date(date); + switch (component) { + case DateComponent.day: + modifiedDate.setDate(modifiedDate.getDate() + value); + break; + case DateComponent.hour: + modifiedDate.setHours(modifiedDate.getHours() + value); + break; + case DateComponent.minute: + modifiedDate.setMinutes(modifiedDate.getMinutes() + value); + break; + } + + return modifiedDate; +} + +export class DateDiff { + private readonly fromDate: Date; + private readonly toDate: Date; + + public constructor(fromDate: DateType, toDate: DateType) { + this.fromDate = new Date(fromDate); + this.toDate = new Date(toDate); + } + + get milliseconds(): number { + return this.toDate.getTime() - this.fromDate.getTime(); + } + + get seconds(): number { + return this.floor(this.milliseconds / 1000); + } + + get minutes(): number { + return this.floor(this.seconds / 60); + } + + get hours(): number { + return this.floor(this.minutes / 60); + } + + get days(): number { + return this.floor(this.hours / 24); + } + + get months(): number { + const months = new Date(Math.abs(this.milliseconds)).getUTCMonth(); + const monthsWithSign = this.milliseconds >= 0 ? months : -months; + return this.years * 12 + monthsWithSign; + } + + get years(): number { + const years = new Date(Math.abs(this.milliseconds)).getUTCFullYear() - 1970; + return this.milliseconds >= 0 ? years : -years; + } + + private floor(n: number): number { + return n >= 0 ? Math.floor(n) : Math.ceil(n); + } +} + +export function formatRelativeDate( + fromDate: DateType, + toDate: DateType, + withSuffix = false, +): string { + const diff = new DateDiff(fromDate, toDate); + const years = Math.abs(diff.years); + const months = Math.abs(diff.months); + const days = Math.abs(diff.days); + const hours = Math.abs(diff.hours); + const minutes = Math.abs(diff.minutes); + + if (!withSuffix) { + if (years > 0) { + return sprintf(messages.ngettext('1 year', '%d years', years), years); + } else if (months >= 3) { + return sprintf(messages.ngettext('1 month', '%d months', months), months); + } else if (days > 0) { + return sprintf(messages.ngettext('1 day', '%d days', days), days); + } else { + return messages.gettext('less than a day'); + } + } else if (diff.milliseconds > 0) { + if (years > 0) { + return sprintf(messages.ngettext('1 year left', '%d years left', years), years); + } else if (months >= 3) { + return sprintf(messages.ngettext('1 month left', '%d months left', months), months); + } else if (days > 0) { + return sprintf(messages.ngettext('1 day left', '%d days left', days), days); + } else { + return messages.gettext('less than a day left'); + } + } else { + if (years > 0) { + return sprintf(messages.ngettext('a year ago', '%d years ago', years), years); + } else if (months > 0) { + return sprintf(messages.ngettext('a month ago', '%d months ago', months), months); + } else if (days > 0) { + return sprintf(messages.ngettext('a day ago', '%d days ago', days), days); + } else if (hours > 0) { + return sprintf(messages.ngettext('an hour ago', '%d hours ago', hours), hours); + } else if (minutes > 0) { + return sprintf(messages.ngettext('a minute ago', '%d minutes ago', minutes), minutes); + } else { + return messages.gettext('less than a minute ago'); + } + } +} |
