Search code examples
angularcountdowntimerangular-moment

Exact same count down timer hh:mm:ss for everyone


I'm using angular for auction site, calculating remaining time from auction end time using moment and showing counter, but it fails when user change his clock time.

Getting accurate time from server and calculate remaining time is good but after page loading, disturbing clock create issue, is there a way to get system clock changing event or check if user set auto sync/ internet time?

While getting remaining time from server also include network response delay and some other issues Need to know best way to show exact same timer for everyone.


Solution

  • you can try subscribe to document focus, and then get the dateTime form a server. After find the different between the date of client and the value.Some like

      inc: number = 0;
      timeInitial = 0;
      time;
      toogle: boolean = false;
      constructor(private timerService: TimerService) {}
      click() {
        this.toogle = !this.toogle;
        if (this.toogle) {
          fromEvent(document, "focus")
            .pipe(
              takeWhile(() => this.toogle),
              startWith(null),
              switchMap(() => {
                return this.timerService.getTime();
              })
            )
            .subscribe(res => {
              this.inc = new Date().getTime() - res.time;
              if (!this.timeInitial) this.timeInitial = res.timeInitial;
              console.log(this.inc, this.timeInitial);
            });
    
          timer(0, 1000)
            .pipe(
              takeWhile(() => this.toogle),
              map(() => {
                return (
                  this.timeInitial -
                  new Date(new Date().getTime() - this.inc).getTime()
                );
              })
            )
            .subscribe(res => {
              this.time = res;
            });
        } else {
          this.timeInitial = 0;
        }
      }
    

    Your .html as

    <button (click)="click()">{{toogle?'stop':'start'}}</button>
    {{time |date:'H:mm:ss':'UTC'}}
    

    And our service that make a call to a server that give us the date time, e.g.

    export class TimerService {
      constructor(private httpClient: HttpClient) {}
      getTime() {
        return this.httpClient
          .get("https://worldtimeapi.org/api/timezone/America/Argentina/Salta")
          .pipe(
            map((res: any) => {
              const time = new Date(res.datetime).getTime();
              return {
                time: time,
                timeInitial: time + 30 * 60 * 1000
              };
            })
          );
      }
    }
    

    Well, if you change the time in your computer you see as the countdown change, but when you focus the app, the countdown re-calculate give you the correct time

    You can see in stackblitz