ruby 此代码在转换日期和时间时是否有问题?

3pmvbmvn  于 12个月前  发布在  Ruby
关注(0)|答案(2)|浏览(108)
if picture[:latitude] && picture[:longitude]

  parsed_date_time = DateTime.rfc3339(picture[:picture_timestamp]).to_s(:db)
  timezone = Timezone.lookup(picture[:latitude], picture[:longitude])
  date_obj = ActiveSupport::TimeZone[timezone.name].parse(parsed_date_time)

  date_with_offset = DateTime.new(date_obj.year, date_obj.month, date_obj.day, date_obj.hour, date_obj.min, date_obj.sec, date_obj.zone).to_s

  @dailypost.picture_timestamp = Time.zone.parse(date_with_offset)
end

字符串
我有以下情况,客户端将照片的EXIF数据发送到服务器,而且任何日期(originalDateTime,dateTime或digitizedDateTime)都是以偏移量为零的rfc 3339格式发送的(例如:2017-20- 10 T12:50:30 + 00:00,为什么是这样而不是其他,另一个问题,我现在无法更改)。
(And当我得到一个偏移量为零的dateTime时,这仅仅是因为客户端将偏移量归零,同时简单地将偏移量为零的日期和时间连接起来。只是一个连接。这就是为什么我只是从rfc 3339解析日期和时间,然后我创建一个特定timeZone的dateTime对象)
在服务器端,我们根据坐标计算timeZone,创建一个具有所需偏移量的日期-时间对象,然后将此日期设置为服务器上的默认时区(中部夏令时),然后保存到数据库。我现在不能改变我们接收日期和保存到数据库的格式。进一步从数据库中,这个日期被取出,再次转换成rfc 3339格式,并发送到客户端。
我认为这里肯定有一些错误,日期和时间的转换,我现在看不到。问题是,我被告知有照片上传的日期错误。所有这些操作都有效吗?

ltqd579y

ltqd579y1#

将DateTime视为带有时间和时区的日期,通过执行DateTime.rfc3339(picture[:picture_timestamp]),您已经将rfc日期转换为带有时区的日期时间,如果EXIF返回所有带有+00:00的日期,则意味着它们是使用零偏移量注册的,这意味着时间是正确的,只是以其他时区显示,或者在最坏的情况下,它们没有注册。在这种情况下,您应该使用原始值创建新的DateTime并添加时区,在您的情况下

offset = ActiveSupport::TimeZone[timezone.name].formatted_offset
date_with_offset = DateTime.new(parsed_date_time.year, parsed_date_time.month, parsed_date_time.day, parsed_date_time.hour, parsed_date_time.min, parsed_date_time.sec, offset)

字符串
另一方面,rails将使用config/application.rb文件中应用程序的默认时区来显示和转换数据库中的日期,因此如果您的应用程序是在CDT中配置的,您只需将正确的datetime对象传递给数据库,rails将处理保存的转换,因为您的日期已经有了解析的时区,不用担心 (这将是不同的是你问用户的日期,并需要时区,使它的意义),根据数据库,这些将被处理为日期时间对象或整数时间戳,但很可能没有时区(+0)。对于向用户显示日期的部分,如果希望每个用户具有不同的时区,则应该在数据库中具有此字段,并在显示部分使用它,类似于Time.at(@dailypost.picture_timestamp).in_time_zone(current_user.timezone),其中Time.at是datetime since a timestamp (seconds since epoc) 和current_user.timezone是时区的名称,例如:'Sidney',或者如果您可以访问lat和lon,则可以像示例中那样计算时区。
参考文献:

iklwldmw

iklwldmw2#

将上面的代码提取到一个像def get_local_datetime(lat, lon, timestamp)这样的函数中,然后你就可以编写一个测试用例了。给定SantaClara的lat/lon和rfc 3339时间戳,你应该知道这个函数的输出-它匹配吗?
最后,rfc 3339是一个exif的东西。我也讨厌它。而且,有些相机输出它没有任何时区声明。它很糟糕。

相关问题