2013-11-05 34 views
6

İlişkilendirilmiş bir tarih almadan bir kullanıcıdan zaman toplamanız gerektiğinde bazı durumlar vardır. Örneğin, kullanıcı her gün aynı anda çalışan bir yinelenen etkinlik yapılandırıyorsa. Django'nun TimeField, zaman dilimi olsa da oynamıyor. Bununla birlikte, bu özel durumda (ve muhtemelen kendi başına bir zaman kaydettiğiniz zaman), saat dilimi önemli bir faktördür. Peki, bir saat dilimi farkında saatini nasıl saklıyorsunuz?TimeField saat dilimi farkında olunması nasıl sağlanır?

cevap

4

Cevap siz değilsiniz. Zaman diliminin bilinmesi gereken bir zaman için, onunla ilişkili bir tarihin olması gerekir.

# Model 
class MyModel(models.Model): 
    time_of_day = models.DateTimeField() 

# Form Fields 
from django.forms.util import from_current_timezone 
from django.forms.util import to_current_timezone 
from django.utils import timezone 

class TzAwareTimeField(forms.fields.TimeField): 
    def prepare_value(self, value): 
     if isinstance(value, datetime.datetime): 
      value = to_current_timezone(value).time() 
     return super(TzAwareTimeField, self).prepare_value(value) 

    def clean(self, value): 
     value = super(TzAwareTimeField, self).to_python(value) 
     dt = to_current_timezone(timezone.now()) 
     return dt.replace(
      hour=value.hour, minute=value.minute, 
      second=value.second, microsecond=value.microsecond) 


# Forms 
class MyForm(forms.ModelForm): 
    time_of_day = TzAwareTimeField() 
+3

Açılış ifadeniz (ve Django’nun davranışı), Python'un 'zaman' nesnelerini nasıl ele aldığıyla tutarlı değildir. Bir Python 'time' nesnesinde, tarihin başka bir yerde saklanması gibi, bazı durumlarda yararlı olan _is_ ile ilgili herhangi bir tarih içermeyen bir zaman dilimi-farkında olan' time' nesnesine izin veren bir 'tzinfo' alanı olabilir. Django'da bir 'Day' modelinde 'open_time' ve' close_time' 'TimeField' ile bu konuya yeni rastladım. Bu zamanlar ideal olarak zaman dilimi farkında olur, ancak Django bunu desteklemediği için olamaz. – jbg

+0

Bu eski, ancak yine de kullanışlıdır, bu yüzden, 'clean' yönteminin dönüş değerini 'from_current_timezone' şeklinde sarmanız gerektiğini düşünüyorum. –

0

Bu eksik denenmemiş ve:

class TimeFieldWithZone(TimeField): 
    def db_type(self, connection): 
     if (connection.settings_dict['ENGINE'] == 
      'django.db.backends.postgresql_psycopg2'): 
      return 'time with time zone' 
     raise Exception('Unsupported database type') 

    def get_db_prep_value(self, value, *args, **kwargs): 
     try: 
      return super(TimeFieldWithZone, self).get_db_prep_value(
       value, *args, **kwargs) 
     except ValueError: 
      return six.text_type(value) 

Bu kullanacaktır bunun için Çözümümün modeline bir DateTimeField kullanmak ve şöyle formu geçersiz kılmak için oldu ... Gün ışığından düşünün Postgres 'time with time zone veri türü. 'HH: MM: SS.mmmmmm + HH: MM' biçiminde bir dizgeyi geçirirseniz ve auto_now kullanarak bir naif zaman kaydetmeye çalışacaksınız (bu, bir hata atarsa).

Eğer UTC dışında bir saat dilimiyle bir süre ekleyerek deneyin eğer bir istisna atılır jenerik arka uç kodunda düzenleme

. 2

düzenleme Bir bir dizeye diliminin sahip, sağlanan time dönüştürmek için get_db_prep_value güncellenmiş eklendi, ancak sağlanan saat dilimi (bir tarihi olmayan belirsiz olabilir) bir UTC çıkışı sadece çalışır.

Görünüşe göre time with time zone biraz yanıltıcıdır ... Anlayabildiğim kadarıyla, aslında bir UTC ofseti ve bir saat dilimi ile bir zaman depolar. Bu yüzden, iade edilen değeri almak, takvim tarihi eklemek ve gün ışığından yararlanma saati ile ilgili uygun zamanı geri almak zor olurdu.

İlgili konular