php mysql datetime时区,Django models通过DateTimeField保存到MySQL的时间的时区问题
最近開始使用Django開發一些系統,在models.py中設置一些數據庫表結構并給日期時間字段賦初值,不過在使用的過程中,遇到一點問題。問題是,我本來服務器使用的市區是“Asia/Shanghai”(+08:00),然后用datetime.now保存到數據庫中時,里面的時間總是比我的系統時間相差8小時(感覺是UTC時間),但是我也查看了MySQL數據庫中的時區是“+08:00”的(在MySQL中“SET GLOBAL time_zone = '+08:00';”語句可以設置時區)。這到底是什么原因呢?今天還花了不少時間來弄清楚這個問題。
我在models.py中定義的一個類如下(對于數據庫中一張表):
Python
class TestSuite(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=40, blank=True)
description = models.CharField(max_length=255, blank=True)
bu = models.CharField(max_length=40, blank=True)
is_enabled = models.BooleanField(default=True)
create_time = models.DateTimeField(default=datetime.now)
update_time = models.DateTimeField(default=datetime.now)
1
2
3
4
5
6
7
8
classTestSuite(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=40,blank=True)
description=models.CharField(max_length=255,blank=True)
bu=models.CharField(max_length=40,blank=True)
is_enabled=models.BooleanField(default=True)
create_time=models.DateTimeField(default=datetime.now)
update_time=models.DateTimeField(default=datetime.now)
這里的create_time和update_time存到數據庫中的時間總是UTC時區的時間(比北京時間慢了8個小時)。
Django還有一些warning打印出來:/Users/jay/workspace/te/env/lib/python2.7/site-packages/django/db/models/fields/__init__.py:903: RuntimeWarning: DateTimeField TestSuite.update_time received a naive datetime (2014-06-15 14:38:37.873873) while time zone support is active. RuntimeWarning)
這個warning的原因是,Django配置為使用timezone的datetime格式,而datetime.now是不包含timezone信息的。
如果不需要在程序中特別處理時區(timezone-aware),在Django項目的settings.py文件中,可以直接設置為“USE_TZ = False”就省心了。然后,在models.py中簡單的設置為“ create_time = models.DateTimeField(auto_now_add=True)”和“update_time = models.DateTimeField(auto_now=True)”。
如果還要保持USE_TZ=True,則可設置為“default=datetime.now().replace(tzinfo=utc)” 。
我還試圖去通過,django.utils.timezone.now()函數來獲取當前時間,我還以為settings.py中已經設置“TIME_ZONE = 'Asia/Shanghai'”,就可以得到正確的時區和時間;可惜它依然得到的是UTC的時間,翻看它的實現就一下明白了,如下:
Python
def now():
"""
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
"""
if settings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
return datetime.utcnow().replace(tzinfo=utc)
else:
return datetime.now()
1
2
3
4
5
6
7
8
9
defnow():
"""
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
"""
ifsettings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
returndatetime.utcnow().replace(tzinfo=utc)
else:
returndatetime.now()
另外,如果USE_TZ=True,那么設置auto_now_add=True(或auto_now=True)可以達到我的目的嗎?答案也是否定的,翻看了一下Django對auto_now_add=True的處理就明白了,它就是對其賦值為 django.utils.timezone.now() 。
還是試圖通過timezone來使用系統本地時間和時區,比如:default=timezone.localtime(timezone.now()) ,結果發現,也是不行的,存到MySQL中也是UTC時區的日期時間。得看下Django相應的實現代碼了,DateTimeField與MySQL數據庫交互的時候,是否都先轉換為UTC的時間再更新到數據庫的。
參考資料:
https://docs.djangoproject.com/en/1.4/ref/settings/#time-zone
https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#usage
總結
以上是生活随笔為你收集整理的php mysql datetime时区,Django models通过DateTimeField保存到MySQL的时间的时区问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 减肥能吃菠萝吗
- 下一篇: php获取某地的ip,php获取本土实际