考虑rails webapp和iCal中的夏令时

时间:2013-09-11 11:18:55

标签: ruby-on-rails utc dst icalendar

是的,这对我来说有点混乱,所以我将尝试从顶部解释!

我有一个rails web应用程序。它是一个内部公司应用程序,只会在英国使用。 该应用程序所做的一件事就是管理会议。 会议有一个日期&他们开始的时候。表格上有一个日期/时间选择器,允许用户选择日期和时间。会议的时间。我将这个日期保存到数据库中。所有会议持续2个小时,所以结束时间只是开始+ 2个小时。

示例:

2013-06-23 6:45PM in the form is stored in the db as 2013-06-23 18:45:00
2013-12-23 6.45pm in the form is stored in the db as 2013-12-23 18:45:00

请注意,第一个日期是夏令时(BST),第二个日期是GMT期间。我实际上并不关心它是GMT还是BST:绝对是在那个时候举行会议。

在rails webapp中,我只打印出确切的日期&来自DB的时间 - 当然很好地格式化了!

现在,在某些时候,我会向会议的组织者和他们会面的人发送电子邮件。这封电子邮件告诉他们日期&会议时间等,还包括一个iCal(.ics)文件,供他们放入(通常是Outlook,还有Apple或gmail)日历。

我遇到的问题是(使用上面的示例)Outlook会显示如下会议:

Meeting #1: Start: 23/06/2013 7:45pm, End: 23/06/2013 9:45pm
Meeting #2: Start: 23/12/2013 6:45pm, End: 23/12/2013 8:45pm

请注意,由于BST / GMT的原因,它已经调整了第一个。

.ics文件的文本包含以下代码:

会议#1:

BEGIN:VCALENDAR
...
DTEND:20130623T204500Z
DTSTART:20130623T184500Z
...
END:VCALENDAR

会议#2:

BEGIN:VCALENDAR
...
DTEND:20131223T204500Z
DTSTART:20131223T184500Z
...
END:VCALENDAR

所以我使用Z时区(UTC)编码日期/时间。我理解这就是为什么Outlook错误地将UTC时间转换为#1的BST时间并且单独留下#2(因为GMT == UTC)

我的问题是:如何阻止这种情况发生?我希望会议安排的时间是绝对的实际时间,无论GMT / BST:下午6:45

我应该在数据库中存储UTC的日期时间吗?如何做到这一点(我认为它将适用于所有日期,而不仅仅是满足开始日期)。当我在webapp中显示它们时,如何将它们重新转换回实际日期时间?

额外: 我的initializers / time_formats.rb中有一个条目,如下所示:

:ical => "%Y%m%dT%H%M00Z" 

所以日期就像“20130623T184500Z”。我在构建ics时使用它。我认为这是问题 - 如果日期/时间是在BST期间我不想使用Z,而是其他什么?

2 个答案:

答案 0 :(得分:0)

您的问题是您的日期/时间格式。你有:

DTSTART:20130623T184500Z

在.ics文件中,这对应于BST 19:45(英国夏令时为UTC + 1)。

你应该做一些事情。首先,您只需从日期末尾删除“Z”即可。这意味着时间继承了日历或底层应用程序的时区。

这将假设运行Outlook的计算机都在欧洲/伦敦时区。如果没有,或者您想要更安全一点,您还应该在BEGIN: VCALENDAR行之后指定以下内容:

X-WR-TIMEZONE:Europe/London

这指定了未明确指定的所有日期的默认时区。

最后,如果由于任何原因这不起作用,那么您需要明确定义日期时间。首先,您需要将欧洲/伦敦的时区定义添加到日历中。您需要的信息可在http://www.tzurl.org/zoneinfo-outlook/Europe/London.ics处获得。然后,您需要确保所有日期时间的格式为:

DTSTART;TZID=Europe/London:20130623T184500

最后一种方法是最好的,因为这意味着如果您的需求扩展到其他时区,您将能够相对轻松地处理它们。

答案 1 :(得分:0)

很抱歉自己回答这个问题,但是如果有人遇到这个问题,我发现的是我特定问题的原因。请注意,上述时区的答案也很有意义!

我的rails应用程序将UTC日期时间存储在数据库中(默认情况下) 但是,它还认为它自己的时区是UTC,这似乎也是默认值。

其结果实际上是存储本地日期,无论如何都是UTC。更改应用程序以确定它位于欧洲/伦敦,因此数据库中的日期现在都准确地为UTC(这意味着,如果我目前在BST,他们只有一小时的休息时间)

我现在可以在iCals中使用Z日期时间格式,而outlook和rails应用程序都将UTC日期转换回查看用户的语言环境的实际日期时间(目前每个人都在欧洲/伦敦)。这就是我想要的。