How to make TimeField a time zone?

There are times when you need to collect time from a user without collecting an associated date. For example, if a user sets up a recurring event that runs every day at the same time. However, Django TimeField does not play with time zones. However, in this particular case (and probably at any time when you record time separately), the time zone is an important factor. So how do you keep the time corresponding to the time of the clock?

+6
source share
2 answers

The answer is no. For some time, in order to know about the time zone, it must have a date associated with it. Think about summer savings ... My solution for this was to use a DateTimeField on the model and override the form as follows:

 # 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() 
+4
source

This is untested and incomplete:

 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) 

This will use the Postgres' time with time zone data type. It will break if you pass it a line in the format "HH: MM: SS.mmmmmm + HH: MM", and with the help of auto_now will try to save the naive time (not sure if this causes an error).

Edit

An exception is thrown in the common base code if you try to insert a time with a time zone other than UTC.

change 2

I added an updated get_db_prep_value to convert the provided time with the time zone to a string, but it only works if the provided time zone outputs the offset utc (which may be ambiguous without a date).

It seems that time with time zone bit misleading ... As far as I can tell, in fact it stores time with a UTC offset and NOT a time zone. Thus, it would be difficult to take the return value, add the calendar date and return to the correct time relative to daylight saving time.

0
source

Source: https://habr.com/ru/post/957397/


All Articles