Milvus
Zilliz
Home
  • User Guide
  • Home
  • Docs
  • User Guide

  • Schema & Data Fields

  • TIMESTAMPTZ Field

TIMESTAMPTZ FieldCompatible with Milvus 2.6.6+

Applications that track time across regions, such as e-commerce systems, collaboration tools, or distributed logging, need precise handling of timestamps with time zones. The TIMESTAMPTZ data type in Milvus provides this capability by storing timestamps with their associated time zone.

What is a TIMESTAMPTZ field?

A TIMESTAMPTZ field is a schema-defined data type (DataType.TIMESTAMPTZ) in Milvus that processes time zone-aware input and stores all time points internally as UTC absolute time:

  • Accepted input format: ISO 8601 strings with a time-zone offset (for example, "2025-05-01T23:59:59+08:00" represents 11:59:59 PM in UTC+08:00).

  • Internal storage: All TIMESTAMPTZ values are normalized and stored in Coordinated Universal Time (UTC).

  • Comparison and filtering: All filtering and ordering operations are performed in UTC, ensuring consistent and predictable results across different time zones.

  • You can set nullable=True for TIMESTAMPTZ fields to allow missing values.

  • You can specify a default timestamp value using the default_value attribute in ISO 8601 format.

See Nullable & Default for details.

Basic operations

The basic workflow of using a TIMESTAMPTZ field mirrors other scalar fields in Milvus: define the field → insert data → query/filter.

Step 1: Define a TIMESTAMPTZ field

To use a TIMESTAMPTZ field, explicitly define it in your collection schema when creating the collection. The following example demonstrates how to create a collection with a tsz field of type DataType.TIMESTAMPTZ.

import time
from pymilvus import MilvusClient, DataType
import datetime
import pytz

server_address = "http://localhost:19530"
collection_name = "timestamptz_test123"

client = MilvusClient(uri=server_address)

if client.has_collection(collection_name):
    client.drop_collection(collection_name)

schema = client.create_schema()
# Add a primary key field
schema.add_field("id", DataType.INT64, is_primary=True)
# Add a TIMESTAMPTZ field that allows null values
schema.add_field("tsz", DataType.TIMESTAMPTZ, nullable=True)
# Add a vector field
schema.add_field("vec", DataType.FLOAT_VECTOR, dim=4)

client.create_collection(collection_name, schema=schema, consistency_level="Session")
print(f"Collection '{collection_name}' with a TimestampTz field created successfully.")
// java
// nodejs
// go
# restful

Step 2: Insert data

Insert entities containing ISO 8601 strings with time zone offsets.

The example below inserts 8,193 rows of sample data into the collection. Each row includes:

  • a unique ID

  • a timezone-aware timestamp (Shanghai time)

  • a simple 4-dimensional vector

data_size = 8193

# Get the Asia/Shanghai time zone using the pytz library
# You can use any valid IANA time zone identifier such as:
#   "Asia/Tokyo", "America/New_York", "Europe/London", "UTC", etc.
# To view all available values:
#   import pytz; print(pytz.all_timezones)
# Reference:
#   IANA database – https://www.iana.org/time-zones
#   Wikipedia – https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
shanghai_tz = pytz.timezone("Asia/Shanghai")

data = [
    {
        "id": i + 1,
        "tsz": shanghai_tz.localize(
            datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(days=i)
        ).isoformat(),
        "vec": [float(i) / 10 for i in range(4)],
    }
    for i in range(data_size)
]

client.insert(collection_name, data)
print("Data inserted successfully.")
// java
// nodejs
// go
# restful

Step 3: Filtering operations

TIMESTAMPTZ supports scalar comparisons, interval arithmetic, and extraction of time components.

Before you can perform filtering operations on TIMESTAMPTZ fields, make sure:

  • You have created an index on each vector field.

  • The collection is loaded into memory.

Show example code

# Create index on vector field
index_params = client.prepare_index_params()
index_params.add_index(
    field_name="vec",
    index_type="AUTOINDEX",
    index_name="vec_index",
    metric_type="COSINE"
)
client.create_index(collection_name, index_params)
print("Index created successfully.")

# Load the collection
client.load_collection(collection_name)
print(f"Collection '{collection_name}' loaded successfully.")
// java
// nodejs
// go
# restful

Query with timestamp filtering

Use arithmetic operators like ==, !=, <, >, <=, >=. For a full list of arithmetic operators available in Milvus, refer to Arithmetic Operators.

The example below filters entities with timestamps (tsz) that are not equal to 2025-01-03T00:00:00+08:00:

# Query for entities where tsz is not equal to '2025-01-03T00:00:00+08:00'
expr = "tsz != ISO '2025-01-03T00:00:00+08:00'"

results = client.query(
    collection_name=collection_name,
    filter=expr,
    output_fields=["id", "tsz"],
    limit=10
)

print("Query result: ", results)

