TypeScript Difference Between two dates in Days

20,272

Using moment's diff function you can get the proper 1 day diff between these two dates.

this.firstDate = moment('2019/03/31');
this.secondDate = moment('2019/04/01');
this.diffInDays = Math.abs(this.firstDate.diff(this.secondDate, 'days')); 

See this stackblitz for demo.

Update:

I forked your stackblitz. Generally created two new functions and cleaned up some duplication.

NgbDate has three properties year, month and day. The important thing is that month is starting from 1 (not from zero for JS native Date object) See NgbDate docs here.

  private createDateFromNgbDate(ngbDate: NgbDate): Date {
    const date: Date = new Date(Date.UTC(ngbDate.year, ngbDate.month-1, ngbDate.day));  
    return date;
  }

And a separate function to calculate the diff in days like this:

private calcDaysDiff(): number {
    const fromDate: Date = this.createDateFromNgbDate(this.fromDate);
    const toDate: Date = this.createDateFromNgbDate(this.toDate);  
    const daysDiff = Math.floor(Math.abs(<any>fromDate - <any>toDate) / (1000*60*60*24));
    return daysDiff;
  }

Check the updated stackblitz and let me know if you still have issues.

Share:
20,272

Related videos on Youtube

AbdalRahman Farag
Author by

AbdalRahman Farag

Updated on May 07, 2020

Comments

  • AbdalRahman Farag
    AbdalRahman Farag almost 4 years

    I am trying to calculate difference between two dates in days. However, when the two dates are in different months the days in the previous month are discarded.

    For instance, if start date is March 31, and end date is April 1st, the difference is 0.

    HTML:

    <ngb-datepicker #dp (select)="onDateSelection($event)" [displayMonths]="2" [dayTemplate]="t" outsideDays="hidden">
        </ngb-datepicker>
    
        <ng-template #t let-date let-focused="focused">
          <span class="custom-day"
                [class.focused]="focused"
                [class.range]="isRange(date)"
                [class.faded]="isHovered(date) || isInside(date)"
                (mouseenter)="hoveredDate = date"
                (mouseleave)="hoveredDate = null">
            {{ date.day }}
          </span>
        </ng-template>
    
        <p>Number of selected dates: {{DiffDate}}</p>
    
    
        <pre>From: {{ fromDate | json }} </pre>
        <pre>To: {{ toDate | json }} </pre> 
    

    Typsript File:

        import {Component} from '@angular/core';
        import {NgbDate, NgbCalendar} from '@ng-bootstrap/ng-bootstrap';
    
        @Component({
          selector: 'ngbd-datepicker-range',
          templateUrl: './datepicker-range.html',
          styles: [`
            .custom-day {
              text-align: center;
              padding: 0.185rem 0.25rem;
              display: inline-block;
              height: 2rem;
              width: 2rem;
            }
            .custom-day.focused {
              background-color: #e6e6e6;
            }
            .custom-day.range, .custom-day:hover {
              background-color: rgb(2, 117, 216);
              color: white;
            }
            .custom-day.faded {
              background-color: rgba(2, 117, 216, 0.5);
            }
          `]
        })
        export class NgbdDatepickerRange {
    
          hoveredDate: NgbDate;
    
          fromDate: NgbDate;
          toDate: NgbDate;
          DiffDate;
          enddate;
          startDate;
    
          constructor(calendar: NgbCalendar) {
            this.fromDate = calendar.getToday();
            this.toDate = calendar.getNext(calendar.getToday(), 'd', 10);
          }
    
          onDateSelection(date: NgbDate) {
            if (!this.fromDate && !this.toDate) {
              this.fromDate = date;
            } else if (this.fromDate && !this.toDate && date.after(this.fromDate)) {
              this.toDate = date;
            } else {
              this.toDate = null;
              this.fromDate = date;
            }
            this.enddate=new Date (this.toDate.year,this.toDate.month,this.toDate.day);
    
            this.startDate=new Date (this.fromDate.year,this.fromDate.month,this.fromDate.day);
    
            this.DiffDate=Math.floor((Date.UTC(this.enddate.getFullYear(),this.enddate.getMonth(),this.enddate.getDate())-Date.UTC(this.startDate.getFullYear(),this.startDate.getMonth(),this.startDate.getDate()) )/(1000 * 60 * 60 * 24));
            //this.DiffDate=(this.DiffDate/86400000);
    
          }
    
          isHovered(date: NgbDate) {
            return this.fromDate && !this.toDate && this.hoveredDate && date.after(this.fromDate) && date.before(this.hoveredDate);
          }
    
          isInside(date: NgbDate) {
            return date.after(this.fromDate) && date.before(this.toDate);
          }
    
          isRange(date: NgbDate) {
            return date.equals(this.fromDate) || date.equals(this.toDate) || this.isInside(date) || this.isHovered(date);
          }
        }
    

    If two days are in the same month, it is working fine.

    Appreciate your support in advance.

    update: I figured how to fix it. Everything is working as expected, except when the day selected is the last day of the month. A live demo can be found below:

    The DEMO Here

    For instance, start date: March 19, end date: Marc 21st. Difference is 2 days.

    But when start day selected is March 31st, it is calculated as May 1st:

    Any idea what is going wrong? Thanks in advance.

    • fastAsTortoise
      fastAsTortoise about 5 years
      I think just convert the dates to milliseconds then subtract and then convert to days. Might work.
    • MRsa
      MRsa about 5 years
      (dateTo.valueOf() - dateFrom.valueOf()) / 86400000
    • AbdalRahman Farag
      AbdalRahman Farag about 5 years
      Thanks, I tried this, but not working as well
    • robert
      robert about 5 years
    • AbdalRahman Farag
      AbdalRahman Farag about 5 years
      Thanks...I tried below, but still not working: this.DiffDate=Math.floor((Date.UTC(this.enddate.getFullYear(‌​),this.enddate.getMo‌​nth(),this.enddate.g‌​etDate())-Date.UTC(t‌​his.startDate.getFul‌​lYear(),this.startDa‌​te.getMonth(),this.s‌​tartDate.getDate()) )/(1000 * 60 * 60 * 24)); Any suggestion
    • AbdalRahman Farag
      AbdalRahman Farag about 5 years
      Below lines are only working if we are on the same month...if different months, the difference in days is 0: this.enddate=new Date (this.toDate.year,this.toDate.month,this.toDate.day); this.startDate=new Date (this.fromDate.year,this.fromDate.month,this.fromDate.day); this.DiffDate=Math.floor((Date.UTC(this.enddate.getFullYear(‌​),this.enddate.getMo‌​nth(),this.enddate.g‌​etDate())-Date.UTC(t‌​his.startDate.getFul‌​lYear(),this.startDa‌​te.getMonth(),this.s‌​tartDate.getDate()) )/(1000 * 60 * 60 * 24));
    • Eliseo
      Eliseo about 5 years
      in new Date, month beging by 0, 0=january, 1=february..., in ngb-bootstrap, fromDate.month begin by 1, 1=january,2=february..
  • AbdalRahman Farag
    AbdalRahman Farag about 5 years
    many thanks for your support. I updated, my code, and it is actually working. However, the issue I have when I selected dates from different months. For instance, when I select two dates from the same month, the difference is calculated correctly. However, when I select two different dates, the data is corrupted. A live demo can be found at: stackblitz.com/github/abdelrahman84/…
  • AbdalRahman Farag
    AbdalRahman Farag about 5 years
    I can't thank you enough. This fixed my issue, and everything is working as expected. Have a wonderful day