-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Code of Conduct
- I agree to follow Django's Code of Conduct
Feature Description
I would like to propose that timestamps of features imported through the GDAL API retain their full, sub-second resolution if present in the original data source input.
Problem
Given e.g. a GPX file with sub-second resolution on timestamps:
<trkpt lat="47.454540000" lon="8.573658000">
<ele>436.900</ele>
<time>2025-09-25T12:24:42.990Z</time>
</trkpt>
the DateTime field of the point feature is truncated to the next lower second:
>>> point
<django.contrib.gis.gdal.feature.Feature object at 0x7f99254b9190>
>>> point.get('time')
datetime.datetime(2025, 9, 25, 12, 24, 42)
>>> point['time']
<django.contrib.gis.gdal.field.OFTDateTime object at 0x7f99253212b0>
>>> point['time'].as_datetime()
(c_int(2025), c_int(9), c_int(25), c_int(12), c_int(24), c_int(42), c_int(100))
This leads to loss of information in the timestamp, and possibly to conflicting data points (several points with the same timestamp, but different locations).
Request or proposal
request
Additional Details
The GDAL API actually reads the full resolution on import; it is still available as the string representation of the feature:
>>> point['time'].as_string()
'2025/09/25 12:24:42.990+00'
While this could be parsed to get a the original timestamp, it is not in a standard (ISO) format, and the .get() and .as_datetime() methods feel more natural.
I originally filed a feature request ticket: https://code.djangoproject.com/ticket/36626 If the proposal gets picked up, maybe the ticket could be reopened and used to track it.
Implementation Suggestions
In the API, OGR_F_GetFieldAsDateTime() is used to return the datetime object:
https://gdal.org/en/stable/doxygen/ogr__api_8h.html#a47ca681bb6099eb8c18004d1f7112d95
GDAL also provides OGR_F_GetFieldAsDateTimeEx() that returns seconds as float with millisecond accuracy:
https://gdal.org/en/stable/doxygen/ogr__api_8h.html#a748995fa28574b25f6b723013a405a8f
Would it be possible and acceptable to add an optional parameter to .as_datetime(), e.g. with_milliseconds, defaulting to False to preserve backwards compatibility?
>>> point['time'].as_datetime(with_microseconds=True)
(c_int(2025), c_int(9), c_int(25), c_int(12), c_int(24), c_float(42.99), c_int(100))
Furthermore, would it be acceptable to return datetime objects with full resolution from the Feature's .get(fieldname) method and the Field's .value property? This doesn't change the returned type, just has the microsecond part of datetime set to the original value instead of 0, and fits well with the documented behaviour ("returns the value in the most appropriate form").
Metadata
Metadata
Assignees
Labels
Type
Projects
Status