dstack icon indicating copy to clipboard operation
dstack copied to clipboard

[Bug]: Time zone ignored in various API request fields

Open jvstme opened this issue 3 weeks ago • 0 comments

Steps to reproduce

This example demonstrates the problem using fleets, but it can also be reproduced with any prev_*_at request fields when listing other resources (events, instances, etc).

  1. Create two fleets.

    $ curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --request POST --data '{"spec": {"configuration": {"name": "fleet-1", "type": "fleet", "nodes": "0", "backends": []}, "profile": {}}}' http://localhost:3000/api/project/$PROJECT/fleets/create | jq
    $ curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --request POST --data '{"spec": {"configuration": {"name": "fleet-2", "type": "fleet", "nodes": "0", "backends": []}, "profile": {}}}' http://localhost:3000/api/project/$PROJECT/fleets/create | jq
    
  2. List the fleets.

    > curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --request POST --data '{"limit": 2}' http://localhost:3000/api/fleets/list | jq '[ .[] | {name, created_at} ]'
    [
      {
        "name": "fleet-2",
        "created_at": "2025-12-05T17:04:33.812462+00:00"
      },
      {
        "name": "fleet-1",
        "created_at": "2025-12-05T17:04:24.451853+00:00"
      }
    ]
    
  3. List only fleet-1 by setting prev_created_at to a timestamp that precedes fleet-2 creation timestamp.

    curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --request POST --data '{"limit": 1, "prev_created_at": "2025-12-05T17:04:30+00:00"}' http://localhost:3000/api/fleets/list | jq '[ .[] | {name, created_at} ]'
    [
      {
        "name": "fleet-1",
        "created_at": "2025-12-05T17:04:24.451853+00:00"
      }
    ]
    
  4. Try listing the same fleet by passing the same prev_created_at timestamp, but in a different time zone (e.g., 2025-12-05T17:04:30+00:00 -> 2025-12-05T18:04:30+01:00)

Actual behaviour

Returns an incorrect result:

> curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --request POST --data '{"limit": 1, "prev_created_at": "2025-12-05T18:04:30+01:00"}' http://localhost:3000/api/fleets/list | jq '[ .[] | {name, created_at} ]'
[
  {
    "name": "fleet-2",
    "created_at": "2025-12-05T17:04:33.812462+00:00"
  }
]

Expected behaviour

Returns the same result as step 3.

dstack version

master

Server logs


Additional information

The datetime values from the request are compared directly to NaiveDateTime fields. This requires coercing these values to NaiveDateTime, which leads to their time zone being lost. So the values are always interpreted as UTC, regardless of what time zone they actually specify.

Possible solutions:

  • Forbid specifying any time zone but UTC in requests.
  • Instead of ignoring the time zone, convert the value to UTC before comparisons (possibly right in NaiveDateTime.process_bind_param).

jvstme avatar Dec 05 '25 18:12 jvstme