Fixing date-time insertion issues using JSOM

Introduction

 
In today’s world, most SharePoint/O365 projects are developed using JSOM/SPFx or any client object model. As such, while developing these projects we are frequently faced with issues while inserting a date-time object from JSOM/SPfx.
 
Problem: In general by default, every date-time object from Javascript will have a client offset time, a server offset time and daylight savings time.
 
Example: If I try to insert “2019-08-23T20:23:00Z” into one of the SharePoint lists, it inserts “2019-08-24T01:53:00Z” instead.
 
Solution 1:
 
This is a temporary solution. We must have the regional time zone of the site. Based on that, we can convert the new date-time to the regional time zone.
 
For example:
 
New Date().toLocaleString("en-US", {timeZone: "America/Los_Angeles"});
 
Or
 
We need to pass the time zone information as shown below:
 
var jun = moment("2014-06-01T12:00:00Z");
jun.tz('America/Los_Angeles')
 
However, we need to know all time zones based on the current browser. It should be browser dependent. Unfortunately while doing so, we have the below issues:
 
1) If the admin unexpectedly changes the regional settings, the hardcoded zone will not give the proper date-time, because the time zone offset time will vary based on the zones.
 
2) This will give the wrong data when we have daylight savings time.
 
Solution 2
 
Based on the above problems, we should have the regional time zone offset time dynamically. It should include both offset time and daylight savings hours if any.
 
We have one REST API endpoint for retrieving this information.
 
 
If we are using the SPFx with SP-Pnp-Js
 
pnp.sp.web.regionalSettings.get().then(() => {
});
 
This results in JSON format for the above endpoints:
 
image1 
 
From the above result, we have the information for Bias and Daylight savings in minutes.
 
Before inserting or displaying the data to/from the SharePoint list, we need to convert date-time data based on the above result.
 
Below I have written reusable methods to display and insert date-time in typescript. For direct reusable control, please download from the attachments.
  1. public formatDisplayDate() {  
  2.         let data = this.state.data;  
  3.         if (this.props.dateTime != undefined && this.props.dateTime != "") {  
  4.             if (!data["selectedDate"]) {  
  5.                 data["selectedDate"] = this.dateConversionForDisplay(this.props.dateTime);  
  6.             }  
  7.         }  
  8.         else  
  9.             data["selectedDate"] = "";  
  10.         this.setState({ data: data });  
  11.     }  
  12.       public dateConversionForSave(enteringDate): any {  
  13.         try {  
  14.             let regionalSettings: any;  
  15.             let value = this.props.regionalSettings;  
  16.             let userOffset: number = enteringDate.getTimezoneOffset();  
  17.             let bias = value.Information.Bias;  
  18.             let daylightBias = value.Information.DaylightBias;  
  19.             let zone = value.Description;  
  20.             regionalSettings = {  
  21.                 "offset": (bias + daylightBias) / 60.0,  
  22.                 "utcStd ": zone.split(" ")[0]  
  23.             };  
  24.             let date1 = new Date(enteringDate);  
  25.             var nd = new Date(date1.getTime() - (userOffset * 60000) + (3600000 * (regionalSettings.offset)));  
  26.             return nd;  
  27.         }  
  28.         catch (error) {  
  29.             this.logToConsole("dateConversionForSave " + error);  
  30.         }  
  31.   
  32.     }  
  33.     public dateConversionForDisplay(displayDateinString): any {  
  34.         try {  
  35.             let enteringDate = new Date(Date.parse(displayDateinString));  
  36.             let regionalSettings: any;  
  37.             let value = this.props.regionalSettings;  
  38.             let userOffset: number = enteringDate.getTimezoneOffset();  
  39.             let bias = value.Information.Bias;  
  40.             let daylightBias = value.Information.DaylightBias;  
  41.             let zone = value.Description;  
  42.             regionalSettings = {  
  43.                 "offset": (bias + daylightBias) / 60.0,  
  44.                 "utcStd ": zone.split(" ")[0]  
  45.             };  
  46.             var d = new Date(enteringDate.getTime() + (userOffset * 60000) - (3600000 * (regionalSettings.offset)));  
  47.             //new Date(displayDateinString.replace(/-/g,''));  
  48.             //let d: Date = new Date(displayDateinString.split('T').replace(/-/g, ' '));  
  49.             let nd = moment(d).format('DD-MMM-YYYY');  
  50.             return nd;  
  51.         }  
  52.         catch (error) {  
  53.             this.logToConsole("dateConversionForDisplay " + error);  
  54.         }  
  55.   
  56.     }