Reputation: 4728
I am displaying a number of seconds that counts down from 3600 to 0.
<div class="time-box" *ngIf="p.value.playerTimer > 0">{{ p.value.playerTimer }}</div>
I would like to format the number of seconds as minutes:seconds
I hoped to be able to use DatePipe - https://angular.io/api/common/DatePipe
<div class="time-box" *ngIf="p.value.playerTimer > 0">{{ p.value.playerTimer | date:'mmss' }}</div>
But this doesn't work as it expects p.value.playerTimer
to be a date object or number of seconds since the epoch.
Is there another way to achieve this?
Upvotes: 35
Views: 38243
Reputation: 4453
Angular Date Pipe works with number value too, But please note: Only with milliseconds.
If you want to get mm:ss(00:00)
you need to convert your number value to milliseconds. In your case it should be: 3600 * 1000
<div class="time-box" *ngIf="p.value.playerTimer > 0">
{{ p.value.playerTimer * 1000 | date:'mm:ss' }}
</div>
NOTE:
'UTC'
to get results for local time zonesdate: 'HH:mm:ss':'UTC'
to use 24 hour format. if not 30 mins will be displayed as 12:30:00
here is the Stackblitz example https://stackblitz.com/edit/date-pipe-example-nhafvx
maybe someone will come in handy
Upvotes: 50
Reputation: 7334
I found this custom pipe in a GitHub repo which allows formatting seconds or milliseconds to desired format:
USAGE:
{{value_given_milliseconds | durationFormat: 'ms':'hhmmss'}}
{{value_given_seconds | durationFormat: 's':'hhmmss'}}
Output: '00:00:00'
{{value_given_milliseconds | durationFormat: 'ms':'ddhhmmss'}}
{{value_given_seconds | durationFormat: 's':'ddhhmms'}}
Output: '00d, 00h, 00m, 00s'
{{value_given_milliseconds | durationFormat: 'ms':'ddhhmmssLong'}}
{{value_given_seconds | durationFormat: 's':'ddhhmmssLong'}}
Output: '00 days, 00 hours, 00 minutes, 00 seconds'
CODE:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'durationFormat',
pure: false
})
export class DurationFormatPipe implements PipeTransform {
transform(value: any, arg1: any, arg2: any): any {
let days: any;
let seconds: any;
let minutes: any;
let hours: any;
if (arg1 === 'ms' && arg2 === 'hhmmss') {
seconds = Math.floor((value / 1000) % 60);
minutes = Math.floor(((value / (1000 * 60)) % 60));
hours = Math.floor((value / (1000 * 60 * 60)));
return this.format(arg2, seconds, minutes, hours, days);
} else if (arg1 === 's' && arg2 === 'hhmmss') {
seconds = Math.floor((value % 60));
minutes = Math.floor(((value / 60) % 60));
hours = Math.floor(((value / 60) / 60));
return this.format(arg2, seconds, minutes, hours, days);
} else if (arg1 === 'ms' && (arg2 === 'ddhhmmss' || arg2 === 'ddhhmmssLong') ) {
seconds = Math.floor(((value / 1000) % 60));
minutes = Math.floor((value / (1000 * 60) % 60));
hours = Math.floor((value / (1000 * 60 * 60) % 24));
days = Math.floor((value / (1000 * 60 * 60 * 24)));
return this.format(arg2, seconds, minutes, hours, days);
} else if (arg1 === 's' && (arg2 === 'ddhhmmss' || arg2 === 'ddhhmmssLong') ) {
seconds = Math.floor(value % 60);
minutes = Math.floor(((value / 60) % 60));
hours = Math.floor(((value / 60) / 60) % 24);
days = Math.floor((((value / 60) / 60) / 24));
return this.format(arg2, seconds, minutes, hours, days);
}
else {
return value;
}
}
private format(arg2, seconds, minutes, hours, days) {
(days < 10) ? days = '0' + days : days;
(hours < 10) ? hours = '0' + hours : hours;
(minutes < 10) ? minutes = '0' + minutes : minutes;
(seconds < 10) ? seconds = '0' + seconds : seconds;
switch(arg2) {
case 'hhmmss':
return `${hours}:${minutes}:${seconds}`;
case 'ddhhmmss':
return `${days}d, ${hours}h, ${minutes}m, ${seconds}s`;
case 'ddhhmmssLong':
return `${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`;
}
}
}
Upvotes: 0
Reputation: 75
For anyone looking for an answer that goes a step further and supports hours:
const toHoursMinutesSeconds = totalSeconds => {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
let result = `${minutes
.toString()
.padStart(1, '0')}:${seconds.toString().padStart(2, '0')}`;
if (!!hours) {
result = `${hours.toString()}:${minutes
.toString()
.padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
return result;
};
Produces:
toHoursMinutesSeconds(55);
'0:55'
toHoursMinutesSeconds(679);
'11:19'
toHoursMinutesSeconds(12345);
'3:25:45'
toHoursMinutesSeconds(123456);
'34:17:36'
Upvotes: 6
Reputation: 2634
To put all the answers together plus a sample usage in HTML:
From markau and PierreDuc:
@Pipe({
name: 'minuteSeconds'
})
export class MinuteSecondsPipe implements PipeTransform {
transform(value: number): string {
const minutes: number = Math.floor(value / 60);
return minutes.toString().padStart(2, '0') + ':' +
(value - minutes * 60).toString().padStart(2, '0');
}
}
Then in your html:
<div ...>{{ p.value.playerTimer | minuteSeconds }}</div>
So for example, if p.value.playerTimer = 127, it will show 02:07
Upvotes: 21
Reputation: 1018
Using francisco-danconia's answer, I was getting the mm:ss as ==> 04:58.69999999999999. So I modified the code slightly as follows. I am now getting 04:58 as expected.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'minuteSeconds'
})
export class MinuteSecondsPipe implements PipeTransform {
transform(value: number): string {
const minutes: number = Math.floor(value / 60);
return minutes.toString().padStart(2, '0') + ':' +
Math.floor((value - minutes * 60)).toString().padStart(2, '0');
}
}
Upvotes: 1
Reputation: 123
case 1 int = 100 output 01:40
case 2 int = 50 output 00:50
case 3 int = 125 output = 02:05
transform(value: number, args?: any): string {
const hours: number = Math.floor(value / 60);
const minutes: number = (value - hours * 60);
if (hours < 10 && minutes < 10) {
return '0' + hours + ' : 0' + (value - hours * 60);
}
if (hours > 10 && minutes > 10) {
return '0' + hours + ' : ' + (value - hours * 60);
}
if (hours > 10 && minutes < 10) {
return hours + ' : 0' + (value - hours * 60);
}
if (minutes > 10) {
return '0' + hours + ' : ' + (value - hours * 60);
}
}
Upvotes: 1
Reputation: 932
Following from PierreDuc's answer, if you want to pad the minutes/seconds with a leading zero (e.g. 00:01), you can use the ES2017 padStart
method:
return minutes.toString().padStart(2, '0') + ':' + (value - minutes * 60).toString().padStart(2, '0');
Upvotes: 3
Reputation: 71951
You have to write your own pipe. Something like this. Be aware though, it's untested and does not take into account any strange input it might receive. Also it does not have any leading zeros, but hey, now you got something to do as well:
@Pipe({
name: 'minuteSeconds'
})
export class MinuteSecondsPipe implements PipeTransform {
transform(value: number): string {
const minutes: number = Math.floor(value / 60);
return minutes + ':' + (value - minutes * 60);
}
}
Upvotes: 36