我在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);
我尝试传递一个replacer参数(stringify上的第二个参数),但问题是该值已经被处理过了。
我也尝试在日期对象上使用toString()
和toUTCString()
,但这些并没有给我我想要的东西..
任何人都可以帮助我吗?
答案 0 :(得分:58)
最近我遇到了同样的问题。它使用以下代码解决:
x = new Date();
let hoursDiff = x.getHours() - x.getTimezoneOffset() / 60;
let minutesDiff = (x.getHours() - x.getTimezoneOffset()) % 60;
x.setHours(hoursDiff);
x.setMinutes(minutesDiff);
答案 1 :(得分:36)
JSON使用不代表当地时间的Date.prototype.toISOString
函数 - 它表示未经修改的UTC时间 - 如果查看日期输出,您可以看到您处于UTC + 2小时,这就是为什么JSON字符串更改两个小时,但如果这允许在多个时区中正确表示相同的时间。
答案 2 :(得分:14)
仅供记录,请记住“2009-09-28T08:00:00Z”中的最后一个“Z”表示时间确实是UTC。
有关详细信息,请参阅http://en.wikipedia.org/wiki/ISO_8601。
答案 3 :(得分:6)
这是另一个答案(我个人认为这更合适)
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 :)
答案 4 :(得分:4)
date.toJSON()将UTC-Date打印成格式化的字符串(因此在将其转换为JSON格式时添加偏移量。)
date = new Date();
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();
答案 5 :(得分:4)
我有点迟了但你总是可以在使用Prototype的情况下覆盖toJson函数,如下所示:
Date.prototype.toJSON = function(){
return Util.getDateTimeString(this);
};
就我而言,Util.getDateTimeString(this)返回如下字符串:" 2017-01-19T00:00:00Z"
答案 6 :(得分:2)
通常您希望在当地时间内向每个用户显示日期 -
这就是我们使用GMT(UTC)的原因。
使用Date.parse(jsondatestring)获取本地时间字符串
除非您希望向每位访问者显示当地时间。
在这种情况下,请使用Anatoly的方法。
答案 7 :(得分:2)
JavaScript通常将本地时区转换为UTC。
date = new Date();
date.setMinutes(date.getMinutes()-date.getTimezoneOffset())
JSON.stringify(date)
答案 8 :(得分:2)
您可以使用moment.js来格式化本地时间:
Date.prototype.toISOString = function () {
return moment(this).format("YYYY-MM-DDTHH:mm:ss");
};
答案 9 :(得分:2)
使用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对象的时间与提供的本地时间匹配,但与日期选择器匹配。
答案 10 :(得分:1)
开箱即用的解决方案,可强制pattern = re.compile('[0-9]{4}-[0-9]{2}-[0-9]{2}')
if pattern.search(line):
matches.append(pattern.search(line))
...
忽略时区:
JSON.stringify
使用moment.js库:
// 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);
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);
答案 11 :(得分:1)
这确实很简单(我相信至少是这样:)),不需要复制日期操作或重载toJSON等浏览器的任何本机功能(参考:How to JSON stringify a javascript Date and preserve timezone,coursy Shawson)>
将替换函数传递给JSON.stringify,将内容字符串化为您内心的所有内容!这样,您就不必进行小时和分钟的差异或其他任何操作。
我已放入console.logs以查看中间结果,因此很清楚正在发生什么以及递归如何工作。这揭示了一些值得注意的东西:替换者的值参数已经转换为ISO日期格式:)。使用此[键]处理原始数据。
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.
*/
答案 12 :(得分:1)
我碰到了一些遗留问题,这些遗留问题只在美国东海岸起作用,而不在UTC中存储日期,这全都是EST。我必须根据浏览器中的用户输入过滤日期,因此必须以JSON格式在本地时间传递日期。
仅说明已发布的此解决方案-这就是我使用的方法:
// 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();
所以我的理解是,这将继续进行,并根据时区偏移量(返回分钟)从开始日期中减去时间(以毫秒为单位(因此为60000))-预计将增加对JSON()的时间。
答案 13 :(得分:0)
您可以使用format函数代替toJSON
,该函数始终提供正确的日期和时间+ GMT
这是最强大的显示选项。它需要一串令牌 并用相应的值替换它们。
答案 14 :(得分:0)
如果你的服务器后端与时区无关,那么所有这些都归结为。 如果不是,则需要假设服务器的时区与客户端相同,或者传输有关客户端时区的信息,并将其包含在计算中。
基于PostgreSQL后端的示例:
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'
如果你不愿意正确实现时区逻辑,最后一个可能是你想在数据库中使用的。
答案 15 :(得分:0)
我在8号角试过了:
创建模型:
export class Model { YourDate: string | Date; }
在您的组件中
model : Model;
model.YourDate = new Date();
将日期发送到您的API以进行保存
从API加载数据时,您将执行以下操作:
model.YourDate = new Date(model.YourDate+"Z");
您将正确地获得带有您所在时区的日期。
答案 16 :(得分:0)
在这种情况下,我认为您需要将日期转换为UNIX时间戳
timestamp = testDate.getTime();
strJson = JSON.stringify(timestamp);
之后,您可以重新使用它来创建日期对象并设置其格式。 javascript和toLocaleDateString
(https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date/toLocaleDateString)的示例
newDateObject = new Date(JSON.parse(strJson));
newDateObject = newDateObject.toLocalDateStrin([
"fr-FR",
]);
如果您使用stringify来使用AJAX,则现在不再有用。您只需要发送时间戳并将其保存在脚本中即可:
$newDateObject = new \DateTime();
$newDateObject->setTimestamp(round($timestamp/1000));
请注意,getTime()
将返回以毫秒为单位的时间,而PHP函数setTimestamp
将以秒为单位。这就是为什么您需要除以1000和round
的原因。