Angular calendar datepicker creates incorrect date one day behind the selection

I was working at the bug fix task, which was from first sight very strange. In an Angular-Spring application, at frontend Angular calendar datepicker I choose a specific date. However, the database suddenly saved one day before the initially picked date.

I started investigating the cause of the issue. First I investigated with breakpoint Spring backend REST endpoint call. The entity with the date was coming already incorrect from Angular frontend to the backend endpoint, so the error was not in the backend code.

At frontend call for backend REST endpoint, I also used JSON.stringify(object) to check if the produced entity which was leaving frontend to backend was correct. What I found was that it was also already false.

Consequently, the issue happened somewhere between the user browser and Angular call for the backend. In this way, I also eliminated the possibility that issue was somewhere in Spring JSON converting library. I use Jackson.

In the end, I figured it out. The issue was in class, which was migrating datepicker form data into the object. While the Angular calendar datepicker collect the date from browser also with local time zone as a string, data to JSON ware pushed as a JavaScript Date class without a time zone. So if you for example pickup up any date, it was selected as the date for midnight with the timezone offset and transferred from string to Date as the day before due the offset counted as date subtraction. In the case of Central Europe where I was working, browser records +1 hour from GMT in datepicker. So if I pick up the date, hours and minutes are selected for midnight (00:00). However, Date class takes the datepicker string and subtract the negative offset from midnight and set a selected date for a day before.

This is the Angular’s datepicker component HTML code from the component form:

           <div class="ui-g-6">
              <div>
                <label for="startDate">Start Date</label>
              </div>
              <vrm-form-field [control]="editForm.controls['startDate']">
                <p-calendar id="startDate"
                            [formControlName]="'startDate'"
                            dateFormat="yy-mm-dd"
                            yearRange="1900:2100">
                </p-calendar>
              </vrm-form-field>
            </div>

Following static function created an object from form datepicker which was pushed to REST endpoint before the fix:

 static mapFromFormData(form: any) {
    return new ImportantDate(form.startDate);
  }

To fix the problem, I created a workaround. I created a Utility class with moment library which takes a datepicker string and select only required date information.

export class Utils {
  public static formatDate(date: any): string {
    if (date === undefined || date === null) {
      return undefined;
    } else {
      return moment(date).format('YYYY-MM-DD');
    }
  }
}

You can see the implementation of the static Util method which fixed the date.

 static mapFromFormData(form: any) {
    return new ImportantDate(
        Utils.formatDate(form.startDate)
    );
  }
This entry was posted in Bug hunt and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.