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

Django写入MySQL时DateTime时区自动变更问题及解决方法

问题:Django向MySQL写入DateTime值时时区偏移

我的Django应用在向MySQL数据库写入DateTime值时会出现时区变更问题。添加新记录的方法如下:

def add_record(self, mdl, **kwargs):
    """add new data as new record in local db"""
    return mdl.objects.create(**kwargs)

传入的**kwargs包含:

'timestamp': 2020-09-17T17:50:14.304Z

写入数据库后,通过phpMyAdmin查看时,时间显示为上述值但带有-0400偏移。

MySQL全局时区为SYSTEM,对应服务器时区为'America/New York',数据库似乎默认使用此时区,即便我传入了带时区的时间。

注:我尝试将"Z"替换为"UTC"或"+00:00",但无法解决问题。

Django配置如下:

TIME_ZONE = 'UTC'
USE_TZ = True

注:我尝试将USE_TZ设为False,但问题仍未解决,且无法向数据库传递时区信息。

如何强制数据库保存正确的时区?


临时解决方案

无法让数据库以UTC时区存储时间,因此采用以下临时方案修改时间以匹配数据库默认时区,供参考。

注:需加载MySQL时区表才能生效。

添加记录后,使用以下函数修正时间:

def fix_timezone(self, tm, rid):
    sql = "UPDATE data_testdata SET timestamp=CONVERT_TZ('"
    sql += tm.replace("T", " ").replace("Z", "")
    sql += "', '+00:00', '" + DateTimeFunctions().get_mysql_timezone_offset() + "') "
    sql += "WHERE dataPointId=" + str(rid) + ";"
    cursor = connection.cursor()
    cursor.execute(sql)
    transaction.commit()

配套使用的工具类:

from django.db import connection
from datetime import datetime
from zoneinfo import ZoneInfo
from django.utils.dateformat import time_format

class DateTimeFunctions(object):
    """functions for manipulating dates, times, timezones, etc"""

    def __init__(self):
        pass

    def get_mysql_timezone_offset(self):
        """get the offset (+HH:MM) for the mysql timezone"""
        return self.get_timezone_offset_from_name(self.get_mysql_timezone_name())
    
    def get_mysql_timezone_name(self):
        """get the name default timezone for the datbase (session tz, or global tz if no session)"""
        cursor = connection.cursor()
        cursor.execute("SELECT @@global.time_zone, @@session.time_zone;")
        tzglobal, tzsession = cursor.fetchone()
        if tzsession == "" or tzsession is None:
            tz = tzglobal
        else:
            tz = tzglobal
        if tz == "SYSTEM":
            return self.get_mysql_system_timezone_name()
        else:
            return tz

    def get_mysql_system_timezone_name(self):
        """get the name of the mysql system timezone"""
        cursor = connection.cursor()
        cursor.execute("SELECT @@system_time_zone;")
        tzname = cursor.fetchone()
        return tzname[0]

    def get_timezone_offset_from_name(self, tznm):
        tdelta = datetime.now(ZoneInfo(tznm)).utcoffset()
        deltaseconds = tdelta.total_seconds()
        sign = "-" if deltaseconds < 0 else "+"
        deltahrs = str(abs(round(deltaseconds/(60*60))))
        if len(deltahrs) == 1: 
            deltahrs = "0" + deltahrs
        deltamin = str(round((deltaseconds % (60*60))))
        if len(deltamin) == 1:
            deltamin = "0" + deltamin
        return sign + deltahrs + ":" + deltamin

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:01:08