MOBILE-3919 utils: Move formatTime functions to CoreTime

main
Dani Palou 2022-03-29 08:13:58 +02:00
parent b793a9dbe9
commit 9b40c5e87e
13 changed files with 103 additions and 73 deletions

View File

@ -26,6 +26,7 @@ import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTime } from '@singletons/time';
import { AddonModAssignListFilterName } from '../../classes/submissions-source';
import {
AddonModAssign,
@ -182,7 +183,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
if (this.assign.duedate - time <= 0) {
this.timeRemaining = Translate.instant('addon.mod_assign.assignmentisdue');
} else {
this.timeRemaining = CoreTimeUtils.formatTime(this.assign.duedate - time);
this.timeRemaining = CoreTime.formatTime(this.assign.duedate - time);
}
if (this.assign.duedate < time) {

View File

@ -58,6 +58,7 @@ import { CoreSync } from '@services/sync';
import { AddonModAssignSubmissionPluginComponent } from '../submission-plugin/submission-plugin';
import { AddonModAssignModuleHandlerService } from '../../services/handlers/module';
import { CanLeave } from '@guards/can-leave';
import { CoreTime } from '@singletons/time';
/**
* Component that displays an assignment submission.
@ -230,7 +231,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
this.timeRemaining = Translate.instant(
'addon.mod_assign.' + (onTime ? earlyString : lateString),
{ $a: CoreTimeUtils.formatTime(Math.abs(lateCalculation - lateThreshold)) },
{ $a: CoreTime.formatTime(Math.abs(lateCalculation - lateThreshold)) },
);
this.timeRemainingClass = onTime ? 'earlysubmission' : 'latesubmission';
@ -242,7 +243,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
const submissionsEnabled = response.lastattempt?.submissionsenabled || response.gradingsummary?.submissionsenabled;
this.timeRemaining = Translate.instant(
'addon.mod_assign.' + (submissionsEnabled ? 'overdue' : 'duedatereached'),
{ $a: CoreTimeUtils.formatTime(time - this.assign.duedate) },
{ $a: CoreTime.formatTime(time - this.assign.duedate) },
);
this.timeRemainingClass = 'overdue';
this.timeLimitFinished = true;
@ -260,7 +261,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
}
// Assignment is not overdue, and no submission has been made. Just display the due date.
this.timeRemaining = CoreTimeUtils.formatTime(this.assign.duedate - time);
this.timeRemaining = CoreTime.formatTime(this.assign.duedate - time);
this.timeRemainingClass = 'timeremaining';
}
@ -367,7 +368,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
try {
await CoreDomUtils.showConfirm(
Translate.instant('addon.mod_assign.confirmstart', {
$a: CoreTimeUtils.formatTime(this.assign.timelimit),
$a: CoreTime.formatTime(this.assign.timelimit),
}),
undefined,
Translate.instant('addon.mod_assign.beginassignment'),

View File

@ -18,6 +18,7 @@ import { CoreCourseContentsPage } from '@features/course/pages/contents/contents
import { IonContent } from '@ionic/angular';
import { CoreNavigator } from '@services/navigator';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreTime } from '@singletons/time';
import { AddonModChat, AddonModChatChat, AddonModChatProvider } from '../../services/chat';
import { AddonModChatModuleHandlerService } from '../../services/handlers/module';
@ -67,7 +68,7 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp
if (this.chat.chattime && this.chat.schedule && span > 0) {
this.chatInfo = {
date: CoreTimeUtils.userDate(this.chat.chattime * 1000),
fromnow: CoreTimeUtils.formatTime(span),
fromnow: CoreTime.formatTime(span),
};
} else {
this.chatInfo = undefined;

View File

@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
import { CoreWSExternalWarning, CoreWSExternalFile, CoreWSFile } from '@services/ws';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
@ -27,6 +26,7 @@ import { makeSingleton, Translate } from '@singletons/index';
import { CoreWSError } from '@classes/errors/wserror';
import { CoreError } from '@classes/errors/error';
import { AddonModH5PActivityAutoSyncData, AddonModH5PActivitySyncProvider } from './h5pactivity-sync';
import { CoreTime } from '@singletons/time';
const ROOT_CACHE_KEY = 'mmaModH5PActivity:';
@ -90,8 +90,8 @@ export class AddonModH5PActivityProvider {
formattedAttempt.durationReadable = '-';
formattedAttempt.durationCompact = '-';
} else {
formattedAttempt.durationReadable = CoreTimeUtils.formatTime(attempt.duration, 3);
formattedAttempt.durationCompact = CoreTimeUtils.formatTimeShort(attempt.duration);
formattedAttempt.durationReadable = CoreTime.formatTime(attempt.duration, 3);
formattedAttempt.durationCompact = CoreTime.formatTimeShort(attempt.duration);
}
return formattedAttempt;

View File

@ -25,7 +25,6 @@ import { CoreNavigator } from '@services/navigator';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreForms } from '@singletons/form';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { AddonModLessonRetakeFinishedInSyncDBRecord } from '../../services/database/lesson';
@ -47,6 +46,7 @@ import {
AddonModLessonSyncResult,
} from '../../services/lesson-sync';
import { AddonModLessonModuleHandlerService } from '../../services/handlers/module';
import { CoreTime } from '@singletons/time';
/**
* Component that displays a lesson entry page.
@ -505,15 +505,15 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
// Format times and grades.
if (formattedData.avetime != null && formattedData.numofattempts) {
formattedData.avetime = Math.floor(formattedData.avetime / formattedData.numofattempts);
this.avetimeReadable = CoreTimeUtils.formatTime(formattedData.avetime);
this.avetimeReadable = CoreTime.formatTime(formattedData.avetime);
}
if (formattedData.hightime != null) {
this.hightimeReadable = CoreTimeUtils.formatTime(formattedData.hightime);
this.hightimeReadable = CoreTime.formatTime(formattedData.hightime);
}
if (formattedData.lowtime != null) {
this.lowtimeReadable = CoreTimeUtils.formatTime(formattedData.lowtime);
this.lowtimeReadable = CoreTime.formatTime(formattedData.lowtime);
}
if (formattedData.lessonscored) {

View File

@ -34,8 +34,8 @@ import {
AddonModLessonUserAttemptAnswerPageWSData,
} from '../../services/lesson';
import { AddonModLessonAnswerData, AddonModLessonHelper } from '../../services/lesson-helper';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreCourse } from '@features/course/services/course';
import { CoreTime } from '@singletons/time';
/**
* Page that displays a retake made by a certain user.
@ -222,7 +222,7 @@ export class AddonModLessonUserRetakePage implements OnInit {
if (formattedData.userstats.gradeinfo) {
// Completed.
formattedData.userstats.grade = CoreTextUtils.roundToDecimals(formattedData.userstats.grade, 2);
this.timeTakenReadable = CoreTimeUtils.formatTime(formattedData.userstats.timetotake);
this.timeTakenReadable = CoreTime.formatTime(formattedData.userstats.timetotake);
}
// Format pages data.

View File

@ -26,6 +26,7 @@ import {
AddonModLessonGetPageDataWSResponse,
AddonModLessonProvider,
} from './lesson';
import { CoreTime } from '@singletons/time';
/**
* Helper service that provides some features for quiz.
@ -531,7 +532,7 @@ export class AddonModLessonHelperProvider {
}
data.timestart = CoreTimeUtils.userDate(retake.timestart * 1000);
if (includeDuration) {
data.duration = CoreTimeUtils.formatTime(retake.timeend - retake.timestart);
data.duration = CoreTime.formatTime(retake.timeend - retake.timestart);
}
} else {
// The user has not completed the retake.

View File

@ -16,7 +16,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreTime } from '@singletons/time';
/**
* Component to render the preflight for time limit.
@ -41,7 +41,7 @@ export class AddonModQuizAccessTimeLimitComponent implements OnInit {
return;
}
this.readableTimeLimit = CoreTimeUtils.formatTime(this.quiz?.timelimit);
this.readableTimeLimit = CoreTime.formatTime(this.quiz?.timelimit);
}
}

View File

@ -24,7 +24,6 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { ModalController, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events';
@ -47,6 +46,7 @@ import { AddonModQuizSync } from '../../services/quiz-sync';
import { CanLeave } from '@guards/can-leave';
import { CoreForms } from '@singletons/form';
import { CoreDom } from '@singletons/dom';
import { CoreTime } from '@singletons/time';
/**
* Page that allows attempting a quiz.
@ -352,7 +352,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
}
if (this.quiz!.timelimit && this.quiz!.timelimit > 0) {
this.readableTimeLimit = CoreTimeUtils.formatTime(this.quiz.timelimit);
this.readableTimeLimit = CoreTime.formatTime(this.quiz.timelimit);
}
// Get access information for the quiz.

View File

@ -19,10 +19,10 @@ import { CoreQuestionHelper } from '@features/question/services/question-helper'
import { IonContent, IonRefresher } from '@ionic/angular';
import { CoreNavigator } from '@services/navigator';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreDom } from '@singletons/dom';
import { CoreTime } from '@singletons/time';
import {
AddonModQuizNavigationModalComponent,
AddonModQuizNavigationModalReturn,
@ -276,11 +276,11 @@ export class AddonModQuizReviewPage implements OnInit {
const timeTaken = (this.attempt.timefinish || 0) - (this.attempt.timestart || 0);
if (timeTaken > 0) {
// Format time taken.
this.timeTaken = CoreTimeUtils.formatTime(timeTaken);
this.timeTaken = CoreTime.formatTime(timeTaken);
// Calculate overdue time.
if (this.quiz.timelimit && timeTaken > this.quiz.timelimit + 60) {
this.overTime = CoreTimeUtils.formatTime(timeTaken - this.quiz.timelimit);
this.overTime = CoreTime.formatTime(timeTaken - this.quiz.timelimit);
}
} else {
this.timeTaken = undefined;

View File

@ -14,7 +14,7 @@
import { Pipe, PipeTransform } from '@angular/core';
import { CoreLogger } from '@singletons/logger';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreTime } from '@singletons/time';
/**
* Filter to turn a number of seconds to a duration. E.g. 60 -> 1 minute.
@ -48,7 +48,7 @@ export class CoreDurationPipe implements PipeTransform {
seconds = numberSeconds;
}
return CoreTimeUtils.formatTime(seconds);
return CoreTime.formatTime(seconds);
}
}

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import moment, { LongDateFormatKey } from 'moment';
import { makeSingleton, Translate } from '@singletons';
import { CoreTime } from '@singletons/time';
/*
* "Utils" service with helper functions for date and time.
@ -160,39 +161,10 @@ export class CoreTimeUtilsProvider {
* @param seconds A number of seconds
* @param precision Number of elements to have in precision.
* @return Seconds in a human readable format.
* @deprecated since app 4.0. Use CoreTime.formatTime instead.
*/
formatTime(seconds: number, precision = 2): string {
precision = precision || 6; // Use max precision if 0 is passed.
const eventDuration = moment.duration(Math.abs(seconds), 'seconds');
let durationString = '';
if (precision && eventDuration.years() > 0) {
durationString += ' ' + moment.duration(eventDuration.years(), 'years').humanize();
precision--;
}
if (precision && eventDuration.months() > 0) {
durationString += ' ' + moment.duration(eventDuration.months(), 'months').humanize();
precision--;
}
if (precision && eventDuration.days() > 0) {
durationString += ' ' + moment.duration(eventDuration.days(), 'days').humanize();
precision--;
}
if (precision && eventDuration.hours() > 0) {
durationString += ' ' + moment.duration(eventDuration.hours(), 'hours').humanize();
precision--;
}
if (precision && eventDuration.minutes() > 0) {
durationString += ' ' + moment.duration(eventDuration.minutes(), 'minutes').humanize();
precision--;
}
if (precision && (eventDuration.seconds() > 0 || !durationString)) {
durationString += ' ' + moment.duration(eventDuration.seconds(), 'seconds').humanize();
precision--;
}
return durationString.trim();
return CoreTime.formatTime(seconds, precision);
}
/**
@ -200,21 +172,10 @@ export class CoreTimeUtilsProvider {
*
* @param seconds Seconds
* @return Short human readable text.
* @deprecated since app 4.0. Use CoreTime.formatTimeShort instead.
*/
formatTimeShort(duration: number): string {
const minutes = Math.floor(duration / 60);
const seconds = duration - minutes * 60;
const durations = <string[]>[];
if (minutes > 0) {
durations.push(minutes + '\'');
}
if (seconds > 0 || minutes === 0) {
durations.push(seconds + '\'\'');
}
return durations.join(' ');
return CoreTime.formatTimeShort(duration);
}
/**
@ -223,10 +184,10 @@ export class CoreTimeUtilsProvider {
* @param duration Duration in seconds
* @param precision Number of elements to have in precision. 0 or undefined to full precission.
* @return Duration in a human readable format.
* @deprecated since 4.0. Use formatTime instead.
* @deprecated since app 4.0. Use CoreTime.formatTime instead.
*/
formatDuration(duration: number, precision?: number): string {
return this.formatTime(duration, precision);
return CoreTime.formatTime(duration, precision);
}
/**
@ -234,10 +195,10 @@ export class CoreTimeUtilsProvider {
*
* @param duration Duration in seconds
* @return Duration in a short human readable format.
* @deprecated since 4.0. Use formatTime instead.
* @deprecated since app 4.0. Use CoreTime.formatTimeShort instead.
*/
formatDurationShort(duration: number): string {
return this.formatTimeShort(duration);
return CoreTime.formatTimeShort(duration);
}
/**

View File

@ -12,11 +12,76 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import moment from 'moment';
/**
* Singleton with helper functions for time operations.
*/
export class CoreTime {
/**
* Returns years, months, days, hours, minutes and seconds in a human readable format.
*
* @param seconds A number of seconds
* @param precision Number of elements to have in precision.
* @return Seconds in a human readable format.
*/
static formatTime(seconds: number, precision = 2): string {
precision = precision || 6; // Use max precision if 0 is passed.
const eventDuration = moment.duration(Math.abs(seconds), 'seconds');
let durationString = '';
if (precision && eventDuration.years() > 0) {
durationString += ' ' + moment.duration(eventDuration.years(), 'years').humanize();
precision--;
}
if (precision && eventDuration.months() > 0) {
durationString += ' ' + moment.duration(eventDuration.months(), 'months').humanize();
precision--;
}
if (precision && eventDuration.days() > 0) {
durationString += ' ' + moment.duration(eventDuration.days(), 'days').humanize();
precision--;
}
if (precision && eventDuration.hours() > 0) {
durationString += ' ' + moment.duration(eventDuration.hours(), 'hours').humanize();
precision--;
}
if (precision && eventDuration.minutes() > 0) {
durationString += ' ' + moment.duration(eventDuration.minutes(), 'minutes').humanize();
precision--;
}
if (precision && (eventDuration.seconds() > 0 || !durationString)) {
durationString += ' ' + moment.duration(eventDuration.seconds(), 'seconds').humanize();
precision--;
}
return durationString.trim();
}
/**
* Converts a number of seconds into a short human readable format: minutes and seconds, in fromat: 3' 27''.
*
* @param seconds Seconds
* @return Short human readable text.
*/
static formatTimeShort(duration: number): string {
const minutes = Math.floor(duration / 60);
const seconds = duration - minutes * 60;
const durations = <string[]>[];
if (minutes > 0) {
durations.push(minutes + '\'');
}
if (seconds > 0 || minutes === 0) {
durations.push(seconds + '\'\'');
}
return durations.join(' ');
}
/**
* Wrap a function so that it is called only once.
*