0

I have an API which gives the date format like 01/04/2020 00:17:26 and we are using the JavaScript code below:

function getLocalTime(timestamp){
    try {
        let localTime = new Date(timestamp.replace('at ','') + ' GMT+530');
        return localTime;
    } catch(e){
        return timestamp;
    }
}

vat date = getLocalTime('01/04/2020 00:17:26');
console.log(date);

The above code is returning Sat Jan 04 2020 00:17:26 GMT+0530 (India Standard Time) But expected result will be as like Wed Apr 01 2020 00:17:26 GMT+0530 (India Standard Time)

Please help us with this.

Chinmay235
  • 3,236
  • 8
  • 62
  • 93
  • 1
    Does this answer your question? [new Date('dd/mm/yyyy') instead of newDate('mm/dd/yyyy')](https://stackoverflow.com/questions/51085176/new-datedd-mm-yyyy-instead-of-newdatemm-dd-yyyy) – czolbe Apr 01 '20 at 02:21
  • this is unclear, timestamp is supposed to be UTC time ? ( GMT doesn't exist anymore) – Mister Jojo Apr 01 '20 at 02:22
  • @MisterJojo—for all practical purposes, in ECMAScript GMT === UTC. – RobG Apr 01 '20 at 09:18

1 Answers1

1

The issue is the wrong date format you are using.

Your format: DD/MM/YYYY

Expected format: MM/DD/YYYY

Still, if the input format you are expecting (from the user) is DD/MM/YYYY (e.g. 01/04/2020 00:17:26), then you can use regex to extract the date info like so

function getLocalTime(timestamp){
    try {
        const datePart = timestamp.match(/^(\d{2})\/(\d{2})\/(\d{4})/);
        const day = datePart[1];
        // month goes from 0 to 11
        const month = datePart[2] - 1;
        const year = datePart[3];
        
        const localTime = new Date(timestamp.replace('at ','') + ' GMT+0530');
        localTime.setFullYear(year);
        localTime.setMonth(month);
        localTime.setDate(day);
        
        return localTime;
    } catch(e){
        return timestamp;
    }
}

const date = getLocalTime('01/04/2020 00:17:26');
console.log(date);

Update

@RobG proposed a fantastic solution (see in comments below).

function getLocalTime(timestamp) {
    try {
        const matches = timestamp.split(/\D+/);  // or use timestamp.match(/\d+/g) 
        return new Date(Date.UTC(matches[2], matches[1]-1, matches[0], matches[3]-5, matches[4]-30, matches[5]));
    } catch(e){
        return timestamp;
    }
}

const date = getLocalTime('01/04/2020 00:17:26');
console.log(date);
Kenan Güler
  • 1,868
  • 5
  • 16
  • Using the built–in parser is a bad start, setting the values separately makes it worse. Far better to extract the parts using say `timestamp.match(/\d+/g)` and use the Date constructor with a single call `new Date(year, month - 1, day, ...)`. – RobG Apr 01 '20 at 09:15
  • @RobG your suggestion `timestamp.match(/\d+/g)` would not provide all matches for `'01/04/2020 00:17:26'.match(/\d+/)` You would get `["01", index: 0, input: "01/04/2020 00:17:26", groups: undefined]` as result. Also please notice the offset `GMT+0530` which should also be considered during the constructing of the `localTime`. How would you deal with that part otherwise? I didn't want to spend much time with this question, so just used the existing code base. – Kenan Güler Apr 01 '20 at 09:35
  • `setting the values separately makes it worse` makes it worse? how so? It was may intention to set the values separately to make the code readable for the OP. And it sure is no different than passing the values directly to constructor. But describing that as `it makes things worse` has really no rational ground. – Kenan Güler Apr 01 '20 at 09:38
  • 1
    Using the built–in parser means a date like 31/03/2020 00:17:26 will most likely return an invalid date, so trashing the time part. Also see [*Javascript setMonth shows improper date*](https://stackoverflow.com/questions/23976513/javascript-setmonth-shows-improper-date). `timestamp.match(/\d+/g)` will match groups of one or more digits, so `'01/04/2020 00:17:26'.match(/\d+/g)` will return the array `['01','04','2020','00','17','26']`, which is everything needed to call the Date constructor directly to create a Date for 2020-04-01 00:17:26. Offset +5:30 can be applied concurrently. – RobG Apr 01 '20 at 11:02
  • 1
    Consider `let b = '01/04/2020 00:17:26'.split(/\D+/); new Date(Date.UTC(b[2], b[1]-1, b[0], b[3]-5, b[4]-30, b[5]))` which builds the Date from the parts and applies the timezone offset at the same time. – RobG Apr 01 '20 at 11:11
  • @RobG you are right. Thanks a lot for your time and explanation (and for the link regarding the `setMonth()` - I honestly didn't know about the second argument). I updated my answer. Cheers! – Kenan Güler Apr 01 '20 at 11:29
  • @KenanGüler It was working fine. But today we found the date hours mismatch. Kindly change the date `01/04/2020 00:17:26` to `13/04/2020 14:17:26` and you will get the issue. – Chinmay235 Apr 13 '20 at 09:23
  • @KenanGüler Updated answer is working fine – Chinmay235 Apr 13 '20 at 09:29