I have an array of times (futuretimes) so I need to show a countdown timer in MM:SS format in decrement order by comparing with the current time(HH:MM). so when the timer finishes then it will jump to find the next highest timer from new current HH:MM
How to do this ?
const futuretimes = ["5:00 AM" , "5:30 AM" , "5:45 AM" , "6:00 AM" , "6:15 AM" , "6:30 AM" , "6:40 AM" , "6:50 AM" , "7:00 AM" , "7:08 AM" , "7:16 AM" , "7:24 AM" , "7:35 AM" , "7:40 AM" , "7:45 AM" , "7:50 AM" , "7:55 AM" , "8:00 AM" , "8:05 AM" , "8:10 AM" , "8:15 AM" , "8:20 AM" , "8:25 AM" , "8:30 AM" , "8:34 AM" , "8:38 AM" , "8:42 AM" , "8:46 AM" , "8:50 AM" , "8:54 AM" , "8:58 AM" , "9:02 AM" , "9:06 AM" , "9:10 AM" , "9:15 AM" , "9:20 AM" , "9:25 AM" , "9:30 AM" , "9:35 AM" , "9:40 AM" , "9:45 AM" , "9:50 AM" , "9:55 AM" , "10:00 AM" , "10:06 AM" , "10:12 AM" , "10:18 AM" , "10:26 AM" , "10:34 AM" , "10:40 AM" , "10:50 AM" , "11:00 AM" , "11:10 AM" , "11:20 AM" , "11:30 AM" , "11:40 AM" , "11:50 AM" , "12:00 PM" , "12:10 PM" , "12:20 PM" , "12:30 PM" , "12:40 PM" , "12:50 PM" , "1:00 PM" , "1:10 PM" , "1:20 PM" , "1:30 PM" , "1:40 PM" , "1:50 PM" , "2:00 PM" , "2:10 PM" , "2:20 PM" , "2:30 PM" , "2:40 PM" , "2:50 PM" , "3:00 PM" , "3:10 PM" , "3:20 PM" , "3:30 PM" , "3:40 PM" , "3:50 PM" , "4:00 PM" , "4:08 PM" , "4:16 PM" , "4:24 PM" , "4:32 PM" , "4:40 PM" , "4:45 PM" , "4:50 PM" , "4:55 PM" , "5:00 PM" , "5:05 PM" , "5:10 PM" , "5:14 PM" , "5:18 PM" , "5:22 PM" , "5:26 PM" , "5:30 PM" , "5:34 PM" , "5:38 PM" , "5:42 PM" , "5:46 PM" , "5:50 PM" , "5:55 PM" , "6:00 PM" , "6:05 PM" , "6:10 PM" , "6:15 PM" , "6:20 PM" , "6:25 PM" , "6:30 PM" , "6:35 PM" , "6:40 PM" , "6:45 PM" , "6:50 PM" , "6:55 PM" , "7:00 PM" , "7:05 PM" , "7:10 PM" , "7:15 PM" , "7:20 PM" , "7:25 PM" , "7:30 PM" , "7:35 PM" , "7:40 PM" , "7:45 PM" , "7:50 PM" , "7:55 PM" , "8:00 PM" , "8:06 PM" , "8:12 PM" , "8:18 PM" , "8:24 PM" , "8:30 PM" , "8:36 PM" , "8:42 PM" , "8:48 PM" , "8:54 PM" , "9:00 PM" , "9:08 PM" , "9:16 PM" , "9:24 PM" , "9:32 PM" , "9:40 PM" , "9:50 PM" , "10:00 PM" , "10:15 PM" , "10:30 PM" , "10:45 PM" , "11:00 PM"];
Expected output: E.g: Suppose if the current time HH:MM is 5:31AM then the countdown timer should pick a next highest HH:MM time comparing with the current time HH:MM from above-defined array(i.e futuretimes) which is just highest time, so in this example it should pick 5:45 AM from array because it is next highest value from current time(5:31AM) and then countdown timer should be shown and once the current countdown timer finishes then it will take next highest from array as compared to the new current time etc.
I tried to get the current time in seconds and but stuck how to make for loop between these arrayoftime and pick the highest one to start timercountdown:
const currentMinute = new Date().getMinutes();
const currenthour = new Date().getHours();
const totalseconds=3600*currenthour +60*currentMinute;//current time in seconds
// now stuck how to do further
Here's one implementation in angular using observables.
Stackblitz: https://stackblitz.com/edit/angular-sbosff
<small>Now</small>
<p>{{ now$ | async | date:'h:mm:ss a' }}</p>
<hr>
<small>Next Time</small>
<ng-container>
<p>{{ (nextTime$ | async)?.time }}</p>
</ng-container>
<hr>
<ng-container>
<small>Countdown to Next</small>
<p>{{ timeToNext$ | async }}</p>
</ng-container>
<hr>
<small>All Times</small>
<ng-container *ngFor="let timeOption of futuretimes">
<p>{{ timeOption }}</p>
</ng-container>
import { Component } from '@angular/core';
import { Observable, interval, combineLatest } from 'rxjs';
import { startWith, map } from 'rxjs/operators';
interface StringTimeWithDate {
time: string;
asDate: Date;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
now$: Observable<Date>;
nextTime$: Observable<StringTimeWithDate>;
timeToNext$: Observable<string>;
futuretimes = [
'5:00 AM',
'5:30 AM',
'5:45 AM',
'6:00 AM',
'6:15 AM',
'6:30 AM',
'6:40 AM',
'6:50 AM',
'7:00 AM',
'7:08 AM',
'7:16 AM',
'7:24 AM',
'7:35 AM',
'7:40 AM',
'7:45 AM',
'7:50 AM',
'7:55 AM',
'8:00 AM',
'8:05 AM',
'8:10 AM',
'8:15 AM',
'8:20 AM',
'8:25 AM',
'8:30 AM',
'8:34 AM',
'8:38 AM',
'8:42 AM',
'8:46 AM',
'8:50 AM',
'8:54 AM',
'8:58 AM',
'9:02 AM',
'9:06 AM',
'9:10 AM',
'9:15 AM',
'9:20 AM',
'9:25 AM',
'9:30 AM',
'9:35 AM',
'9:40 AM',
'9:45 AM',
'9:50 AM',
'9:55 AM',
'10:00 AM',
'10:06 AM',
'10:12 AM',
'10:18 AM',
'10:26 AM',
'10:34 AM',
'10:40 AM',
'10:50 AM',
'11:00 AM',
'11:10 AM',
'11:20 AM',
'11:30 AM',
'11:40 AM',
'11:50 AM',
'12:00 PM',
'12:10 PM',
'12:20 PM',
'12:30 PM',
'12:40 PM',
'12:50 PM',
'1:00 PM',
'1:10 PM',
'1:20 PM',
'1:30 PM',
'1:40 PM',
'1:50 PM',
'2:00 PM',
'2:10 PM',
'2:20 PM',
'2:30 PM',
'2:40 PM',
'2:50 PM',
'3:00 PM',
'3:10 PM',
'3:20 PM',
'3:30 PM',
'3:40 PM',
'3:50 PM',
'4:00 PM',
'4:08 PM',
'4:16 PM',
'4:21 PM',
'4:32 PM',
'4:40 PM',
'4:45 PM',
'4:50 PM',
'4:55 PM',
'5:00 PM',
'5:05 PM',
'5:10 PM',
'5:14 PM',
'5:18 PM',
'5:22 PM',
'5:26 PM',
'5:30 PM',
'5:34 PM',
'5:38 PM',
'5:42 PM',
'5:46 PM',
'5:50 PM',
'5:55 PM',
'6:00 PM',
'6:05 PM',
'6:10 PM',
'6:15 PM',
'6:20 PM',
'6:25 PM',
'6:30 PM',
'6:35 PM',
'6:40 PM',
'6:45 PM',
'6:50 PM',
'6:55 PM',
'7:00 PM',
'7:05 PM',
'7:10 PM',
'7:15 PM',
'7:20 PM',
'7:25 PM',
'7:30 PM',
'7:35 PM',
'7:40 PM',
'7:45 PM',
'7:50 PM',
'7:55 PM',
'8:00 PM',
'8:06 PM',
'8:12 PM',
'8:18 PM',
'8:24 PM',
'8:30 PM',
'8:36 PM',
'8:42 PM',
'8:48 PM',
'8:54 PM',
'9:00 PM',
'9:08 PM',
'9:16 PM',
'9:24 PM',
'9:32 PM',
'9:40 PM',
'9:50 PM',
'10:00 PM',
'10:15 PM',
'10:30 PM',
'10:45 PM',
'11:00 PM'
];
futureTimesAsDate: StringTimeWithDate[];
constructor() {
// map time to date and ensure sort ascending
this.futureTimesAsDate = this.futuretimes
.map(time => ({ time, asDate: this.timeStringToDate(time) }))
.sort((a, b) => (a.asDate > b.asDate ? 1 : -1));
this.now$ = interval(1000).pipe(
startWith(null),
map(() => new Date())
);
this.nextTime$ = this.now$.pipe(
map((now: Date) => this.futureTimesAsDate.find(timeDate => timeDate.asDate > now))
);
this.timeToNext$ = combineLatest(this.now$, this.nextTime$, (now, nextTime) => {
if (!now || !nextTime) {
return null;
}
const diff = nextTime.asDate.valueOf() - now.valueOf();
const millisPerSec = 1000;
const millisPerMin = millisPerSec * 60;
const min = Math.floor(diff / millisPerMin);
const msLeftover = Math.floor(diff % millisPerMin);
const secLeftover = Math.ceil(msLeftover / millisPerSec);
const formattedMin = min < 10 ? `0${min}` : min;
const formattedSec = secLeftover < 10 ? `0${secLeftover}` : secLeftover;
const minMsToNext = `${formattedMin}:${formattedSec}`;
return minMsToNext;
});
}
ngOnInit() {}
private timeStringToDate = dateString => {
const [time, period] = dateString.split(' ');
const [hour, minutes] = time.split(':').map(numString => Number(numString));
const hourOutOf24 = period.toLowerCase() === 'pm' && hour !== 12 ? hour + 12 : hour;
const dateForDateString = new Date();
dateForDateString.setHours(hourOutOf24, minutes, 0, 0);
return dateForDateString;
}
}