如何使用 jQuery Datepicker 在 Rails 应用程序的 Ruby 中发送到服务器之前将时间转换为 UTC

How to convert time to UTC before sending to server in Ruby on Rails application using jQuery Datepicker

我最近在 Rails 接手了一个用 Ruby 编写的功能齐全的项目。报告了一个错误,我正在尝试解决但没有取得太大成功。

这是在 Haml 代码中调用的 CoffeeScript 代码:

$('#report-datetime-picker').daterangepicker({
    timePicker: true,
    timePicker12Hour: false,
    timePickerIncrement: 5,
    format: 'YYYY-MM-DD HH:mm'
  }, (start, end) ->
    # assign human readable string to input box
    # unix times are the real values sent to server.  datetime-text-field is just user frontend
    $('#datetime-start').val(start.unix())
    $('#datetime-end').val(end.unix())
    $('#datetime-text-field').val(start.format('YYYY-MM-DD HH:mm') + " - " + end.format('YYYY-MM-DD HH:mm'))
  )

和:

                %label#datetime-label{ for: 'datetime-text-field' } Date/Time Range
                .form-group
                    .input-group.date#report-datetime-picker
                        %span.input-group-addon.add-on
                            %i.fa.fa-calendar

                        %input.form-control#datetime-text-field{ type: 'text', value: @time_format }

                %input#datetime-start{ hidden: true, name: 'startTime', text: 'text', value: (@start_time.to_i rescue nil) }
                %input#datetime-end{ hidden: true, name: 'endTime', text: 'text', value: (@end_time.to_i rescue nil) }

                %button.btn{ type: 'submit' } Submit

问题是,当用户选择一个日期范围时,它会被转换为与用户当前系统时间相关的 UTC 等效时间。

例如东部时区的用户要拉取月度报告,因此选择“4/1/2020 0:00 - 4/30/2020 23:59”,则而是发送到服务器 4/1/2020 04:00 - 5/1/2020 03:59,导致月度报告错过 activity 的前四个小时,并错误地包括下个月 activity 的前四个小时。不能使用月份关系,因为时间范围不一定是月度报告,即使这是最常见的用例。

我检查了 application.rb 和 config.time_zone = 'UTC'。我还搜索了其余代码,所有时区引用均采用 UTC。

我还确认,如果东部时区的用户在日期选择器中选择“4/1/2020 00:00”,则实际存储在开始时间中的时间是4/1/2020 04:00, 而不是 4/1/2020 00:00.

由于查询工作正常但显示不正确,请尝试转换为普通 JS 日期对象而不是 .unix() 方法,然后在服务器上转换为 UTC

$('#datetime-start').val(start.toDate())
$('#datetime-end').val(end.toDate())

提交表单并将值发送到服务器时,它们应包含时区信息(例如Wednesday, April 8, 2020 11:11:50 AM GMT+01:00 DST

如果将其解析为日期对象服务器端,则可以使用 Time.parse 将其转换为 Time 对象,并使用 .utc() 将其从给定时区转换为 UTC .