Skip to content

Conversation

@trolldbois
Copy link

@trolldbois trolldbois commented Dec 26, 2025

  1. handle_datetimeoffset Fixes the datetime parsing of column type DATETIMEOFFSET. This updates Pull Add TimeZone support #140 that forgot to parse the timezone offset part of the type. This is a straightforward bugfix. (see Datetimeoffset support ? #136 )

  2. sqlserver_now Fixes Now(), to use timezone-aware SYSDATETIMEOFFSET(), to ensure a timezone aware (USE_TZ) django get a correct value for Now() when the database OS is not configured as UTC timezone.

This also fixes #371 .

This fixes the handling of the timezone part for a DATETIMEOFFSET type.
When USE_TZ=True, it's important that Now() reflect the current time, with timezone offset. If the database system OS is not using UTC , the SYSDATETIME() is a local-timezone value, which incorrectly CASTED as UTC (because offset = 00:00). This fix and the previous one allows to leverage the timezone part of SYSDATETIMEOFFSET() to ensure the timezone offset makes Now() the correct value.
@trolldbois
Copy link
Author

@microsoft-github-policy-service agree

@trolldbois trolldbois changed the title Updates TimeZone support for DATETIMEOFFSET type, fixes incorrect Now() in USE_TZ=True cases. FIX: Updates TimeZone support for DATETIMEOFFSET type, fixes incorrect Now() in USE_TZ=True cases. Dec 26, 2025
@trolldbois
Copy link
Author

trolldbois commented Dec 26, 2025

An explainer for fix 2. sqlserver_now
If you have a model that uses auto_now or auto_now_add the database value of that field will use the SQL server's Now() function. Using Now=SYSDATETIME() returns a timezone deficient value, with the database OS's local time (So lets say time in Africa/Nairobi +03:00).
But with settings.USE_TZ=True, django will parse this timezone-deficient value, and incorrectly replace the empty timezone offset (tzinfo) with the default django UTC offset (00:00) instead of the offset that the OS's system timezone used (+03:00).
So previous to this fix, all usage of Now(), for database OS not using UTC as system timezone, have stored a localtime, that is incorrectly parsed back by django as UTC. In this example, Now() would be parsed back by django as a datetime 3 hours in the future.
By using Now=SYSDATETIMEOFFSET(), we allow the storage of the timezone offset in DATETIMEOFFSET columns, whereas for DATETIME2 columns, the offset is truncated by sql server, and the value remains the same as SYSDATETIME().
With the addition of the handle_datetimeoffset bugfix, django will parse back a datetime with the correct timezone information, and now becomes the present, once again.

Notably, if your model still use a DATETIME2 column, and the Database timezone is not UTC, you will still experience a bug when using Now() or a model with auto_now, auto_now_add , unless you set your django database setting to the correct TIME_ZONE. But then you will experience other issues when USE_TZ=True . Logically, DATETIME2 is not compatible with USE_TZ=True when the SQL Server OS is using a timezone that is not UTC. See https://github.com/microsoft/mssql-django/wiki/Timezone-Support for migration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Datetime conversion issue with USE_TZ and settings.TIME_ZONE != 'UTC'?

1 participant