1

How can I set manually DateTimeField value given date and time ?

Here is my model and I am trying to assign date & time value to "created_at" field:

class Attendance(models.Model):
    employee = models.ForeignKey(Employee)
    company = models.ForeignKey(Company)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
​
    def __str__(self):
        return self.employee.username
​

Here is something I tried in the console:​ ​

> o = Attendance.objects.last()
> o.updated_at
datetime.datetime(2018, 6, 26, 0, 45, 31, 829827, tzinfo=<UTC>)
> x = datetime.strptime('17/07/2018 12:20', '%d/%m/%Y %H:%M')
> x
datetime.datetime(2018, 7, 17, 12, 20)
>o.updated_at = x
o.save()
>z = Attendance.objects.last()
>z.updated_at
datetime.datetime(2018, 7, 29, 12, 0, 13, 204815, tzinfo=<UTC>)

notice that I set "2018, 7, 17" but it appears "2018, 7, 29". is the assignment correct ? probably it needs the timezone as well.

Axil
  • 3,606
  • 10
  • 62
  • 136
  • Are you sure o and z are the same object? This code seems correct, but it may be that changing / saving the objects makes a different object respond to the 'Attendance.objects.last()'. – Dylan Brams Jul 29 '18 at 13:12
  • yes its same, in development on my local machine. i was told that auto_now_add could be a problem, should use default instead – Axil Jul 29 '18 at 13:13
  • You realize that your auto_now might be working and overriding your updated_at field, right? Since you're updating the updated_at field and getting a result of today, it seems that you're getting one of two possibly correct results depending on when the auto_now is applied. – Dylan Brams Jul 29 '18 at 13:15
  • oh didnt realize that, was testing on updated_at instead since i didnt want to touch created_at – Axil Jul 29 '18 at 13:16
  • Perhaps you could add an extra field to check the updated_at..... To me it looks like your code is working as written. – Dylan Brams Jul 29 '18 at 13:27
  • "Attendance.created_at received a naive datetime (2018-07-17 12:20:00) while time zone support is active." i seem to get this now, since removing the auto_now_add, how should i put in the time zone from x = datetime.strptime('17/07/2018 12:20', '%d/%m/%Y %H:%M') – Axil Jul 29 '18 at 13:38
  • my timezone is 'Asia/Kuala_Lumpur' – Axil Jul 29 '18 at 13:41
  • https://stackoverflow.com/questions/3305413/python-strptime-and-timezones gives some info. Basically you need to add an offset to the time zone. – Dylan Brams Jul 29 '18 at 13:50
  • instead of EST i tried putting Asia/Kuala_Lumpur for the timezone, doesnt seem to have an effect – Axil Jul 29 '18 at 14:07

2 Answers2

1

datetimes will always be stored in UTC if USE_TZ is True.

The only way around that is to set USE_TZ to False. auto_now uses django.utils.timezone.now(), which is defined to do the following:

If USE_TZ is False, this will be a naive datetime (i.e. a datetime without an associated timezone) that represents the current time in the system’s local timezone.

Converting time and storing it in DB is not a good method, So, convert the time whenever you need

JPG
  • 82,442
  • 19
  • 127
  • 206
0

So, if what you're trying to do is set the updated_at field to the current Asia/Kuala_Lumpur timezone, you want to generate the datetime.datetime(2018, 7, 29, 12, 0, 13, 204815, tzinfo=) with an appropriate tzinfo value.

This is a combination of the following two Stack Overflow answers:

Python strptime() and timezones?

Is there a list of Pytz Timezones?

Your resulting call will reference

Asia/Kuala_Lumpur

And the call will probably look like:

x = datetime.tzinfo("Asia/Kuala_Lumpur")
y = datetime.datetime(2018, 7, 29, 12, 0, 13, 204815, x)
Dylan Brams
  • 2,089
  • 1
  • 19
  • 36
  • it doesnt work. it has this error TypeError: tzinfo argument must be None or of a tzinfo subclass, not type 'str'. perhaps it should work something like this ? not sure. i event tried your code with "US/Pacific" – Axil Jul 29 '18 at 14:26
  • 1
    Worked with it a little in the console and I think that solves your issue. – Dylan Brams Jul 30 '18 at 07:44