2

我正在开发一个应用程序,它检测浏览器的时区并要求用户将时区设置为浏览器检测到的值。

因此,我填充了一个选择下拉列表,其中列出了 ActiveSupport::TimeZone::MAPPING 中存在的所有键。

现在,我有一个用户的时区是 (GMT-08:00) Pacific/Pitcairn。ActiveSupport::TimeZone 中不存在许多这样的值。

我应该如何处理这些价值观。我检查了许多声称发送 Rails Supported Values 的 js 文件,但它们似乎都不起作用。

如果我在 Windows 机器中将时区设置为 UTC-08:00,那么我的 javascript 插件会检测到时区并发送美国/洛杉矶的值。

我们有一个复选框,不允许在 Windows 机器上使用 DST 计时。因此,在这种情况下,以 UTC-08:00 作为时区并且未选中 DST 框,我们将得到一个值 Pacific/Pitcairn。

因此,在 America/Los Angeles 和 Pacific/Pitcairn 的两个不同值之前/之前进行匹配是不可能的。

通过 UTC 偏移量设置值,忽略名称也无济于事。对于蒂华纳,我们有两个单独的值,即 (UTC-08:00) 太平洋时间(美国和加拿大)和 (UTC-08:00)。那么我如何决定设置哪个值。

showTimeZoneInfo: function(member_time_zone, timeZoneInfo, invertTZHash){
  var tzValue = jQuery().get_timezone({'defaultvalue' : 'Etc/UTC'});
  var railsOffset = TimeZoneFlash.extractOffset(timeZoneInfo[member_time_zone]);
  var browserOffset = TimeZoneUtils.zoneWithoutDST();
  if ( railsOffset != browserOffset) {
    jQuery(".time_zone_text").text(browserOffset + " " + invertTZHash[tzValue]);
    jQuery('.cjs_display_time_zone').removeClass('hide');
  }
}

现在我们有一个 invertTZHash 不包含 Pacific/Pitcairn 的情况。它返回一个未定义的值。

我正在为与浏览器时区相比处于不同时区的用户构建一个警报框。甚至 Intl.DateTimeFormat().resolved.timeZone 也无济于事,因为我的大部分流量来自 IE 和 FF 浏览器

4

2 回答 2

3

时区!= 偏移量。请参阅时区标签 wiki。因此,将其换成恰好在 UTC-8 上的另一个时区并不是一个好主意。您将获取该区域的所有 DST 规则,这些规则不一定适用。

Pacific/Pitcairn如果您处理过去的日期,甚至不是纯粹的 UTC-8。它在 1998 年从 UTC-08:30 移动到 UTC-08:00 - 你可以在这里看到。

这是我对 ActiveSupport::TimeZone 不满意的原因之一。他们在他们的文档中非常清楚地表明它是有限的:

将 TZInfo 提供的区域集限制为 146 个区域的有意义子集。

这似乎相当随意。谁来决定什么是“有意义的”,什么不是?如果它没有意义,它一开始就不会在数据库中!

您应该考虑使用tzinfo gem,这是 ActiveSupport 所基于的。它具有完整的 TZDB 及其所有时区数据,而不是有限的子集。

关于时区检测,我不确定您使用什么 JavaScript 来“检测”时区。您展示了调用一些函数get_timezoneTimeZoneFlash.extractOffset这些函数必须为您的应用程序自定义或由外部库提供。请详细说明您正在使用什么。

我知道的唯一 JavaScript 时区检测库是jsTimeZoneDetect - 这很清楚它只需要有根据的猜测。除非您依赖最新的 Chrome 和 Opera 中的新国际化 API(我认为您不是),否则无法保证在没有用户参与的情况下检测时区。另请参阅此答案

我们有一个复选框,不允许在 Windows 机器上使用 DST 计时。因此,在这种情况下,以 UTC-08:00 作为时区并且未选中 DST 框,我们将得到一个值 Pacific/Pitcairn。

是的,这是一个可怕的现实。恕我直言 - 永远不应该取消检查。如果复选框不存在会更好。DST 是否适用由时区处理,因此没有充分的理由禁用它。我敢肯定,他们是专门为像皮特凯恩这样的情况而将其留在那里的,因为没有专门针对他们的 Windows 时区条目。

更新

从您的评论中:

我已经有一个下拉菜单。我正在为与浏览器时区相比处于不同时区的用户构建一个警报框。

使用 . 从 JavaScript 获取当前偏移量new Date().getTimezoneOffset()。(以分钟为单位,并且符号相反,因此您可能需要一些简单的数学运算。)将其与下拉列表中所选时区的当前偏移量进行比较。(您应该能够从您的服务器端代码中获得它。)

如果它们不匹配,则提醒您的用户。为此根本不需要 jsTimeZoneDetect。

于 2013-08-21T13:55:51.723 回答
-1

第一个选项:由 UTC 偏移量设置

  1. 获取 UTC 偏移量
  2. 在您的 ruby​​ 数组中搜索 UTC 偏移量。
  3. 通过 UTC 偏移量设置值,忽略名称。选择具有正确 UTC 偏移量的第一个时区。

为此的一些代码:

timezone = ActiveSupport::TimeZone.all.select { |tz| tz.utc_offset == my_offset }.first

第二个选项:将新时区添加到列表中

如果您知道 UTC 偏移量,请将newTimeZone 添加到列表中。请参阅文档

希望有帮助!

于 2013-08-21T11:32:56.940 回答