JSON Stringify는 UTC로 인해 날짜 시간을 변경합니다.
JavaScript의 날짜 개체는 내가있는 위치 때문에 항상 UTC +2로 표시됩니다. 따라서 이렇게
Mon Sep 28 10:00:00 UTC+0200 2009
문제는 JSON.stringify
위 날짜를 다음 으로 변환하는 것입니다.
2009-09-28T08:00:00Z (notice 2 hours missing i.e. 8 instead of 10)
내가 필요한 것은 날짜와 시간을 존중하는 것이지만 그렇지 않습니다.
2009-09-28T10:00:00Z (this is how it should be)
기본적으로 나는 이것을 사용합니다.
var jsonData = JSON.stringify(jsonObject);
대체 매개 변수 (stringify의 두 번째 매개 변수)를 전달하려고 시도했지만 문제는 값이 이미 처리되었다는 것입니다.
나는 또한 사용하여 시도 toString()
및 toUTCString()
날짜 개체에 있지만 이러한 나도 원하는 걸주지 않는다 ..
누구든지 나를 도울 수 있습니까?
최근에 같은 문제가 발생했습니다. 그리고 다음 코드를 사용하여 해결되었습니다.
x = new Date();
let hoursDiff = x.getHours() - x.getTimezoneOffset() / 60;
let minutesDiff = (x.getHours() - x.getTimezoneOffset()) % 60;
x.setHours(hoursDiff);
x.setMinutes(minutesDiff);
JSON은 Date.prototype.toISOString
현지 시간을 나타내지 않는 함수를 사용합니다 . 수정되지 않은 UTC의 시간을 나타냅니다. 날짜 출력을 보면 UTC + 2 시간이라는 것을 알 수 있습니다. 이것이 JSON 문자열이 2 시간 씩 변경되는 이유입니다. 그러나 이것이 여러 시간대에서 동일한 시간이 올바르게 표시되도록 허용하는 경우.
기록을 위해 "2009-09-28T08 : 00 : 00Z"의 마지막 "Z"는 시간이 실제로 UTC임을 의미합니다.
자세한 내용은 http://en.wikipedia.org/wiki/ISO_8601 을 참조하십시오.
여기 또 다른 대답이 있습니다 (개인적으로 더 적절하다고 생각합니다)
var currentDate = new Date();
currentDate = JSON.stringify(currentDate);
// Now currentDate is in a different format... oh gosh what do we do...
currentDate = new Date(JSON.parse(currentDate));
// Now currentDate is back to its original form :)
나는 조금 늦었지만 Prototype을 사용하는 Date의 경우 항상 toJson 함수를 덮어 쓸 수 있습니다.
Date.prototype.toJSON = function(){
return Util.getDateTimeString(this);
};
제 경우에는 Util.getDateTimeString (this)이 다음과 같은 문자열을 반환합니다. "2017-01-19T00 : 00 : 00Z"
date.toJSON ()은 UTC-Date를 형식화 된 문자열로 인쇄합니다 (따라서 JSON 형식으로 변환 할 때 오프셋을 추가합니다).
date = new Date();
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();
일반적으로 각 사용자에게 자신의 현지 시간으로 날짜를 표시하려고합니다.
이것이 우리가 GMT (UTC)를 사용하는 이유입니다.
Date.parse (jsondatestring)을 사용하여 현지 시간 문자열을 가져옵니다.
각 방문자에게 현지 시간이 표시되는 것을 원하지 않는 한 .
이 경우 Anatoly의 방법을 사용하십시오.
moment.js
라이브러리 (비 시간대 버전) 를 사용하여이 문제를 해결했습니다 .
var newMinDate = moment(datePicker.selectedDates[0]);
var newMaxDate = moment(datePicker.selectedDates[1]);
// Define the data to ask the server for
var dataToGet = {"ArduinoDeviceIdentifier":"Temperatures",
"StartDate":newMinDate.format('YYYY-MM-DD HH:mm'),
"EndDate":newMaxDate.format('YYYY-MM-DD HH:mm')
};
alert(JSON.stringify(dataToGet));
나는 flatpickr.min.js
도서관 을 사용하고 있었다 . 생성 된 결과 JSON 객체의 시간은 제공된 현지 시간과 일치하지만 날짜 선택기입니다.
moment.js 를 사용하여 현지 시간으로 형식을 지정할 수 있습니다 .
Date.prototype.toISOString = function () {
return moment(this).format("YYYY-MM-DDTHH:mm:ss");
};
JSON.stringify
시간대 를 강제로 무시하는 즉시 사용 가능한 솔루션 :
- 순수 자바 스크립트 (Anatoliy 답변 기반) :
// Before: JSON.stringify apply timezone offset
const date = new Date();
let string = JSON.stringify(date);
console.log(string);
// After: JSON.stringify keeps date as-is!
Date.prototype.toJSON = function(){
const hoursDiff = this.getHours() - this.getTimezoneOffset() / 60;
this.setHours(hoursDiff);
return this.toISOString();
};
string = JSON.stringify(date);
console.log(string);
Using moment.js library:
const date = new Date();
let string = JSON.stringify(date);
console.log(string);
Date.prototype.toJSON = function(){
return moment(this).format("YYYY-MM-DDTHH:mm:ss:ms");;
};
string = JSON.stringify(date);
console.log(string);
<html>
<header>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.min.js"></script>
</header>
</html>
Here is something really neat and simple (atleast I believe so :)) and requires no manipulation of date to be cloned or overloading any of browser's native functions like toJSON (reference: How to JSON stringify a javascript Date and preserve timezone, courtsy Shawson)
Pass a replacer function to JSON.stringify that stringifies stuff to your heart's content!!! This way you don't have to do hour and minute diffs or any other manipulations.
I have put in console.logs to see intermediate results so it is clear what is going on and how recursion is working. That reveals something worthy of notice: value param to replacer is already converted to ISO date format :). Use this[key] to work with original data.
var replacer = function(key, value)
{
var returnVal = value;
if(this[key] instanceof Date)
{
console.log("replacer called with key - ", key, " value - ", value, this[key]);
returnVal = this[key].toString();
/* Above line does not strictly speaking clone the date as in the cloned object
* it is a string in same format as the original but not a Date object. I tried
* multiple things but was unable to cause a Date object being created in the
* clone.
* Please Heeeeelp someone here!
returnVal = new Date(JSON.parse(JSON.stringify(this[key]))); //OR
returnVal = new Date(this[key]); //OR
returnVal = this[key]; //careful, returning original obj so may have potential side effect
*/
}
console.log("returning value: ", returnVal);
/* if undefined is returned, the key is not at all added to the new object(i.e. clone),
* so return null. null !== undefined but both are falsy and can be used as such*/
return this[key] === undefined ? null : returnVal;
};
ab = {prop1: "p1", prop2: [1, "str2", {p1: "p1inner", p2: undefined, p3: null, p4date: new Date()}]};
var abstr = JSON.stringify(ab, replacer);
var abcloned = JSON.parse(abstr);
console.log("ab is: ", ab);
console.log("abcloned is: ", abcloned);
/* abcloned is:
* {
"prop1": "p1",
"prop2": [
1,
"str2",
{
"p1": "p1inner",
"p2": null,
"p3": null,
"p4date": "Tue Jun 11 2019 18:47:50 GMT+0530 (India Standard Time)"
}
]
}
Note p4date is string not Date object but format and timezone are completely preserved.
*/
I run into this a bit working with legacy stuff where they only work on east coast US and don't store dates in UTC, it's all EST. I have to filter on the dates based on user input in the browser so must pass the date in local time in JSON format.
Just to elaborate on this solution already posted - this is what I use:
// Could be picked by user in date picker - local JS date
date = new Date();
// Create new Date from milliseconds of user input date (date.getTime() returns milliseconds)
// Subtract milliseconds that will be offset by toJSON before calling it
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();
So my understanding is this will go ahead and subtract time (in milliseconds (hence 60000) from the starting date based on the timezone offset (returns minutes) - in anticipation for the addition of time toJSON() is going to add.
All boils down to if your server backend is timezone-agnostic or not. If it is not, then you need to assume that timezone of server is the same as client, or transfer information about client's timezone and include that also into calculations.
a PostgreSQL backend based example:
select '2009-09-28T08:00:00Z'::timestamp -> '2009-09-28 08:00:00' (wrong for 10am)
select '2009-09-28T08:00:00Z'::timestamptz -> '2009-09-28 10:00:00+02'
select '2009-09-28T08:00:00Z'::timestamptz::timestamp -> '2009-09-28 10:00:00'
The last one is probably what you want to use in database, if you are not willing properly implement timezone logic.
Instead of toJSON
, you can use format function which always gives the correct date and time + GMT
This is the most robust display option. It takes a string of tokens and replaces them with their corresponding values.
참고URL : https://stackoverflow.com/questions/1486476/json-stringify-changes-time-of-date-because-of-utc
'IT story' 카테고리의 다른 글
Eclipse에서 pep8.py를 통합하는 방법은 무엇입니까? (0) | 2020.09.05 |
---|---|
Google의 Imageless 버튼 (0) | 2020.09.05 |
base128이 사용되지 않는 이유는 무엇입니까? (0) | 2020.09.04 |
문자열에서 선행 및 후행 0을 제거하는 방법은 무엇입니까? (0) | 2020.09.04 |
감독자 소켓 오류 문제 [종료 됨] (0) | 2020.09.04 |