Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

toISOString() changes datetime value

I have array of the objects.Each object in array has date property.I try to get biggest(the last) date from array.

Here is array:

var sensorsData = [{
  Id: 1,
  MeasureDate: "2017-08-20T09:52:32"
}, {
  Id: 2,
  MeasureDate: "2017-08-20T09:54:35"
}, {
  Id: 3,
  MeasureDate: "2017-08-20T09:56:13"
}];

And here is function the fetch the biggest date from array above:

function updateLatestDate(sensorsData) {
  return new Date(Math.max.apply(null, sensorsData.map(function(e) {
    return new Date(e.MeasureDate);
  }))).toISOString();
}

the result that I get from updateLatestDate function is:

2017-08-20T06:56:13.000Z

but it strange because, as you can see no one of the properties in sensorsData objects doesn't have the date as returned from updateLatestDate function.

Here is FIDDLER.

Any idea why updateLatestDate function returns wrong result?

like image 518
Michael Avatar asked Aug 20 '17 08:08

Michael


People also ask

How do you use toISOString on a date?

toISOString() method is used to convert the given date object's contents into a string in ISO format (ISO 8601) i.e, in the form of (YYYY-MM-DDTHH:mm:ss. sssZ or ±YYYYYY-MM-DDTHH:mm:ss. sssZ). The date object is created using date() constructor.

What is toISOString in Javascript?

The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long ( YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ , respectively). The timezone is always zero UTC offset, as denoted by the suffix Z .

What is Z in Javascript date?

The T is just a literal to separate the date from the time, and the Z means “zero hour offset” also known as “Zulu time” (UTC). If your strings always have a “Z” you can use: SimpleDateFormat format = new SimpleDateFormat( “yyyy-MM-dd'T'HH:mm:ss).


2 Answers

When you create a date with new Date(str) it creates a date object with a time zone. toISOString() makes it zero UTC offset, as denoted by the suffix "Z".

Here is a workaround:

var date = new Date(e.MeasureDate)
return new Date(date.getTime() - date.getTimezoneOffset() * 60000)

Updated fiddler: https://jsfiddle.net/xf5jmLL6/7

getTimezoneOffset returns number of minutes and new Date expects number of milliseconds since January 1 1970 00:00:00 UTC, so multiplying by 60000 provides needed adjustment.

like image 57
Danil Speransky Avatar answered Oct 20 '22 02:10

Danil Speransky


The problem lay in that this process (that makes date conversion to integers than back to dates) is not reversible the proof is in the following function that performs conversion from dates to int and then back to dates, only to get different values from the starting ones

<button onclick="setDate()">irreversible conversion</button>
<script>
   
function setDate(){
var sensorsData = [{Id:1,MeasureDate:"2017-08-20T09:52:32" },{Id:2,MeasureDate:"2017-08-20T09:54:35" },{Id:3,MeasureDate:"2017-08-20T09:56:13"}];

function irreversible(){
          sensorsData.forEach(function (e){
            console.log(
                 new Date(
                      new Date(e.MeasureDate).getTime()
                 )
             );
          })        
        } 
        
        irreversible();
}        

</script>

My solution is pretty simple : comparing dates as are, and returning the result

function setDate(){
var sensorsData = [{Id:1,MeasureDate:"2017-08-20T09:52:32" },{Id:2,MeasureDate:"2017-08-20T09:54:35" },{Id:3,MeasureDate:"2017-08-20T09:56:13"}];

var lastDate = updateLatestDate(sensorsData);
console.log(lastDate.MeasureDate);


function compare(d1,d2){
if (d1.MeasureDate >d2.MeasureDate)
  return d1;
else
  return d2;
}

function updateLatestDate(sensorsData) {
      return ( sensorsData.reduce(compare) );
  }
}
</script>
<button onclick="setDate()">update date</button>
like image 1
user10089632 Avatar answered Oct 20 '22 01:10

user10089632