Skip to content

Commit

Permalink
fix(dateTime): calculate ralative time via duration (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
ValeraS authored Sep 30, 2024
1 parent 0cb9da1 commit 8b8d132
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 13 deletions.
42 changes: 40 additions & 2 deletions src/dateTime/dateTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,49 @@ class DateTimeImpl implements DateTime {
fromNow(withoutSuffix?: boolean | undefined): string {
return this.from(dateTime({timeZone: this._timeZone, lang: this._locale}), withoutSuffix);
}
from(formaInput: DateTimeInput, withoutSuffix?: boolean): string {
from(fromInput: DateTimeInput, withoutSuffix?: boolean): string {
if (!this.isValid()) {
return this._localeData.invalidDate || INVALID_DATE_STRING;
}
return fromTo(this, formaInput, this._localeData.relativeTime, withoutSuffix, true);

const value = DateTimeImpl.isDateTime(fromInput)
? fromInput.timeZone(this._timeZone)
: createDateTime({
ts: getTimestamp(fromInput, 'system', this._locale)[0],
timeZone: this._timeZone,
locale: this._locale,
offset: this._offset,
});

if (!value.isValid()) {
return this._localeData.invalidDate || INVALID_DATE_STRING;
}

let a = value;
let b: DateTime = this;
let switched = false;
if (b.isBefore(a)) {
a = this;
b = value;
switched = true;
}

let months = b.month() - a.month() + (b.year() - a.year()) * 12;
if (a.add(months, 'months').isAfter(b)) {
months--;
}
let milliseconds = b.valueOf() - a.add(months, 'months').valueOf();

if (switched) {
months = -months;
milliseconds = -milliseconds;
}

return fromTo(
duration({months, milliseconds}),
this._localeData.relativeTime,
withoutSuffix,
);
}
locale(): string;
locale(locale: string): DateTime;
Expand Down
11 changes: 4 additions & 7 deletions src/dateTime/relative.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type {Locale, RelativeTime} from '../settings/types';
import type {BaseUnit, DateTime, DateTimeInput} from '../typings';

import {dateTime} from './dateTime';
import type {BaseUnit, Duration} from '../typings';

export interface RelativeTimeThreshold {
l: Exclude<keyof RelativeTime, 'future' | 'past'>;
Expand Down Expand Up @@ -40,19 +38,18 @@ const relObj = {
} satisfies RelativeTime;

export function fromTo(
date: DateTime,
input: DateTimeInput,
duration: Duration,
loc: Locale['relativeTime'] = relObj,
withoutSuffix = false,
isFrom = true,
): string {
let result = 0;
let isFuture;
let out = '';

for (let i = 0; i < thresholds.length; i += 1) {
let t = thresholds[i];
if (t.d) {
result = isFrom ? date.diff(input, t.d, true) : dateTime({input}).diff(date, t.d, true);
result = duration.as(t.d);
}
const abs = Math.round(Math.abs(result));
isFuture = result > 0;
Expand Down
8 changes: 4 additions & 4 deletions src/duration/duration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2019 JS Foundation and other contributors
// Copyright 2024 YANDEX LLC

import {dateTimeUtc} from '../dateTime';
import {fromTo} from '../dateTime/relative';
import {settings} from '../settings';
import type {
Duration,
Expand All @@ -11,7 +11,7 @@ import type {
FormatOptions,
} from '../typings';
import {normalizeDateComponents, normalizeDurationUnit} from '../utils';
import {getListFormat, getNumberFormat} from '../utils/locale';
import {getListFormat, getLocaleData, getNumberFormat} from '../utils/locale';

import {createDuration} from './createDuration';
import {normalizeValues, orderedUnits, rescale, shiftTo} from './normalize';
Expand Down Expand Up @@ -294,8 +294,8 @@ export class DurationImpl implements Duration {
if (!this.isValid()) {
return 'Invalid Duration';
}
const now = dateTimeUtc({lang: this._locale});
return now.add(this.valueOf(), 'ms').from(now, !withSuffix);
const localeData = getLocaleData(this._locale);
return fromTo(this, localeData.relativeTime, !withSuffix);
}

humanizeIntl(
Expand Down
11 changes: 11 additions & 0 deletions src/utils/locale.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import dayjs from '../dayjs';
import type {Locale} from '../settings/types';

const dateTimeFormatCache = new Map<string, Intl.DateTimeFormat>();
export function getDateTimeFormat(locale: string, options: Intl.DateTimeFormatOptions = {}) {
const key = JSON.stringify([locale, options]);
Expand Down Expand Up @@ -33,3 +36,11 @@ export function getNumberFormat(locale: string, options: Intl.NumberFormatOption
}
return numberFormat;
}

export function getLocaleData(locale: string) {
const localeData = dayjs.Ls[locale];
if (!localeData) {
throw new Error(`Locale ${locale} is not loaded`);
}
return localeData as Locale;
}

0 comments on commit 8b8d132

Please sign in to comment.