Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with Search datetime parameter parsing - blank start or end range and lowercase t or z #161

Closed
philvarner opened this issue Jun 18, 2021 · 4 comments
Assignees
Labels
spec Compliance with STAC/OGC specifications

Comments

@philvarner
Copy link
Collaborator

philvarner commented Jun 18, 2021

These issues were found on https://planetarycomputer.microsoft.com/api/stac/v1/ and locally running both the pgstac and sqlalchemy backends.

These datetime parameter values applied to /search should be accepted, but incorrectly return a 400:

Search with datetime=/1985-04-12T23:20:50.52Z returned status code 400
Search with datetime=1985-04-12T23:20:50.52Z/ returned status code 400

This is likely because only .. is accepted as an open ended interval, whereas blank string is also allowed per: "Open ranges in time intervals at the start or end are supported using a double-dot (..) or an empty string for the start/end." http://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_parameter_datetime

This datetime string gave a 400, likely because it uses t and z, which is acceptable.

Search with datetime=1985-04-12t23:20:50.000z returned status code 400

A large number of valid RFC3339 strings can be found here: https://github.com/stac-utils/stac-api-validator/blob/afb5a91ed6ce804d6b33fb304d6532dd4c50a227/stac_api_validator/validations.py#L38

@geospatial-jeff
Copy link
Collaborator

geospatial-jeff commented Jul 3, 2021

The new version of stac-pydantic will use pydantic's datetime parser, which still doesn't quite do the job:

from pydantic.datetime_parse import parse_datetime


dates = [
    "1985-04-12T23:20:50.52Z",
    "1985-04-12",
    "1937-01-01T12:00:27.87+0100",
    "37-01-01T12:00:27.87",
    "1985-12-12T23:20:50.52",
    "1985-04-12T23:20:50,Z"
]

for d in dates:
    try:
        parse_datetime(d)
    except:
        print("Invalid: ", d)
        continue
    print("Valid: ", d)

"Valid:  1985-04-12T23:20:50.52Z"
"Invalid:  1985-04-12" # date only
"Valid:  1937-01-01T12:00:27.87+0100" # timezone offset must have colon
"Invalid:  37-01-01T12:00:27.87" # 2 digit years not accepted
"Valid:  1985-12-12T23:20:50.52" # datetimes must have a timezone
"Invalid:  1985-04-12T23:20:50,Z" # must be at least one digit of fractional seconds

Looks like most of the cases that break are related to the timezone requirements:

  • a timezone offset must have a colon between the HH and MM
  • datetimes must have a timezone (Z or [+-]HH:MM)

I've been thinking about writing a small and generic python library for validating datetime objects against the stac spec, as none of the existing implementations (pydantic, dateutil, rfc3339-validator) seem to capture all of the edge cases.

@philvarner
Copy link
Collaborator Author

If you do, I have more details and what I think it a correct regex here radiantearth/stac-api-spec#162

@philvarner
Copy link
Collaborator Author

@geospatial-jeff I have a section in the STAC API spec now https://github.com/radiantearth/stac-api-spec/blob/master/implementation.md#datetime-parameter-handling

https://github.com/closeio/ciso8601 has a correct RFC3339 parser.

@philvarner philvarner changed the title Issues with Search datetime parameter parsing Issues with Search datetime parameter parsing - blank start or end range and lowercase t or z Jan 19, 2022
@philvarner philvarner added the spec Compliance with STAC/OGC specifications label Mar 1, 2022
@philvarner philvarner self-assigned this Mar 2, 2022
@geospatial-jeff
Copy link
Collaborator

closed with #368

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec Compliance with STAC/OGC specifications
Projects
None yet
Development

No branches or pull requests

2 participants