# Expected output:
# Query result:  data: ["{'id': 1, 'tsz': '2024-12-31T16:00:00Z'}", "{'id': 2, 'tsz': '2025-01-01T16:00:00Z'}", "{'id': 4, 'tsz': '2025-01-03T16:00:00Z'}", "{'id': 5, 'tsz': '2025-01-04T16:00:00Z'}", "{'id': 6, 'tsz': '2025-01-05T16:00:00Z'}", "{'id': 7, 'tsz': '2025-01-06T16:00:00Z'}", "{'id': 8, 'tsz': '2025-01-07T16:00:00Z'}", "{'id': 9, 'tsz': '2025-01-08T16:00:00Z'}", "{'id': 10, 'tsz': '2025-01-09T16:00:00Z'}", "{'id': 11, 'tsz': '2025-01-10T16:00:00Z'}"]
// java
// nodejs
// go
# restful

In the example above,

  • tsz is the TIMESTAMPTZ field name defined in the schema.

  • ISO '2025-01-03T00:00:00+08:00' is a timestamp literal in ISO 8601 format, including its time-zone offset.

  • != compares the field value against that literal. Other supported operators include ==, <, <=, >, and >=.

Interval operations

You can perform arithmetic on TIMESTAMPTZ fields using INTERVAL values in the ISO 8601 duration format. This allows you to add or subtract durations, such as days, hours, or minutes, from a timestamp when filtering data.

For example, the following query filters entities where the timestamp (tsz) plus zero days is not equal to 2025-01-03T00:00:00+08:00:

expr = "tsz + INTERVAL 'P0D' != ISO '2025-01-03T00:00:00+08:00'"

results = client.query(
    collection_name, 
    filter=expr, 
    output_fields=["id", "tsz"], 
    limit=10
)

print("Query result: ", results)

# Expected output:
# Query result:  data: ["{'id': 1, 'tsz': '2024-12-31T16:00:00Z'}", "{'id': 2, 'tsz': '2025-01-01T16:00:00Z'}", "{'id': 4, 'tsz': '2025-01-03T16:00:00Z'}", "{'id': 5, 'tsz': '2025-01-04T16:00:00Z'}", "{'id': 6, 'tsz': '2025-01-05T16:00:00Z'}", "{'id': 7, 'tsz': '2025-01-06T16:00:00Z'}", "{'id': 8, 'tsz': '2025-01-07T16:00:00Z'}", "{'id': 9, 'tsz': '2025-01-08T16:00:00Z'}", "{'id': 10, 'tsz': '2025-01-09T16:00:00Z'}", "{'id': 11, 'tsz': '2025-01-10T16:00:00Z'}"]
// java
// nodejs
// go
# restful

INTERVAL values follow the ISO 8601 duration syntax. For example:

  • P1D → 1 day

  • PT3H → 3 hours

  • P2DT6H → 2 days and 6 hours

You can use INTERVAL arithmetic directly in filter expressions, such as:

  • tsz + INTERVAL 'P3D' → Adds 3 days

  • tsz - INTERVAL 'PT2H' → Subtracts 2 hours

Search with timestamp filtering

You can combine TIMESTAMPTZ filtering with vector similarity search to narrow results by both time and similarity.

# Define a time-based filter expression
filter = "tsz > ISO '2025-01-05T00:00:00+08:00'"

res = client.search(
    collection_name=collection_name,             # Collection name
    data=[[0.1, 0.2, 0.3, 0.4]],                  # Query vector (must match collection's vector dim)
    limit=5,                                      # Max. number of results to return
    filter=filter,                                # Filter expression using TIMESTAMPTZ
    output_fields=["id", "tsz"],  # Fields to include in the search results
)

print("Search result: ", res)

# Expected output:
# Search result:  data: [[{'id': 10, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-09T16:00:00Z', 'id': 10}}, {'id': 9, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-08T16:00:00Z', 'id': 9}}, {'id': 8, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-07T16:00:00Z', 'id': 8}}, {'id': 7, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-06T16:00:00Z', 'id': 7}}, {'id': 6, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-05T16:00:00Z', 'id': 6}}]]
// java
// nodejs
// go
# restful

If your collection has two or more vector fields, you can perform hybrid search operations with timestamp filtering. For details, refer to Multi-Vector Hybrid Search.

Advanced usage

For advanced usage, you can manage time zones at different levels (e.g. database, collection, or query) or accelerate queries on TIMESTAMPTZ fields using indexes.

Manage time zones at different levels

You can control the time zone for TIMESTAMPTZ fields at the database, collection, or query/search level.

Level

Parameter

Scope

Priority

Database

timezone

Default for all collections in the database

Lowest

Collection

timezone

Overrides the database default time zone setting for that collection

Medium

Query/search/hybrid search

timezone

Temporary overrides for one specific operation

Highest

For step-by-step instructions and code samples, refer to the dedicated pages:

Accelerate queries

By default, queries on TIMESTAMPTZ fields without an index will perform a full scan of all rows, which can be slow on large datasets. To accelerate timestamp queries, create an STL_SORT index on your TIMESTAMPTZ field.

For details, refer to STL_SORT.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Was this page helpful?