【发布时间】:2014-11-01 20:27:38
【问题描述】:
我的 javascript 应用程序必须创建事件,这些事件将作为 UTC 存储在数据库中,以便之后可以在 3 个不同的时区中显示。
我发现难以弄清楚的棘手部分是,在创建事件时,用户必须选择一个时区和日期。
这个想法是: - 用户从带有时区的附加下拉列表中选择日期 + 所需时区。 - 我在数据库中存储为 UTC - 所有用户都可以看到 3 个不同时区的日期。
您可能会问,当使用日期选择器选择日期时,为什么有人需要额外的下拉列表来选择另一个时区,默认情况下已经包含一个时区。
示例:假设 Jim,美国公民,他一生都在使用 EDT 华盛顿时间计划活动;他正在中国访问,进入一家中国网吧,并想使用这个应用程序计划一个活动。日期选择器将选择当地时区,即中国标准时间。但 Jim 想通过 EDT 进行计划,并确保该应用程序能够正确处理所有事情。
因此,他必须从额外的下拉列表中专门选择所需的时区。
所以我的问题是。 因为我允许用户选择所需的时区,我是否首先必须将用户输入的日期转换为那个时区,然后再将其转换为 UTC,然后才存储它? 还是在将事件保存在数据库中时,我根本对时区转换不感兴趣?
那么哪一步是正确的: - 获取本地日期+选定的时区 - 将本地日期转换为用户选择的时区 - 将日期转换为 UTC - 存储到数据库 - 阅读时,使用选定的时区转换为 3 个时区
或 - 获取本地日期+选定的时区 - 将日期转换为 UTC,忽略时区 - 存储到数据库 - 阅读时,使用选定的时区转换为 3 个时区
稍后编辑 - 我在 meteor 中执行此操作,因此是 javascript 服务器端。 DB 是 mongodb,因此出于性能原因,日期必须保存为 JS 日期对象(当然是 utc 格式)。
第二次编辑
以下是我尝试过的实现(它不起作用,例如当我输入 KST 上午 07:00 的事件日期时,当输出从数据库读回的最终结果并在该 KST 时区中转换回时显示除了07:00 AM)
一切从这里开始 - 这是一个服务器端方法,它从日期选择器中读取日期、从时间选择器中读取时间以及从下拉列表中读取时区:
var pStartDate = GetDateAndTimeFromPostData(eventAttributes.startDate, eventAttributes.startTime, eventAttributes.timezone);
这里我尝试从不同的控件(datepicker、timepicker、timezone ddl)构建选定的日期:
function GetDateAndTimeFromPostData(dt, tm, timezone)
{
var t = tm.split(":");
var hour = t[0];
var min = t[1];
var finalDate = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), hour, min);
var utcConverted = ConvertUserTimezoneToServerTimezone(finalDate, timezone);
return utcConverted;
}
我在这里尝试时区转换:
function ConvertUserTimezoneToServerTimezone(dateToConvert, tz)
{
var userTimezonedDate;
switch(tz)
{
case "EDT":
{
userTimezonedDate = moment.tz(dateToConvert, "America/New_York");
break;
}
case "CEST":
{
userTimezonedDate = moment.tz(dateToConvert, "Europe/Berlin");
break;
}
case "KST":
{
userTimezonedDate = moment.tz(dateToConvert, "Asia/Seoul");
break;
}
case "CST":
{
userTimezonedDate = moment.tz(dateToConvert, "Asia/Shanghai");
break;
}
}
var utcDateFromUserTimezonedDate = userTimezonedDate.utc().toDate();
return utcDateFromUserTimezonedDate;
}
错误已经在上面的代码中,因为 utc 日期没有保存为 KST,而是保存为 GMT(我的本地时区)。
作为旁注,我不太了解时刻时区如何转换;当我访问时区网站时,我会在 chrome 开发工具中这样写:
var x = new Date();
var y = moment.tz(x, "Asia/Seoul");
y.utc().toDate()
我实际上希望返回一个显示 KST 的日期对象,对吗?但它显示 GMT+2,我的本地 tz。
2014 年 9 月 8 日星期一 23:44:05 GMT+0200(中欧夏令时间)
我也尝试过向后考虑,例如存储的日期对象应该是什么样子,但这也令人困惑 - 是否应该将其保存为选定的时区?例如2014 年 9 月 8 日星期一 23:44:05 GMT+0900 (KST) 如果不是,我存储的日期对象应该是什么样子?
再次,我使用带有流星和 mongoDB 作为数据库的 javascript 服务器端。
非常感谢,
【问题讨论】:
-
这在很大程度上取决于您要在数据库中存储的格式......
-
只需使用不显示本地时区但可配置为任何时区的日期选择器,然后生成 UTC 时间戳。
-
@Amc_rtty 你在这里最终得到了什么解决方案?
-
@geoboy 采用了 Matt Johnson 的解决方案,见下文
标签: javascript datetime timezone