You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo考勤报表时区问题:打印时间多2小时及服务器时区转用户时区方法

解决Odoo考勤报表的时区问题

问题1:打印报表时时间多2小时

这个问题十有八九是因为报表模板直接读取了Odoo存储的UTC原始时间,没做用户时区转换。Odoo后台所有datetime类型字段都是以UTC存储的,UI界面会自动根据当前用户的时区设置转换显示,但报表模板如果没处理,就会直接输出UTC时间——刚好和你的用户时区差2小时(比如你所在时区是UTC+2)。

修复方法很简单,在你的QWeb报表模板里,给时间字段加上时区转换:

  • 推荐用format_datetime过滤器:
    <span t-esc="format_datetime(record.check_in, format='%Y-%m-%d %H:%M:%S', tz=user.tz)"/>
    <span t-esc="format_datetime(record.check_out, format='%Y-%m-%d %H:%M:%S', tz=user.tz)"/>
    
  • 或者用strftime配合时区参数:
    <span t-esc="record.check_in.strftime('%Y-%m-%d %H:%M:%S') if record.check_in else ''" t-options='{"tz": user.tz}'/>
    

如果你的报表是通过Python代码生成数据(比如在报表的.py文件里),也可以在数据处理阶段就转换时区:

from pytz import timezone

def get_report_values(self, docids, data=None):
    docs = self.env['hr.attendance'].browse(docids)
    user_tz = timezone(self.env.user.tz or 'UTC')
    attendance_records = []
    for rec in docs:
        converted_check_in = rec.check_in.astimezone(user_tz) if rec.check_in else None
        converted_check_out = rec.check_out.astimezone(user_tz) if rec.check_out else None
        attendance_records.append({
            'employee': rec.employee_id.name,
            'check_in': converted_check_in.strftime('%Y-%m-%d %H:%M:%S') if converted_check_in else '',
            'check_out': converted_check_out.strftime('%Y-%m-%d %H:%M:%S') if converted_check_out else '',
        })
    return {
        'doc_ids': docids,
        'doc_model': 'hr.attendance',
        'records': attendance_records,
        'user': self.env.user,
    }

问题2:报表中使用用户时区而非服务器时区

首先要明确:Odoo服务器的时区不建议修改(后台统一用UTC存储时间是最佳实践),正确的做法是在报表中对时间字段进行用户时区转换——上面的方法其实已经解决了这个问题。

额外要注意:确保每个用户都在个人偏好设置里正确配置了时区(路径:设置 > 偏好设置 > 时区)。如果用户没有设置,代码里要默认用UTC,避免出现转换错误。

另外,如果你是基于原生报表做的自定义,也可以检查下原生报表的时间处理逻辑,确保你的自定义代码没有覆盖掉时区转换的部分。

内容的提问来源于stack exchange,提问作者Mohamed Fouad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:50:19