odoo时区修改方法-亲测有效

3,001 阅读4分钟

odoo中的时区问题一直以来是中国开发者比较纠结的问题,odoo框架默认使用的是UTC时间,所以导致使用datetime类型的字段时存入数据库的时间和实际的中国时间相差8小时(少了8小时),但在pc端展示的时候又时正常的东八区时间,这样就会导致在使用datetime类型时处理起来很麻烦,特别是提供接口给外部系统使用的时候,往往需要手动加8小时,假如我们在生成记录的时候都加8小时存库,就会导致odoo前台展示的时候多了8小时,网上有很多关于odoo时区贴子但都没有根本上解决时差问题,笔者经过一番探究和尝试解决了时差问题,有这方面困扰的开发者可以参照此篇文章总结的方法。

datetime源码探究

首先我们得知道为什么后台数据库存取utc时间,前台展示的确是东八区时间, test_date是我的测试字段,日期我手动选择的2021-02-09日,但今天是8号,不影响,主要关注时间

odoo前端时间展示(正常时间)

数据库utc时间(相差8小时)

猜测一定是odoo里面做了时差的增减,我们需要弄清原理,到底在哪些地方处理了时差这样我们才能针对性的改写,我们知道odoo里相应的类型都会有相应的widget做处理,那我们先找到此tree视图渲染时对datetime类型的字段做了什么,首先找到渲染tree视图的 web\static\src\js\views\list\list_renderer.js文件 定位到_renderBodyCell方法,此方法用于渲染tree视图的行,字段就包含在行中,通过debug我们发现datetime类型的字段在赋值的时候,调用了field_utils.format[field.type] 根据此线索我们找到了field_utils.js看一看里面究竟做了什么操作,通过源码不难发现,format一个包含各种字段类型及处理方法map映射,我们的datetime类型字段是由formatDateTime方法处理的 这里有个关于时差处理的关键方法session.getTZOffset(value) 在seesion.js里面有个getTZOffset方法返回了一个时差,我们尝试把这个返回值改为0看在创建一条记录看看是什么情况, 可以看到odoo前台展示的时间已经和数据一致了,说明odoo仅在前台展示的时进行时差的增减,前台将数据传到后台时候直接存库不处理时差

但是又有一个问题,create_date和write_date的时间还是utc时间,我们知道在odoo中这两个字段是每条记录的默认字段,那我们就需要找到创建这两个字段的源头一探究竟 在models.py源码中发现里面所有关于时间的字段处理都使用了utc时间,我们尝试将utc更换全局替换为Asia/Shanghai(东八区),再创建一条记录看看是什么情况,再次声明下test_date是我的测试字段,日期我手动选择的2021-02-09日,但今天是8号所以create_date和write_date都是2021-02-08日,不要被误导,觉得相差了一天,读者主要关注时间的变化,不要care日期 我们看到改了之后就是正常的东八区时间了,(相差了一分钟是因为先手动选择了测试字段,保存的时候间隔了大约一分钟)

总结

对于odoo的时差问题,读者可以参考我上面的方法,核心步骤3步,1-更改seesion.js的getTZOffset(value)方法时差改为0,2-将models.py里utc时间改为Asia/Shanghai,3-在odoo-bin启动文件中使用os.environ['TZ']将时区改为Asia/Shanghai,笔者在开发过程中发现如果不做任何设置odoo框架在导入datetime,time等时间处理模块时将使用操作系统时区