You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Rails中如何将MongoDB ObjectID转时间戳?如何不使用getTimestamp()转MongoDB ID为日期?

嘿,这个问题我太熟了!MongoDB的ObjectID结构里,前4个字节本身就是文档创建时的Unix时间戳(秒级),所以咱们完全可以用Ruby/Rails的原生方法来解析,根本不需要依赖JavaScript的getTimestamp()。下面分两种场景给你具体实现:

1. 将MongoDB ObjectID转换为时间戳

不管你的ObjectID是字符串形式,还是Mongoid里的BSON::ObjectId实例,都能轻松拿到时间戳:

场景1:ObjectID是字符串

直接截取前8个十六进制字符(对应前4个字节),然后转成十进制整数就是Unix时间戳(秒级):

# 示例ObjectID字符串
object_id_str = "60d21b4667d0d8992e610c85"
# 截取前8位,转成16进制到十进制
timestamp = object_id_str[0..7].to_i(16)
# 输出结果:1624365894(对应2021-06-22左右的时间)

场景2:ObjectID是BSON::ObjectId实例

如果是Mongoid模型返回的_id(本身就是BSON::ObjectId对象),可以直接操作字节数组:

# 从字符串生成ObjectID实例(或者直接用模型的user._id)
object_id = BSON::ObjectId.from_string("60d21b4667d0d8992e610c85")
# 取前4个字节,转成大端序整数
timestamp = object_id.bytes[0..3].pack("C*").unpack1("N")
# 同样得到秒级时间戳:1624365894
2. 将MongoDB ObjectID转换为对应的日期

拿到时间戳之后,转日期就简单了,用Rails/Ruby的时间处理方法就行,还能轻松适配时区:

# 用本地时区生成Time对象
local_time = Time.at(timestamp)
# 用Rails配置的时区生成Time对象(推荐在Rails项目中用这个)
zone_time = Time.zone.at(timestamp)
# 转成DateTime对象
datetime = DateTime.strptime(timestamp.to_s, "%s")

也可以把两步合并,直接从ObjectID转日期:

object_id_str = "60d21b4667d0d8992e610c85"
created_at = Time.zone.at(object_id_str[0..7].to_i(16))
# 输出类似:Wed, 22 Jun 2021 15:24:54 UTC +00:00(根据你的时区配置变化)

小提醒

MongoDB ObjectID的时间戳只有秒级精度,没法拿到毫秒哦,这是它的结构决定的。

内容的提问来源于stack exchange,提问作者Jon Kern

火山引擎 最新活动