Skip to content

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

@jvstme

Description

@jvstme

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions