简体   繁体   中英

How do I convert this date from momentjs to plain JavaScript

I have a timestamp that I am trying to roundto the nearest UTC Monday 00:00:00:00:000Z

My code in moment looks like this

let now = Date.now()
moment.unix(now / 1000).utc().startOf("isoWeek").valueOf()

I am trying to do this in plain JS without moment and I am not getting the same answer

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = (monday + 7 - currentDay) % 7;
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    return newDate;
}

> d = Date.now()
1545989455067
> nearestMonday(new Date(d)).getTime()
1546194600000
> m.unix(Date.now() / 1000).utc().startOf("isoWeek").valueOf()
1545609600000

I am in GMT + 530 zone , what do I change to get the same answer as moment

I think this may do what you want:

const nearestMonday = date => {
    const day = 1000*60*60*24;
    const week = day*7;
    return new Date(Math.floor(date.getTime()/week)*week-3*day);
}

Ok, so we have a few problems here:

First: Timezones

Date works with your local timezone, so when you do newDate.setHours(0, 0, 0, 0); and stuff like that, it sets the object to that hours in your timezone. When you do .getTime() , however, it does return millis from epoch in UTC.

The result of this being: if you are in gmt+530 (India, I believe) when you do a .getTime() the millis from epoch will be off by that difference (5h 30m).

To compensate that, you can use getTimezoneOffset() :

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = (monday + 7 - currentDay) % 7;
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
    return newDate;
}

On the other hand, your code using moment will work properly with timezones, so there's no need to change it.


Second: What monday?

Your function nearestMonday calculates the next Monday.

The function startOf('isoWeek') sets the date to the Monday of the current week.

If you want both to calculate the current , you should modify your nearestMonday like:

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = monday - currentDay;
    console.log('dist', distance);
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
    return newDate;
}

Last: Sundays?

getDay() on Sunday will return a 0. Therefore, the "nearestMonday" will be the day after that. I haven't corrected it since I don't know if that's the desired behaviour, but noting it just for completion sake

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM