Json Stringify日期会产生错误日期与JavaScript日期相比

8
当我创建一个 JavaScript 日期,然后将其 "stringify" 并发送到服务器时,我得到了两个不同的日期。 "Stringified" 日期总是晚一天。
所以目前我通过增加 JavaScript 日期一天来接收相同的日期到服务器。
我的当前代码:
var dt = $(.datepicker).datepicker('getDate');//Fri Aug 26 2016 00:00:00 GMT+0200 (South Africa Standard Time)
var result = Json.stringify(dt); //"2016-08-25T22:00:00.000Z"

这种方法是否正确?还有什么遗漏的吗?

dt的内容是什么,result的输出是什么? - Guy
1
将我的 JavaScript 日期增加一天 - 这不是一个好的方法 - 当 UTC 日与您的日相同时,请尝试在不同的时间进行操作 - 然后查看已经尝试解决这些问题的库...日期对于每个语言的每个程序员来说都是一个烦恼 :p - Jaromanda X
请确认您的客户端和服务器处于同一时区。 - ciril sebastian
@guy 我更新了问题。 - JustLearning
@cirilsebastian 这对我的问题有什么影响呢?因为所有的处理都在客户端完成。当我检查控制台和服务器时,ajax post 已经包含了错误的日期,因此服务器接收到的日期也是错误的。 - JustLearning
1
你似乎不理解本地时间和协调世界时(UTC)的日期时间。 - Xotic750
3个回答

11

这是由于Date中的时区组件造成的。我所做的解决方法是:

var date = $(.datepicker).datepicker('getDate');
var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes()))
var result = Json.stringify(utcDate);

去掉时区组件。


你这样做会得到一个不准确的应用程序。 - Xotic750
@Xotic750,你能解释一下为什么并提出一个解决方案吗? - JustLearning
您的问题中的日期时间格式都是相同的,只是时区不同,一个是GMT+2,另一个是UTC。因此,您的服务器已经接收到与客户端相同的日期时间。您需要解释为什么您相信或需要手动创建两个日期时间之间的差异。 - Xotic750
这段代码将在2022年1月1日失败,它会返回2021年1月1日。 - yash

2
您似乎没有理解您的两个日期时间实际上是相同且正确的。您没有解释为什么认为需要手动更改发送到服务器的日期时间之一。这里有一个示例,证明它们实际上是相同的,只是以不同的格式显示在不同的时区中。

// Values from the local datetime string
var local = {
  year: 2016,
  month: 7,
  day: 26,
  hours: 0,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Values from the UTC ISO 8601 datetime string
var utc = {
  year: 2016,
  month: 7,
  day: 25,
  hours: 22,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Create Date object as local
var date1 = new Date(
  local.year,
  local.month,
  local.day,
  local.hours,
  local.minutes,
  local.seconds,
  local.milliseconds
);

// Create Date object as local from UTC
var date2 = new Date(Date.UTC(
  utc.year,
  utc.month,
  utc.day,
  utc.hours,
  utc.minutes,
  utc.seconds,
  utc.milliseconds
));

var pre = document.getElementById('out');
// Display Date1 as local
pre.appendChild(document.createTextNode(date1.toString() + '\n'));
// Display Date2 as local
pre.appendChild(document.createTextNode(date2.toString() + '\n'));
// Display Date2 as UTC
pre.appendChild(document.createTextNode(date2.toUTCString() + '\n'));
// Test if Date1 and Date2 display the same datetime
pre.appendChild(document.createTextNode(
  'Date1 === Date2: ' + (date1.getTime() === date2.getTime())
));
<pre id="out"></pre>

JSON将Date对象转换为ISO 8601(根据规范),但是让我们看看如果您使用您选择的解决方案会发生什么。

// Values from the local datetime string
var local = {
  year: 2016,
  month: 7,
  day: 26,
  hours: 0,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Create Date object as local
var date = new Date(
  local.year,
  local.month,
  local.day,
  local.hours,
  local.minutes,
  local.seconds,
  local.milliseconds
);

// Your solution
var utcDate = new Date(Date.UTC(
  date.getFullYear(),
  date.getMonth(),
  date.getDate(),
  date.getHours(),
  date.getMinutes()));

var pre = document.getElementById('out');
// Display Date as local format
pre.appendChild(document.createTextNode(date.toString() + '\n'));
// Display utcDate as local format
pre.appendChild(document.createTextNode(utcDate.toString() + '\n'));
// Test if Date and utcDate display the same datetime
pre.appendChild(document.createTextNode(
  'Date1 === Date2: ' + (date.getTime() === utcDate.getTime())
));
<pre id="out"></pre>

你最终会得到两个不再相同的日期。不喜欢使用ISO 8601来传输和存储日期时间?那么替代方案就是使用自纪元以来(getTime)的毫秒数UTC。你无法让JSON在转换时使用这种方式而不是ISO 8601,即使使用替换函数也不行。因此,在使用JSON.stringify之前,需要进行任何必要的转换。所以你真的需要解释一下你想要达到什么目的,以及为什么认为现在的方法是错误的。

-1

使用这个

var result = Json.stringify(dt.toISOString());

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - wazz
请添加更多信息。不鼓励仅有代码和“试试这个”的答案,因为它们没有可搜索的内容,并且没有解释为什么某人应该“试试这个”。 - abarisone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接