简体   繁体   中英

MomentJS and JS Date objects not referring to the same hour

I've got a server instance (NodeJS) that receives a set of objects, and schedules them for sending push notifications to users.

Some of these objects, are periodic, and this periodicity is handled by a string like this:

90=>Mon&Tue&Thu=>16:00

Which is read as:

offset_minutes=>days_of_the_week=>initial_hour

Then, what I do is to check whether the current day matches one of the given days in the string, and then, modify the date to the given hour in the "initial_hour", and finally, substract the "offset_minutes" amount of minutes from the Date object.

Seems straightforward until now, right? Well, not that much. Let's first see the code:

const isToday = weekDays.split("&")
            .map(a => {
                switch (a) {
                    case 'Mon': return 1;
                    case 'Tue': return 2;
                    case 'Wed': return 3;
                    case 'Thu': return 4;
                    case 'Fri': return 5;
                    case 'Sat': return 6;
                    case 'Sun': return 7;
                }
            })
            .some(v => v == currentDay);

        if (isToday) {

            let finalDate = moment(today)
                .set("hour", Number(hour))
                .set("minute", Number(mins));


            if (offset) {
             finalDate.subtract('minutes', Number(offset));
            }


            return finalDate.toDate();

Everything works well, until I do the MomentJS transformations. When I output a Date object with the ".toDate()" method, this object is always set to 2 hours before the expected time . But if I use the.toISOString() method, I get the proper time for all the occurrencies.

I guess that something is wrong with my Date objects, setting them up at a different timezone than the one I have. A couple of examples:

  • For the string 90=>Mon&Tue&Thu=>16:00 I get the Date object: 2019-10-14T14:00:11.852Z
  • For the string 30=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30 I get the Date object: 2019-10-14T16:30:11.866Z

I would like to know what's the explanation for such a behavior, and if I can do something to change it so the normal Javascript Date object points to the same hour than my momentjs object, or the.toISOString() output.

Thank you!

The posted code is incomplete and doesn't demonstrate the issue described.

I've reimplemented the code without moment.js as best I can and simplified it. It seems to work fine:

 function parseThing(s) { // Parse input string let b = s.split('=>'); let offset = +b[0]; let days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; let weekDays = b[1].split('&').map(day => days.indexOf(day)); let [hr, min] = b[2].split(':'); // Get a date for today let date = new Date(); // If today included, return an adjusted date if (weekDays.includes(date.getDay())) { date.setHours(hr, min, 0, 0); if (offset) { date.setMinutes(date.getMinutes()+ Number(offset)); } return date; } // If today isn't included, return null return null; } let s0 = '90=>Mon&Tue&Thu=>16:00'; let s1 = '0=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30'; console.log(parseThing(s0).toString()); console.log(parseThing(s1).toString());

Where the local day is one of those in the string (Mon, Tue, Thu) it returns a Date equivalent to a local time of 17:30, which is 90 minutes offset from 16:00, which seems to be correct.

PS I've changed Sunday to 0 as I can't see any rationale for it to be 7. Also seconds and milliseconds are zeroed too.

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