Skip to content

Commit

Permalink
feat(i18n): full relative time
Browse files Browse the repository at this point in the history
  • Loading branch information
MM25Zamanian committed Aug 26, 2024
1 parent 6e77fd2 commit 5a1e15a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
50 changes: 50 additions & 0 deletions packages/i18n/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,60 @@ export class GecutI18N implements I18nInterface {
return this.msg('just_now');
}

rtf(_origin: string | Date, _destination: string | Date = new Date()): string {
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const MONTH = 30 * DAY;
const YEAR = 365 * DAY;

const units: Record<DateTimeRelativeKey, number> = {
years: YEAR,
months: MONTH,
days: DAY,
hours: HOUR,
minutes: MINUTE,
seconds: SECOND,
};

const origin = new Date(_origin);
const destination = new Date(_destination);

let elapsed = destination.getTime() - origin.getTime();

const timeUnits: Record<string, number> = {};

for (const [unit, amount] of Object.entries(units)) {
const count = Math.floor(elapsed / amount);
if (count > 0) {
timeUnits[unit] = count;
elapsed -= count * amount;
}
}

const timeStrings: string[] = [];

for (const [unit, count] of Object.entries(timeUnits)) {
const resourceKey = GecutI18N.getResourcesKeyForRelativeTime(count, unit as DateTimeRelativeKey);

timeStrings.push(this.msg(resourceKey, {'{0}': count.toString()}));
}

if (timeStrings.length === 0) {
return this.msg('just_now');
}

return timeStrings.join(' ' + this.msg('and') + ' ');
}

private static getResourcesKeyForRelativeTime(count: number, unit: DateTimeRelativeKey): string {
if (count === 1) {
return `one_${unit}`;
}
if (unit === 'seconds') {
return 'other_seconds_ago';
}
return `other_${unit}`;
}
}
8 changes: 7 additions & 1 deletion packages/i18n/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ export interface LocaleType {

type __DateTimeRelativeKey = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second';

export type BaseTranslationsKeys = `one_${__DateTimeRelativeKey}s` | `other_${__DateTimeRelativeKey}s` | 'just_now';
export type BaseTranslationsKeys =
| `one_${__DateTimeRelativeKey}s_ago`
| `other_${__DateTimeRelativeKey}s_ago`
| `one_${__DateTimeRelativeKey}s`
| `other_${__DateTimeRelativeKey}s`
| 'and'
| 'just_now';

export type DateTimeRelativeKey = `${__DateTimeRelativeKey}s`;

Expand Down

0 comments on commit 5a1e15a

Please sign in to comment.