odoo 的时差问题

odoo 的时差问题

很多人掉进了odoo的时间坑
转贴并完善ubuntu时间设置:https://www.cnblogs.com/odoouse/p/5523275.html

odoo约定关于日期的数据,存放在数据库时,以 utc0 时区也就是不带时区存放,应用程序读取日期展示日期时,转换成用户的时区展示。用户的时区通过context传递。

odoo本身能很好的处理 这, 例如 每个模型都自带的 create_date / write_date

代码
odoo 的时差问题

它在处理这些的时候,会 使用 utc-0 时区 存数据库。

在 web client 以及 其他界面 展示这些日期 信息时, 能 根据用户的 时区, 例如 上海时区 【东8区】
odoo 的时差问题
如果用户的时区 切换到 其他, 例如 fiji [ utc-12 区] 与 上海时间 相差 4小时。
odoo 的时差问题

展示的时间 为 当地时间, 在上海时间基础上 加 4小时, 所以是 5/13 01:46
而订单存放数据库的 时间是 utc-0
odoo 的时差问题
但是 某些应用 在往数据库存 这些时间的时候, 有的没有处理好。

例如,stock picking 的字段 date_done是分拣完成时的日期,分拣完成时读取系统时间,此时本应该转换为 utc-0 并写入数据库作为 date_done… 的数据

但是 odoo sa的程序员在写这个逻辑的时候,并没有转换为utc-0

代码
self.write(cr, uid, [picking.id], {‘date_done’: time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)

time.strftime() 读取odoo服务器的当前时间【带时区】,如果服务器运行在 utc-8 ,则数据库存的日期也是 with utc-8,也就是下图示的前 2笔交易[ id = 15, 16]
odoo 的时差问题
这样,当用户从应用程序读取改数据时,在此数据基础上 +时差,变成了。
odoo 的时差问题
造成时差 8 小时

原因是

, odoo代码里面的相关日期处理是不正确的,没有遵循在存数据前去掉时区信息。

要解决这个问题, 2个 方式

1, 遵守约定,存数据库时使用 utc-0

例如 stock 有问题部分的代码修改,已经提交 PR [ https://github.com/odoo/odoo/pull/12063 ]

@@ -506,7 +506,7 @@ def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_pa

‘qty’: float_round(qty, precision_rounding=rounding),

‘cost’: price_unit,

‘history_ids’: [(4, move.id)],

  • ‘in_date’: datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
  • ‘in_date’: datetime.utcnow().strftime(DEFAULT_SERVER_DATETIME_FORMAT),

‘company_id’: move.company_id.id,

‘lot_id’: lot_id,

‘owner_id’: owner_id,

2, 使用workaround 解决此问题,那就是将 odoo 服务器的时区设置为 utc -0

使用 dpkg-reconfigure tzdata 设置时区

设置为 utc-0 之后的测试
odoo 的时差问题

服务器设置为 utc-0 之后, datetime.datetime.now() 和 datetime.datetime.utcnow() 以及 time 获取的时间都是不带时区信息,这样就能避免时差问题。

如何设置Ubuntu时间CST-8(北京时间):

Ubuntu修改系统时间
1 Ubuntu的时间分类
1.Ubuntu时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟。
2.查看系统时间:date -R
3.查看硬件时间: sudo hwclock --show
2 修改Ubuntu系统时间
2.1 修改时间
1. tzselect
2. 依次选择4->9->1->1 #Asia->China-> Beijing->yes
2.2 复制文件到/etc目录下
sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.3 查看修改结果
date -R
3 修改Ubuntu硬件时间
sudo date -s MM/DD/YY //修改日期
sudo date -s hh:mm:ss //修改时间
sudo hwclock --systohc //修改生效

如何设置Ubuntu时间为UTC-0:

可以用 sudo tzselect直接选择选择11
odoo 的时差问题
然后输入UTC-0
之后使用sudo vi /etc/localtime,把 CST-8 改为 UTC-0
再查看时间 date -R 和 sudo hwclock --show 就一致了。

参考:
https://www.cnblogs.com/EasonJim/p/8111902.html
https://www.jianshu.com/p/a6a6dde68b91
https://www.cnblogs.com/odoouse/p/5523275.html