ruby-on-rails - 如何将 Rails DateTime 分辨率限制为微秒?
问题描述
Rails 支持DateTime
纳秒级的分辨率,但我注意到这取决于应用程序正在运行的机器。
在我运行 Mojave 的 MacBook 上,Time.zone.now.strftime("%N")
总是会输出一个以 , 结尾的 9 位数字000
(例如"122981000"
)。这意味着在 Mac 上,分辨率仅限于微秒级。
然而,在 Linux 上,相同的命令返回一个具有完整纳秒分辨率的数字(例如"113578523"
)。
我的问题是在我使用时出现的rspec
,我需要比较一些DateTime
值。
当我在我的 Mac 上开发时,测试完美地通过了,但是当我们的 CI (Travis) 运行相同的测试时,它会像这样失败:
expected: 2019-04-09 19:14:27.214939637 -0300
got: 2019-04-09 19:14:27.214939000 -0300
这里的问题是我们的数据库 Postgres 仅限于微秒,就像我的 Mac 一样,它不会失败。我将其存储DateTime
在数据库中,然后将其读回并与我在内存中的内容进行比较。DB 四舍五入到微秒,因此比较失败。
是否可以强制 Rails 使用微秒精度运行?
我的意图是不需要在每次测试中手动舍入或截断时间戳。
解决方案
我过去曾遇到过这种情况,其中新创建的 ActiveRecord 对象在内存中创建/更新的字段上将具有 9 位精度(在 Travis linux VM 上),这与存储在 Postgres 中的内容不同(6 位)。我遇到了同样的问题,这些测试在本地(macOS)通过但在 CI 构建中失败。
过去,我曾破解规范以强制重新加载对象,但正如您所强调的那样,这很丑陋,因为您必须为每次测试都这样做。最近我再次遇到了同样的问题,但这次我创建的服务对象无法“重新加载”,所以我开始尝试寻找更好的解决方案。
它并不完全理想,因为它需要猴子修补 Time 类,但是它可以工作!
module ForceTimePrecision
def now
super.round(6)
end
end
Time.singleton_class.send(:prepend, ForceTimePrecision)
修补 Time 单例的机制(因为我不能直接覆盖 Time.now)基于此答案https://stackoverflow.com/a/60665577/989981
推荐阅读
- c++ - 如何使用来自不同目录的make文件中的文件
- python - 如何从 Python 中的给定字符串中找到最大的数字?
- video - 什么时候应该在 amp-story 的 amp-video 上使用 layout="fill" 与 layout="responsive"?两者有什么区别?
- html - 圆圈内的图像,底部有框内容
- visual-studio - 每次更改分辨率时,Visual Studio 2017 工具箱中的 DLL 文件都会被删除
- sql - 如何在 SQL Server 中将表数据的值更改为“可用”?
- python - 使用 Chalice 时无法访问请求 json_body
- react-native - withNavigation 只能用于导航器的视图层次结构
- java - java socket发送压缩对象
- mongodb - 在 mongodb 中搜索日期