5

I am working on a date problem.

So, in the app I have a table that have some user records that includes a date of birth field (datetime sql type). The problem is that for some users whose date of birth is prior to 1954, the date is not properly reflected.

For example, I have a user whose date of birth is 11/08/1920 but when I set the date of birth via server script, it ends up with the value 11/07/1920 23:23:24.

I am getting the date value from a spreadsheet and the server script looks like this:

function importDOBs(){

  var allRecs = [];

  var ss = SpreadsheetApp.openById("adfsasdfasdfasdfasdfasdf");
  var sheet = ss.getActiveSheet();

  var data = sheet.getRange(2,4,sheet.getLastRow(),2).getValues();
  for(var i=0; i<5; i++){
    var row = data[i];
    var date = row[0];
    var oldMrn = row[1];

    var query = app.models.purgedRecords.newQuery();
    query.filters.oldMrn._equals = oldMrn;
    var record = query.run()[0];
    if(record){
      var dob = new Date(date);
      record.dateOfBirth = dob;
      allRecs.push(record);
    }
  }

  app.saveRecords(allRecs);

}

These are the values in the spreadsheet (they are strings, not dates):

1954-03-04T00:00:00
2014-03-01T00:00:00
1951-10-20T00:00:00
1920-11-08T00:00:00
1938-09-27T00:00:00

However, somehow I'm always getting this:

enter image description here

As you see, there is a discrepancy on the dates that are prior to 1954. So far, I have tried other things such as changing this part:

if(record){
  var dob = new Date(date);
  record.dateOfBirth = dob;
  allRecs.push(record);
}

to this:

if(record){
  var dob = Utilities.formatDate(new Date(date),"GMT","yyyy-MM-dd'T'HH:mm:ss'Z'");
  var birthDate = new Date(dob);
  record.dateOfBirth = birthDate;
  allRecs.push(record);
}

and the above resulted in the same thing. I have tried other dates after 1954 and they also seem wrong. For example 05/19/1968 reflects 05/18/1968 23:00:00. So my best guess so far this has to do something with the daylight savings, perhaps?

halfer
  • 19,824
  • 17
  • 99
  • 186
Morfinismo
  • 4,985
  • 4
  • 19
  • 36
  • Did you try to set your mysql server on UTC time ? Because, UTC time doesn't imply daylight saving times, it could fix your issue. – Philoupe Feb 27 '19 at 17:28
  • @Philoupe thanks for your suggestion, however I don't think I can do that with google cloud sql https://cloud.google.com/sql/docs/mysql/flags#list-flags – Morfinismo Feb 27 '19 at 17:41
  • If it is a string, don't parse the date, just use regexp to put the date into the correct format for SQL datetime. – Mouser Feb 28 '19 at 09:03

1 Answers1

1

The snake pit of converting dates between platforms

Try to set the values to UTC or just format them into the datetime format for MySQL

The first option as seen in the snippet below requires you to convert the format in SQL:

See this answer: MySQL yyyy-mm-ddThh:mm:ss.sssZ to yyyy-mm-dd hh:mm:ss

DATE_FORMAT(STR_TO_DATE(«string»,'%Y-%m-%dT%H:%i:%s.000Z'),'%Y-%m-%d %H:%i:%s');

//Using Z to set to UTC

let allRecs = [];
document.querySelector("pre").textContent.split("\n").forEach(function(element) {
  if (element != "") {
    const dob = new Date(element + "Z"); //Z forces te date to be in UTC with zero time offzet or: 00:00:00
    const dateOfBirth = dob;
    allRecs.push(dateOfBirth);
  }
});
console.log(allRecs);

allRecs = [];
//format to MySQL datetime format
document.querySelector("pre").textContent.split("\n").forEach(function(element) {
  if (element != "") {
    element = element.replace("T", " "); //replace T with space
    //now the string is in the datetime format for MySQL
    allRecs.push(element);
  }
});
console.log(allRecs);
<pre>
1954-03-04T00:00:00
2014-03-01T00:00:00
1951-10-20T00:00:00
1920-11-08T00:00:00
1938-09-27T00:00:00
</pre>
Mouser
  • 13,132
  • 3
  • 28
  • 54
  • 1
    Great answer! I'm pretty sure it would work outside of AppMaker's environment. However, I think the answer to my question is on this documentation https://developers.google.com/appmaker/models/cloudsql#time_zones. Nevertheless, I greatly appreciate your help efforts! – Morfinismo Feb 28 '19 at 10:18
  • Thanks, the second method should work though, since you're allowed to use JavaScript in the appmaker and writing them as the default MySQL datetime format. But indeed you're correctly referencing the docs. – Mouser Feb 28 '19 at 11:16
  • You think the second method would work but it does not. Actually you can set a string because you'd get the error "Date is expected and provided a String type". I think it might be a bug. – Morfinismo Mar 01 '19 at 13:27
  • @Morfinismo Did you manage to solve the issue with the suggestion in the documentation? – TasosZG Mar 04 '19 at 13:21
  • @TasosZG I was not able to solve it. The documentation suggestion isn't helpful. I strongly believe this is a bug. I'm just using String instead of date now. – Morfinismo Mar 05 '19 at 02:11