Skip to content

Preserve full resolution in GDAL API DataSource timestamps #82

@tkoschnick

Description

@tkoschnick

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

No one assigned

    Labels

    Django CoreThis idea is suitable for inclusion in Django itselfGeoDjango

    Type

    No type

    Projects

    Status

    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions