假设您网站的用户输入了一个日期范围。

2009-1-1 to 2009-1-3

您需要将此日期发送到服务器进行某些处理,但服务器要求所有日期和时间均为UTC。

现在假设用户在阿拉斯加。由于它们所处的时区与UTC完全不同,因此需要将日期范围转换为如下所示:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

使用JavaScriptDate对象,如何将第一个“本地化”日期范围转换为服务器能够理解的内容?


当前回答

根据我的观察,

var timeUtc=新日期();

timeUtc将始终显示UTC时间,但如果您调试或控制台,浏览器将始终显示当前时区的时间。

如果您将timeUtc作为参数发送到任何post请求,那么在chrome的网络选项卡中,您可以检查post数据,您将看到timeUtc将具有UTC时间。

其他回答

转换为ISO而不更改日期/时间

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time) 
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z

转换为ISO并更改日期/时间(日期/时间将更改)

isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z 

Fiddle链接

到目前为止,我发现获取GMT时间的最佳方法是首先获取您的本地日期时间。然后转换为GMT字符串。然后使用该字符串通过删除时区来构建新时间。

let dtLocal = new Date()
let dt = new Date(dtLocal.toISOString().split('Z')[0])

注意:-它将以GMT创建新的日期时间。但它将是本地日期时间,因为时区将附加到它。

对于目标是将其作为“日期对象”而不是字符串获取的其他人,并且您只想显示不带TZ(可能是硬编码的)的日期/时间,您可以做的是:

const now = new Date();
const year = now.getUTCFullYear();
const month = now.getUTCMonth();
const day = now.getUTCDate();
const hour = now.getUTCHours();

const tomorrowUTC= new Date();
tomorrowUTC.setDate(day + 1); // +1 because my logic is to get "tomorrow"
tomorrowUTC.setYear(year);
tomorrowUTC.setMonth(month);
tomorrowUTC.Hours(hour);

// then use the tomorrowUTC for to display/format it
// tomorrowUTC is a "Date" and not a string.

然后,您可以执行以下操作:

我们将在${格式(明天UTC,'EEEE do MMMM hh:mmaa')}UTC删除您的帐户

(格式是一个日期fns函数,如果需要,可以使用其他lib);

这有点“黑客”,因为这仍然使用本地时区,但如果你只想显示日期而不是时区,那么这就可以了。

如果需要日期对象

仅传递日期字符串date假定时间按时区偏移00:00:

new Date('2019-03-11')
Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)

如果您添加当前的小时和分钟,您将获得正确的日期:

new Date('2019-03-11 ' + new Date().getHours() + ':' + new Date().getMinutes())
Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)

我的解决方案使日期保持不变,无论客户端上设置了什么时区。也许有人会发现它很有用。

我的用例:

我正在创建一个todo应用程序,您可以在其中设置任务日期。无论您在哪个时区,此日期都应保持不变。

实例你想在6月25日早上8点给你的朋友打电话。

您在中国时,在5天前(6月20日)创建此任务。

然后,在同一天,你飞往纽约几天。

然后在6月25日,当你还在纽约时,你在早上7:30醒来(这意味着你应该在30分钟内收到任务通知(即使在中国,你创建任务时已经是下午1:30)

因此,任务是忽略时区。这意味着“我想在早上8点在任何时区做这件事”。

我所做的是让我们说“我假设你总是在伦敦时区-UTC”。

这意味着-当用户在她/他的时区中选择某个日期时-我将此日期转换为UTC中的相同日期。也就是说,你在中国选择上午8点,但我将其转换为UTC的上午8点。

然后-下次你打开应用程序时-我读取以UTC保存的日期,并将其转换为当前时区中的相同日期-例如,我将UTC中的上午8点转换为纽约时区中的早上8点。

这个解决方案意味着,日期可能意味着其他东西,这取决于你在设置日期时的位置和阅读日期的位置,但它保持不变,“感觉”你总是在同一时区。

让我们编写一些代码:

首先,我们有两个主要函数用于从UTC转换为UTC,忽略时区:

export function convertLocalDateToUTCIgnoringTimezone(date: Date) {
  const timestamp = Date.UTC(
    date.getFullYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds(),
  );

  return new Date(timestamp);
}

export function convertUTCToLocalDateIgnoringTimezone(utcDate: Date) {
  return new Date(
    utcDate.getUTCFullYear(),
    utcDate.getUTCMonth(),
    utcDate.getUTCDate(),
    utcDate.getUTCHours(),
    utcDate.getUTCMinutes(),
    utcDate.getUTCSeconds(),
    utcDate.getUTCMilliseconds(),
  );
}

然后,我保存/读取此日期,如:

function saveTaskDate(localDate: Date) {
  // I convert your local calendar date so it looks like you've picked it being in UTC somewhere around London
  const utcDate = convertLocalDateToUTCIgnoringTimezone(localDate);
  api.saveTaskDate(utcDate);
}

function readTaskDate(taskUtcDate: Date) {
  // I convert this UTC date to 'look in your local timezone' as if you were now in UTC somewhere around london
  const localDateWithSameDayAsUTC = convertUTCToLocalDateIgnoringTimezone(taskUtcDate);

  // this date will have the same calendar day as the one you've picked previously
  // no matter where you were saving it and where you are now
}