30

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?

Ashot Aleqsanyan
  • 4,252
  • 1
  • 15
  • 27
Chris
  • 4,672
  • 13
  • 52
  • 93
  • 1
    that is right... it will expect the date's int value or a valid date. you have to write your own directive for this feature – Gary Sep 05 '17 at 12:47

7 Answers7

44

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>

here is the Stackblitz example https://stackblitz.com/edit/date-pipe-example-nhafvx

maybe someone will come in handy

Ashot Aleqsanyan
  • 4,252
  • 1
  • 15
  • 27
  • 8
    This should be the chosen answer, this is exactly why the date pipe did not work for the asker. – Antonio Ortells Jun 03 '20 at 12:57
  • This doesn't take into account local time zones. For example during BST a duration of 0 milliseconds will be displayed as 1 hour. It will appear to work fine during the winter though . – Simon Apr 21 '21 at 10:38
  • 1
    hmm, can you try to add `date:'mm:ss':'UTC'`? – Ashot Aleqsanyan Apr 21 '21 at 11:47
  • I can confirm that adding the `'UTC'` part does the trick to avoid the extra added hours in some timezones. Only downside to using date pipe is that any overflow is ignored, so if the OP's input is more than 59:59, it will just show 00:00. – mneumann Jan 19 '22 at 05:42
  • 1
    Hi @mneumann I just tested, it works with `UTC`, I have tried for `3655` and it shows `01:00:55` – Ashot Aleqsanyan Jan 19 '22 at 08:40
34

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);
    }

}
Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
19

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

Francisco d'Anconia
  • 2,436
  • 1
  • 19
  • 25
6

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'
Daniel Goudie
  • 75
  • 2
  • 6
3

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');

markau
  • 854
  • 8
  • 21
1

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);
    }
}
URL87
  • 10,667
  • 35
  • 107
  • 174
Ahmed Youssef
  • 113
  • 1
  • 8
1

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');
      }
  }
Nikhil
  • 861
  • 11
  • 15