2014-02-25 71 views
6

基本上我有以下型号:Django的 - DateTimeField字段收到一个天真的日期时间

class Event(models.Model): 
    start = models.DateTimeField(default=0) 

,当我尝试使用datetime.datetime.strptime创建一个对象,我得到

Event.objects.create(start=datetime.datetime.strptime("02/03/2014 12:00 UTC", 
                 "%d/%m/%Y %H:%M %Z")) 

/usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py:903: 
RuntimeWarning: DateTimeField Event.start received a naive datetime (2014-03-02 
12:00:00) while time zone support is active. 

我已经经历了许多类似于此的帖子,但我无法弄清楚为什么它会给出错误事件,尽管我将UTC (%Z)论点放在了一起。

在此先感谢。

+0

我想你应该尝试禁用USE_TZ设置,然后试试这个。 – Anup

+0

可能重复[RuntimeWarning:DateTimeField收到一个天真的日期时间](http://stackoverflow.com/questions/18622007/runtimewarning-datetimefield-received-a-naive-datetime) –

回答

10

由于您正在使用时区并且您正在“手动”创建日期时间对象,因此会记录该警告。我也建议你通过添加打开警告插入错误:

import warnings 
warnings.filterwarnings('error', 
         r"DateTimeField .* received a naive datetime", 
         RuntimeWarning, r'django\.db\.models\.fields') 

settings.py,这样你可以更容易地发现这种违规行为。

老实说,我不知道为什么,但实际上你的日期似乎不知道(如果你使用timezone.is_aware()它应该返回false)。

要解决当前的代码,我建议你依靠的Django刺的时区:

from django.utils import timezone 
timezone.make_aware(yourdate, timezone.get_current_timezone()) 

对于我的项目,我创造了日期的实用工具类,因为我正面临着这样的问题,你可以去看看(尤其是对方法dateFromString):

class DateUtils(object): 

    @classmethod 
    def currentTimezoneDate(cls): 
     """ 
     Returns an aware datetime object based on current timezone. 

     :return: datetime: date 
     """ 
     return timezone.make_aware(datetime.now(), timezone.get_current_timezone()) 


    @classmethod 
    def currentTimezoneOffset(cls): 
     """ 
     Returns the offset (expressed in hours) between current timezone and UTC. 

     :return: int: offset 
     """ 
     offset = cls.currentTimezoneDate().utcoffset() 
     return int(offset.total_seconds()/60/60) 


    @classmethod 
    def UTCDate(cls, year, month, day, hour=0, minute=0, second=0, microsecond=0): 
     """ 
     Creates an aware UTC datetime object. 

     :return: datetime: date 
     """ 
     d = datetime(year, month, day, hour, minute, second, microsecond) 
     return timezone.make_aware(d, timezone.utc) 


    @classmethod 
    def asUTCDate(cls, date): 
     """ 
     Get the UTC version of the given date. 

     :param date: datetime: Date to be converted into UTC 
     :return: datetime UTC date 
     """ 
     if type(date) is Date: 
      return timezone.make_aware(datetime(date.year, date.month, date.day), timezone.utc) 
     if not timezone.is_aware(date): 
      return timezone.make_aware(date, timezone.utc) 
     return date.replace(tzinfo=timezone.utc) 


    @classmethod 
    def getJavaScriptDateFormatForCurrentLocale(cls): 
     """ 
     Return a date mask string that will be understood and used by JavaScript. 

     :return: str: Date mask string for JavaScript. 
     """ 
     f = get_format('SHORT_DATE_FORMAT') 
     return f.replace('Y', 'yyyy').replace('m', 'mm').replace('d', 'dd') 


    @classmethod 
    def getPythonDateFormatForCurrentLocale(cls): 
     """ 
     Return a date mask string that will be understood and used by Python. 

     :return: str: Date mask string for Python. 
     """ 
     f = get_format('SHORT_DATE_FORMAT') 
     return f.replace('Y', '%Y').replace('m', '%m').replace('d', '%d') 


    @classmethod 
    def dateFromString(cls, string, format=None, utc=True): 
     """ 
     Returns a datetime object from the given string. 

     :param string: str: A date string 
     :param format: str: The format of the date 
     :return: datetime: date 
     """ 
     date = datetime.strptime(string, format or cls.getPythonDateFormatForCurrentLocale()) 
     if utc: 
      return cls.asUTCDate(date) 
     return date 


    @classmethod 
    def getFormattedStringForCurrentLocale(cls, date): 
     """ 
     Return a date string formatted using current locale settings. 

     :param date: datetime: 
     :return: str: Formatted Date string. 
     """ 
     return date.strftime(cls.getPythonDateFormatForCurrentLocale()) 


    @classmethod 
    def randomDate(cls, start, end): 
     """ 
     Return a random date between the 2 dates provided. 
     See: http://stackoverflow.com/a/8170651/267719 

     :param start: datetime: Min date. 
     :param end: datetime: Max date. 
     :return: datetime: Random date in range. 
     """ 
     return start + timedelta(seconds=randint(0, int((end - start).total_seconds()))) 


    @classmethod 
    def hourRange(cls, fromHour, toHour): 
     n = fromHour 
     hRange = [fromHour] 
     while n != toHour: 
      n += 1 
      if n > 23: 
       n = 0 
      hRange.append(n) 
     hRange.pop() 
     return hRange 
1

你需要使用Django的make_aware()函数。

from django.utils import timezone 
#.... 

aware_date = timezone.make_aware(datetime.strptime("02/03/2014 12:00 UTC", "%d/%m/%Y %H:%M %Z"), \ 
            timezone.get_default_timezone()) 
相关问题