1、前言

最近一直在使用mongo数据库,前面文章也介绍了一直在做数据过期的事情,

mongo中的数据过期时间之前在程序中增加了一个字段

【Springboot系列】项目启动时怎么给mongo表加自动过期索引

之前看到时间字段没有时区的信息,没有关注,因为只要能定时过期就好了。

今天同事问我为什么我写入的数据没有时区,这个问题才去看

java MongoDB BsonDocumentCodec 中哪里处理了时区的 mongodb时区设置_线性代数

2、解决办法

2.1 给容器增加时区

想当然的以为是容器没加时区,所以导致的在程序中使用new Date()的时候没有时区

这里也介绍下怎么给容器增加时区

2.1.1 在容器启动时

将主机系统的时区映射到容器中。

具体来说,可以使用Docker run命令的 -v选项挂载主机的时区文件到容器中,并将其链接到容器的 /etc/localtime文件。例如,如果主机系统使用的是东八区时区(即北京时间),可以运行以下命令启动容器并设置时区:

docker run -it --name tyjt-mongo -m 10000M --memory-swap -1 -p 27017:27017 -v /home/data/mongo/db:/data/db -v /etc/localtime:/etc/localtime:ro --restart always -d mongo  --wiredTigerCacheSizeGB 2

其中 -v /etc/localtime:/etc/localtime:ro 表示将主机的 /etc/localtime 文件挂载到容器的 /etc/localtime 目录中,并使用只读模式。

-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \

启动容器后,可以通过在容器内运行 date 命令来验证时区是否已成功设置。

java MongoDB BsonDocumentCodec 中哪里处理了时区的 mongodb时区设置_mongodb_02

 和本地时间对了下,是一样的

2.1.2 在dockerfile中设置

大部分的时候我们都是自己开发的程序,在dockerfile中设置也很方便,毕竟脚本不是一直可以接触,自己能控制的就不求别人了

以在Dockerfile中使用 ENV 指令设置 TZ 变量,指定时区信息。例如:

FROM [base_image] ENV TZ=Asia/Shanghai

以上是以基础镜像的方式设置时区,如需快速设置时区可以使用第一种方法。

2.2 mongo中时间的原因

给容器加了时区以后发现还是没能解决问题,可真是麻烦,到底是什么原因呐,一查才发现

MongoDB 存储的日期数据类型是 ISODate 类型,它存储的时间是 UTC 标准时间。因此,在插入数据时,如果不指定时区,MongoDB 会将当前时间存储为 UTC 时间。

试了好几种方式都没解决时区问题

对于这种时间有几种方式处理

  • 如果在程序中加载,可以自己再转回时区,我这里只做定期删除,不需要读,无所谓
  • 如果是读的话可以转为时间戳long型或者格式化之后存入mongo

3、总结

mongo用了挺长一段时间了,日期这个字段类型用得不多,今天也算是学习了,