Подтвердить что ты не робот

Rails: как анализировать строку даты и времени в определенный часовой пояс

Я использую Rails 3.2 и ruby ​​1.9.3 на Debian. У меня есть приложение, которое собирает дату, время и часовой пояс в виде строк через форму HTML. Что-то вроде этого:

start_date: "04-15-2010",
start_time: "10:00:00",
timezone: "Central Time (US & Canada)"

То, что я хотел бы сделать, - разобрать эти 3 элемента на одну дату, которая будет сохранена в моей базе данных в формате UTC, которая в этом случае добавит 7 часов к времени начала, как только она появится в часовом поясе UTC. Таким образом, сохраненное время будет 17:00, когда оно будет в БД, как UTC вместо полученного Центрального времени.

Я пробовал что-то вроде этого, чтобы проанализировать дату:

ActiveSupport::TimeZone[timezone].at DateTime.strptime("{ 2012-04-09 20:00:00 }", "{ %Y-%m-%d %H:%M:%S }").to_i

Однако я не могу включить часовой пояс в результирующее время с% Z. Он либо не анализирует, либо время интерпретируется как UTC, а не центральное время. Поэтому мой вопрос заключается в том, как принуждать строку даты к определенному часовому поясу без изменения значения фактической даты/времени. Я хотел бы иметь возможность анализировать строку в объект даты/времени, который включает в себя правильный часовой пояс с ним в то время, чтобы будущие преобразования часовых поясов были точными. Я все посмотрел и не могу найти способ сделать это. Странно, так как это похоже на то, что обычно происходит с датами, введенными из форм HTML. Спасибо за любую помощь.

4b9b3361

Ответ 1

%Z - это правильный способ указать имя часового пояса. Вы пробовали следующее?

date_and_time = '%m-%d-%Y %H:%M:%S %Z'
DateTime.strptime("04-15-2010 10:00:00 Central Time (US & Canada)",date_and_time)

Ответ 2

Попробуйте следующее:

zone = "Central Time (US & Canada)"  

ActiveSupport::TimeZone[zone].parse("2013-04-03 17:47:00")

Ответ 3

Я лично предпочитаю использовать String # in_time_zone:

>> '22.09.1986 10:30'.in_time_zone('Central Time (US & Canada)')
Mon, 22 Sep 1986 10:30:00 CDT -05:00

Ответ 4

Это метод, с которым я столкнулся. Не самый красивый, но он работает. Позволяет анализировать строку с использованием заданного формата и затем превращать ее в формат, который я знаю Time.zone.parse.

class ActiveSupport::TimeZone
  def strptime(time, format='%m/%d/%Y')
    formatted = Time.strptime(time, format).strftime('%Y-%m-%d %T')
    parse(formatted)
  end
end

Затем вы можете сделать что-то вроде того, что было упомянуто в другом вопросе, но с указанным форматом:

zone = "Central Time (US & Canada)"  
ActiveSupport::TimeZone[zone].strptime('2013-04-03', '%Y-%m-%d')

Или, если у вас уже установлен часовой пояс:

Time.zone = "Central Time (US & Canada)" 
Time.zone.strptime('01/13/2006')

Я использовал формат по умолчанию %m/%d/%Y, потому что это то, что мой пользовательский ввод в большинстве случаев. Вы можете настроить это для своих нужд или использовать формат DateTime по умолчанию, который, по-видимому, iso8601 (%FT%T%z)

Ответ 5

Чтобы DateTime взял строку даты и привязал часовой пояс, отличный от UTC, без изменения значений строки даты, используйте это, его легко, не ломается в високосный день:)

xx = DateTime.strptime("9/1/15 #{object.time_zone}", "%m/%d/%Y %Z")

Ответ 6

Наконец-то я нашел грязный, но окончательный способ сделать это.

Сначала проанализируем строку с использованием простого Ruby Time.strptime следующим образом:

time = Time.strptime('12 : 00 : PM', '%I : %M : %p')

Таким образом вы получите разобранное время, но еще не в правильном часовом поясе. Чтобы исправить это, позвольте преобразовать время в строчную форму и проанализировать ее с помощью стандартного ActiveSupport:: TimeZone # parse

Time.zone.parse(time.to_s)

В результате ActiveSupport:: TimeWithZone с нашим временем анализируется в правильном часовом поясе.

Причина, по которой мы должны это делать, заключается в том, что ни ActiveSupport:: TimeZone, ни ActiveSupport:: TimeWithZone не поддерживают метод strptime. Таким образом, мы должны разбирать Time с основным строком Ruby, который не имеет информации о часовом поясе, конвертирует его в формат, приемлемый в объектах ActiveSupport, а затем снова анализирует его.