Skip to content

feat(ogc): accept date, datetime and Timestamp values in date arguments - #442

Open
bhaskargurram-ai wants to merge 1 commit into
DOI-USGS:mainfrom
bhaskargurram-ai:feat/ogc-dates-accept-datetime
Open

bhaskargurram-ai wants to merge 1 commit into
DOI-USGS:mainfrom
bhaskargurram-ai:feat/ogc-dates-accept-datetime

Conversation

@bhaskargurram-ai

Copy link
Copy Markdown
Contributor

Follow-up from #441, which noted that pd.Timestamp and datetime elements fail with AttributeError or TypeError.

Problem

A datetime.date, datetime.datetime or pandas.Timestamp passed to a date argument fails inside the formatter, and the error names no argument:

  • time=[pd.Timestamp("2024-01-01", tz="UTC"), None] and time=[date(2024, 1, 1), None] raise AttributeError: ... has no attribute 'endswith'
  • time=datetime(2024, 1, 1) raises TypeError: 'datetime.datetime' object is not iterable

time=[df.index.min(), None] is a natural call for a pandas user, and today it hits the first case.

Change

In dataretrieval/ogc/dates.py, these values are now read like the equivalent string:

  • An aware value is converted to UTC.
  • A naive value is read in the local zone, the same rule a naive string follows.
  • A date is midnight of that day.
  • NaT is an open bound, like None.
  • In date-only collections, the date part is used.

A lone value is treated as a single element, as a lone string already is. Any other type, for example a number, raises ValueError naming the argument and listing the accepted types (the minimum suggested in #441).

_format_one now delegates to a small _to_datetime helper, so each function stays under the complexity limit.

Tests

  • test_format_api_dates_accepts_date_and_datetime_objects: date, date pairs, aware Timestamp and datetime (an offset converted to UTC), NaT as an open bound, and mixed string and Timestamp ranges.
  • test_format_api_dates_reads_naive_objects_like_naive_strings: a naive datetime/Timestamp and its string spelling build the same filter, so this holds in any time zone.
  • test_format_api_dates_rejects_other_types_naming_the_argument
  • test_construct_api_requests_accepts_timestamp_bounds: request-level check that time=[Timestamp, None] produces time=2024-01-01%2F..

The full suite passes locally (1267 passed), including the new tests under TZ=UTC, America/Denver, Asia/Kolkata and America/Chicago. coverage report passes at 98.99%. ruff, mypy, lint-imports, xenon and complexipy are clean.

Open question

The public getter annotations still say str | list[str]. Should I widen them to include date objects in this PR, or leave that as a separate change?

A datetime.date, datetime.datetime or pandas.Timestamp passed to a date
argument (time=[df.index.min(), None]) failed inside the formatter with
AttributeError ('endswith') or, for a lone datetime, TypeError (not
iterable), naming no argument. Read them like the equivalent string:
aware values convert to UTC, naive ones use the local zone as naive
strings do, a date is midnight of that day, and NaT is an open bound.
Any other type raises ValueError naming the argument.

Follow-up named in DOI-USGS#441.
@bhaskargurram-ai

Copy link
Copy Markdown
Contributor Author

@thodson-usgs this picks up the non-string follow-up you listed in #441. I went with accepting date/datetime/Timestamp rather than only rejecting them, since time=[df.index.min(), None] is a common call; happy to cut it back to a clear ValueError if you prefer. The "start/end" string validation from the same list would be my next one, unless you'd rather keep it.

This branch has not been deployed

No deployments
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.

1 participant