本地和服务器之间的UTC转换不同

时间:2018-08-01 22:38:28

标签: ruby-on-rails

我正在构建Rails 5应用程序。 在此应用程序中,我有一个查询,用于检查数据库中是否已存在事件。这可以在本地完美运行,但不能在服务器上运行。我所看到的问题是,我将要检查的日期转换为UTC,然后执行了查询。奇怪的是,在相同的日期,本地和服务器之间的转换输出是不同的。

这是查询

scope :available_holidays, -> (date) { where("events.starts_at > ? AND events.starts_at < ? AND ttype = ?", date.beginning_of_day, date.end_of_day, TYPE_NATIONAL) }

这就是我转换为UTC的方式

Time.parse(holiday[:date].to_s).utc

这是本地输出

2017-12-31 00:00:00

这是服务器上的输出

2018-01-01 00:00:00

这是我在控制器中的方法

def holidays
        output = []
        from = Date.civil(params["year"].to_i,1,1)
        to = Date.civil(params["year"].to_i,12,31)
        holidays = Holidays.between(from, to, params["country"])
        holidays.each do |holiday|
            date = Time.parse(holiday[:date].to_s).utc
            event = Event.available_holidays(date).count
            if event == 0
                output.push(holiday)
            end
        end
        render json: output.to_json
    end

出了什么问题?

1 个答案:

答案 0 :(得分:2)

我看到了许多可能的问题。

bind_rows
  • 为什么df1 <- data.frame( A1_01 = c(1, 0, 0, 1, 0, 1, 0, 1, 0, 0), A2_01 = c(1, 1, 1, 0, 1, 0, 0, 0, 0, 0), A3_02 = c(0, 0, 0, 1, 0, 1, 0, 1, 1, 0), L1_02 = c(1, 1, 1, 1, 1, 0, 0, 1, 1, 0), L2_02 = c(0, 0, 0, 1, 1, 1, 0, 1, 0, 0), age = rep(c("40-44", "45-49", "50-54", "55-59", "60-64"), 2), gender = c(rep("M", 5), rep("F", 5)), ID = c( "A12345", "A23456", "A34767", "A34567", "A45678", "A67891", "A78910", "A91011", "A10111", "A11121" ) ) df2 <- data.frame( A1_01 = c(1, 0, 0, 1, 0, 1, 0, 1, 0, 0), A2_01 = c(1, 1, 1, 0, 1, 0, 0, 0, 0, 0), A3_02 = c(0, 0, 0, 1, 0, 1, 0, 1, 1, 0), Z4_02 = c(1, 1, 1, 1, 1, 0, 0, 1, 1, 0), Z5_02 = c(0, 0, 0, 1, 1, 1, 0, 1, 0, 0), age = rep(c("40-44", "45-49", "50-54", "55-59", "60-64"), 2), gender = c(rep("M", 5), rep("F", 5)), ID = c( "Q12345", "Q23456", "Q34767", "Q34567", "Q45678", "Q67891", "Q78910", "Q91011", "Q10111", "Q11121" ) ) library(tidyverse) df_list <- list(df1, df2) cols <- reduce(df_list, .f = ~ intersect(colnames(.x), colnames(.y))) map_dfr(df_list, ~ .[cols]) #> A1_01 A2_01 A3_02 age gender ID #> 1 1 1 0 40-44 M A12345 #> 2 0 1 0 45-49 M A23456 #> 3 0 1 0 50-54 M A34767 #> 4 1 0 1 55-59 M A34567 #> 5 0 1 0 60-64 M A45678 #> 6 1 0 1 40-44 F A67891 #> 7 0 0 0 45-49 F A78910 #> 8 1 0 1 50-54 F A91011 #> 9 0 0 1 55-59 F A10111 #> 10 0 0 0 60-64 F A11121 #> 11 1 1 0 40-44 M Q12345 #> 12 0 1 0 45-49 M Q23456 #> 13 0 1 0 50-54 M Q34767 #> 14 1 0 1 55-59 M Q34567 #> 15 0 1 0 60-64 M Q45678 #> 16 1 0 1 40-44 F Q67891 #> 17 0 0 0 45-49 F Q78910 #> 18 1 0 1 50-54 F Q91011 #> 19 0 0 1 55-59 F Q10111 #> 20 0 0 0 60-64 F Q11121 bind_rows(df_list) #> A1_01 A2_01 A3_02 L1_02 L2_02 age gender ID Z4_02 Z5_02 #> 1 1 1 0 1 0 40-44 M A12345 NA NA #> 2 0 1 0 1 0 45-49 M A23456 NA NA #> 3 0 1 0 1 0 50-54 M A34767 NA NA #> 4 1 0 1 1 1 55-59 M A34567 NA NA #> 5 0 1 0 1 1 60-64 M A45678 NA NA #> 6 1 0 1 0 1 40-44 F A67891 NA NA #> 7 0 0 0 0 0 45-49 F A78910 NA NA #> 8 1 0 1 1 1 50-54 F A91011 NA NA #> 9 0 0 1 1 0 55-59 F A10111 NA NA #> 10 0 0 0 0 0 60-64 F A11121 NA NA #> 11 1 1 0 NA NA 40-44 M Q12345 1 0 #> 12 0 1 0 NA NA 45-49 M Q23456 1 0 #> 13 0 1 0 NA NA 50-54 M Q34767 1 0 #> 14 1 0 1 NA NA 55-59 M Q34567 1 1 #> 15 0 1 0 NA NA 60-64 M Q45678 1 1 #> 16 1 0 1 NA NA 40-44 F Q67891 0 1 #> 17 0 0 0 NA NA 45-49 F Q78910 0 0 #> 18 1 0 1 NA NA 50-54 F Q91011 1 1 #> 19 0 0 1 NA NA 55-59 F Q10111 1 0 #> 20 0 0 0 NA NA 60-64 F Q11121 0 0 返回哈希而不是对象?
  • 为什么holidays.each do |holiday| date = Time.parse(holiday[:date].to_s).utc 是字符串而不是Date对象?
  • 为什么日期Holidays.between解析?
  • 为什么时区与日期有关?

前两个是结构性问题。我认为后两个是真正的问题。日期没有时区。

例如,当您运行时,holiday[:date] Ruby将在该日期的午夜返回Time.parse,并带有一个时区。例如...

Time.parse("2018-05-06")

作为Time的{​​{1}},所以没有害处。但是如果你在+0100 ...

> Time.parse("2018-01-01")
=> 2018-01-01 00:00:00 -0800
> Time.parse("2018-01-01").utc
=> 2018-01-01 08:00:00 UTC

作为Date的{​​{1}}。

不要将日期转换为时间,也不能转换回日期。只需将它们保留为日期即可。

2018-01-01

更好的是,> Time.parse("2018-01-01 00:00:00 +0100").utc => 2017-12-31 23:00:00 UTC Date存储为2017-12-31对象。