anki/ts/lib/time.ts

162 lines
4.7 KiB
TypeScript
Raw Normal View History

2020-06-27 11:24:49 +02:00
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import * as tr from "./i18n";
2020-06-27 11:24:49 +02:00
2020-06-27 14:10:56 +02:00
export const SECOND = 1.0;
export const MINUTE = 60.0 * SECOND;
export const HOUR = 60.0 * MINUTE;
export const DAY = 24.0 * HOUR;
export const MONTH = 30.0 * DAY;
export const YEAR = 12.0 * MONTH;
2020-06-27 11:24:49 +02:00
enum TimespanUnit {
Seconds,
Minutes,
Hours,
Days,
Months,
Years,
}
export function unitName(unit: TimespanUnit): string {
2020-06-27 11:24:49 +02:00
switch (unit) {
case TimespanUnit.Seconds:
return "seconds";
case TimespanUnit.Minutes:
return "minutes";
case TimespanUnit.Hours:
return "hours";
case TimespanUnit.Days:
return "days";
case TimespanUnit.Months:
return "months";
case TimespanUnit.Years:
return "years";
}
}
export function naturalUnit(secs: number): TimespanUnit {
2020-06-27 11:24:49 +02:00
secs = Math.abs(secs);
if (secs < MINUTE) {
return TimespanUnit.Seconds;
} else if (secs < HOUR) {
return TimespanUnit.Minutes;
} else if (secs < DAY) {
return TimespanUnit.Hours;
} else if (secs < MONTH) {
return TimespanUnit.Days;
} else if (secs < YEAR) {
return TimespanUnit.Months;
} else {
return TimespanUnit.Years;
}
}
export function unitAmount(unit: TimespanUnit, secs: number): number {
2020-06-27 11:24:49 +02:00
switch (unit) {
case TimespanUnit.Seconds:
return secs;
case TimespanUnit.Minutes:
return secs / MINUTE;
case TimespanUnit.Hours:
return secs / HOUR;
case TimespanUnit.Days:
return secs / DAY;
case TimespanUnit.Months:
return secs / MONTH;
case TimespanUnit.Years:
return secs / YEAR;
}
}
export function studiedToday(cards: number, secs: number): string {
2020-06-27 11:24:49 +02:00
const unit = naturalUnit(secs);
const amount = unitAmount(unit, secs);
const name = unitName(unit);
let secsPer = 0;
if (cards > 0) {
secsPer = secs / cards;
}
return tr.statisticsStudiedToday({
unit: name,
secsPerCard: secsPer,
2020-06-27 11:24:49 +02:00
cards,
amount,
});
}
2020-06-27 14:10:56 +02:00
2021-03-26 10:24:48 +01:00
function i18nFuncForUnit(
unit: TimespanUnit,
short: boolean
): ({ amount: number }) => string {
if (short) {
switch (unit) {
case TimespanUnit.Seconds:
return tr.statisticsElapsedTimeSeconds;
case TimespanUnit.Minutes:
return tr.statisticsElapsedTimeMinutes;
case TimespanUnit.Hours:
return tr.statisticsElapsedTimeHours;
case TimespanUnit.Days:
return tr.statisticsElapsedTimeDays;
case TimespanUnit.Months:
return tr.statisticsElapsedTimeMonths;
case TimespanUnit.Years:
return tr.statisticsElapsedTimeYears;
}
} else {
switch (unit) {
case TimespanUnit.Seconds:
return tr.schedulingTimeSpanSeconds;
case TimespanUnit.Minutes:
return tr.schedulingTimeSpanMinutes;
case TimespanUnit.Hours:
return tr.schedulingTimeSpanHours;
case TimespanUnit.Days:
return tr.schedulingTimeSpanDays;
case TimespanUnit.Months:
return tr.schedulingTimeSpanMonths;
case TimespanUnit.Years:
return tr.schedulingTimeSpanYears;
}
}
}
2020-06-27 14:10:56 +02:00
/// Describe the given seconds using the largest appropriate unit.
/// If precise is true, show to two decimal places, eg
/// eg 70 seconds -> "1.17 minutes"
/// If false, seconds and days are shown without decimals.
export function timeSpan(seconds: number, short = false): string {
2020-06-27 14:10:56 +02:00
const unit = naturalUnit(seconds);
const amount = unitAmount(unit, seconds);
return i18nFuncForUnit(unit, short)({ amount });
2020-06-27 14:10:56 +02:00
}
2020-06-28 11:34:19 +02:00
export function dayLabel(daysStart: number, daysEnd: number): string {
2020-06-28 11:34:19 +02:00
const larger = Math.max(Math.abs(daysStart), Math.abs(daysEnd));
const smaller = Math.min(Math.abs(daysStart), Math.abs(daysEnd));
if (larger - smaller <= 1) {
// singular
if (daysStart >= 0) {
return tr.statisticsInDaysSingle({ days: daysStart });
2020-06-28 11:34:19 +02:00
} else {
return tr.statisticsDaysAgoSingle({ days: -daysStart });
2020-06-28 11:34:19 +02:00
}
} else {
// range
if (daysStart >= 0) {
return tr.statisticsInDaysRange({
daysStart,
daysEnd: daysEnd - 1,
});
2020-06-28 11:34:19 +02:00
} else {
return tr.statisticsDaysAgoRange({
daysStart: Math.abs(daysEnd - 1),
daysEnd: -daysStart,
2020-06-28 11:34:19 +02:00
});
}
}
}