简体   繁体   中英

Why does react keep changing into an unecessary timezone I just want to create a date object with the same date in the string

I found another answer in stack overflow and it used the Date.UTC to create a normal date object without changing the original string date that was passed into it. I tried it in both the command line with the following code

let test_1 = new Date("2022-12-24T23:40:01Z");

const temp_date_1 = {
    month: test_1.getMonth() + 1,
    date: test_1.getUTCDate(),
    year: test_1.getFullYear(),
    hour: test_1.getUTCHours(),
    minute: test_1.getUTCMinutes(),
    second: test_1.getUTCSeconds(),
}

const utc_1 = new Date(Date.UTC(
    temp_date_1.year,
    temp_date_1.month - 1,
    temp_date_1.date,
    temp_date_1.hour,
    temp_date_1.minute,
    temp_date_1.second
));

console.log(utc_1);

but when I try it in react the date changes

const temp_deadline = new Date("2022-12-24T23:40:01Z");
const new_deadline = new Date(Date.UTC(
                temp_deadline.getFullYear(),
                temp_deadline.getMonth(),
                temp_deadline.getUTCDate(),
                temp_deadline.getUTCHours(),
                temp_deadline.getUTCMinutes(),
                temp_deadline.getUTCSeconds(),
            ))

            //
            console.log(new_deadline)
// this prints out Sun Dec 25 2022 07:40:01 GMT+0800 (Singapore Standard Time) which is wrong in the date wrong and wrong in the hour

It's still the same date & time, you're just viewing it in a different timezone, and since on that timezone it's after midnight, the date has changed as well.

You can define the timezone when printing it out. For instance:

const temp_deadline = new Date("2022-12-24T23:40:01Z");
console.log(temp_deadline.toLocaleString('en-US', { timeZone: 'Asia/Jakarta' }));
12/25/2022, 6:40:01 AM
console.log(temp_deadline.toLocaleString('en-US', { timeZone: 'Europe/Helsinki' }));
12/25/2022, 1:40:01 AM
console.log(temp_deadline.toLocaleString('en-US', { timeZone: 'America/Mexico_city' }));
12/24/2022, 5:40:01 PM

Your code is behaving as expected.

Date objects store an unambiguous representation of a specific moment in time:

Note: It's important to keep in mind that while the time value at the heart of a Date object is UTC, the basic methods to fetch the date and time or its components all work in the local (ie host system) time zone and offset.

This should fully answer your question. Your date object is a pure, absolute date object even if the console prints it using your environment's timezone. You have plenty of date methods to handle your date as needed. Read the above linked documentation.

This is simply how JavaScript dates work. So there is nothing you can do to change this behavior.

Additionally:

A JavaScript date is fundamentally specified as the number of milliseconds that have elapsed since midnight on January 1, 1970, UTC.

So, a date can be stored losslessly by storing the number of milliseconds since midnight on January 1, 1970, UTC (Use Date.prototype.getTime() ). Consequently, our code can be rewritten as:

const temp_deadline = new Date("2022-12-24T23:40:01Z");
const new_deadline = new Date(temp_deadline.getTime());

console.log(new_deadline);

temp_deadline and new_deadline above represent both the same exact date/instant in the same way.

Just remember:

  • A date can be absolutely and completely represented by the number of milliseconds since midnight on January 1, 1970, UTC.

  • A date object can be instantiated by using that number of milliseconds and will represent the exact date/instant all around the world, even if it is displayed in the local timezone.

  • There are date methods that will automatically convert the core UTC representation into a local timezone representation (the majority of date methods).

  • There are other special methods (UTC, ISO, GMT methods) that allow you to work with a "normalized" representation.

  • Date.prototype.getTime() is the absolutest and purest representation of a date in JavaScript.

Probably the react code stringifies the date value. In that case the date is automatically converted to a datetime in the current (local) time zone. So, for printing the date value from a Date Object without any time zone misery, it's best to format it yourself.

 const dl = new Date("2022-12-24T23:40:01Z"); const log = (...strs) => strs.forEach(str => document.querySelector("pre").textContent += str + `\\n`); const pad = (nr, n = 2) => `${nr}`.padStart(n, `0`); const justDisplayTheDamnedDateValueLikeIWantItTo = dl => `${dl.getFullYear()}-${pad(dl.getUTCMonth()+1)}-${ pad(dl.getUTCDate())}T${pad(dl.getUTCHours())}:${pad(dl.getUTCMinutes())}:${ pad(dl.getUTCSeconds())}:${pad(dl.getUTCMilliseconds(), 3)}Z`; log(`Is 'dl' an instance of Date (a 'Date Object')? ${ dl.constructor === Date ? `yep`: `nope`}`, ``, `"when I print" is the keyword here.`, `Printing means: display something as a *string* (stringify).`, `If you don't want the browser to apply its own rules, `, `you have format the Date Object yourself.`, ``, `So let's run 'justDisplayTheDamnedDateValueLikeIWantItTo(dl)': ${ justDisplayTheDamnedDateValueLikeIWantItTo(dl)}`);
 body { font: normal 12px/15px verdana, arial, sans-serif; margin: 2rem; } blockquote { color: #c0c0c0; padding-left: 15px; margin-left: 0; } blockquote:before { content: "> "; font-size: 1.2rem; margin-left: -20px; }
 <blockquote>I just want the new-deadline to be a datetime object that's all</blockquote> <p>And that's what it is</p> <blockquote>I don't want it to be a string, I want it to log 2022-12-24T23:40:01.000Z when I print the object so I know the object is purely this date and not a freakin time zone like singapore and some country from who gives a damn</blockquote> <pre></pre>

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