Skip to main content

Timezone and Natural Time Units

This document describes TDengine timezone semantics and natural time unit behavior. Features are delivered across versions, marked inline:

MarkMeaning
(unmarked)Supported since v3.4.1
[v3.4.2]Supported since v3.4.2
[v3.4.3]Supported since v3.4.3 (not available in v3.4.2)

Timezone Overview

TDengine stores all time data internally as UTC timestamps (int64). Timezones only affect conversions between time strings and UTC: on writes, local time strings are converted to UTC; on reads, UTC is formatted back to local time strings for display.

Supported Timezone Formats

FormatExamplesDST awareDescription
IANA name'Asia/Shanghai', 'America/New_York'✅ Yes (automatic DST handling)Recommended. DST transitions are handled automatically.
POSIX fixed offset'+08:00', '-0500', 'Z', '+10', 'UTC+08:00'❌ No (constant offset)Supported range is -14:00 to +14:00. Entry points SET TIMEZONE, ALTER LOCAL, taos.cfg, TO_CHAR, and TIMETRUNCATE all follow POSIX sign convention (+ = west of UTC, i.e. local = UTC − offset). Exception: TO_ISO8601's fixed-offset parameter uses ISO 8601 sign convention. See "POSIX Fixed-Offset Format Details" below.

POSIX Fixed-Offset Format Details

TDengine's fixed-offset timezone format follows a subset of the POSIX TZ environment variable specification. The full POSIX specification defines the following format:

STD offset [ DST [ dstoffset ] [ , rule ] ]

where STD is the standard-time abbreviation, offset is the offset from UTC, DST and dstoffset define daylight saving time, and rule defines DST transition rules.

TDengine supported subset: TDengine only supports the STD offset portion, and STD only accepts UTC as its value. Manual configuration of DST, dstoffset, and rule is not supported. For DST support, use IANA timezone names. The accepted fixed-offset syntax is:

UTC offset

offset field format: offset represents the offset from UTC, in the format [+|-] hh [ : mm [ : ss ] ], where hh can be one or two digits, and mm and ss (if used) must be two digits. A compact form without colons is also accepted (e.g., +0800, -0530). The special value Z is equivalent to +00:00.

POSIX sign convention: The POSIX standard defines the relationship between local time and UTC as:

local_time = UTC - offset

Therefore: a positive + sign means west of UTC (western timezone, local time is behind UTC), and a negative - sign means east of UTC (eastern timezone, local time is ahead of UTC). This is the opposite of the ISO 8601 sign convention. For example:

NotationPOSIX meaningEquivalent IANA timezone
'+08:00' or 'UTC+08:00'8 hours west of UTCNear Pacific/Pitcairn (Pacific)
'-08:00' or 'UTC-08:00'8 hours east of UTCNear Asia/Shanghai (Beijing time)
'+05:30' or 'UTC+05:30'5.5 hours west of UTCNear America/Bogota (Colombia)
'-05:30' or 'UTC-05:30'5.5 hours east of UTCNear Asia/Kolkata (India)
'Z'UTC itselfEtc/UTC

When the UTC prefix is omitted (e.g., '+08:00'), TDengine still parses the offset using POSIX rules, identical to the prefixed form.

Supported range: The valid offset range is -14:00 to +14:00 (corresponding to 14 hours east of UTC to 14 hours west of UTC).

Difference from IANA timezones: POSIX fixed offsets contain no DST information and use a constant offset year-round. If the target region observes DST (e.g., US, Europe), use an IANA name for correct automatic DST transitions.

Timezone Priority

TDengine uses a five-level timezone priority model, where higher levels override lower levels:

PriorityLevelHow to setDescription
HighestSQL levelFunction timezone parameters (e.g., TO_ISO8601(ts, '+09:00')); TO_ISO8601 IANA parameters [v3.4.2]; stream TIMEZONE clause [v3.4.3]Affects only the current SQL statement or stream task
HighConnection levelC API taos_options_connection; SET TIMEZONE [v3.4.2]Affects all SQL statements on the current connection
MediumClient globaltimezone in client-side taos.cfgAffects only client-side local time formatting
LowServer globaltimezone in server-side taos.cfgFallback for server-side calculations when the connection timezone is unset
LowestSystem defaultAutomatically detected from the operating systemFinal fallback

Important: The client global timezone only affects client-side display (e.g., SELECT ts output formatting), not server-side calculations. Connections without a connection-level timezone fall back to the server global timezone for server-side calculations.

Set Timezone

SET TIMEZONE [v3.4.2]

Set the timezone for the current connection:

SET TIMEZONE 'Asia/Shanghai';
SET TIMEZONE '-08:00'; -- POSIX: local = UTC+8, same as Beijing time
SET TIMEZONE '+08:00'; -- POSIX: local = UTC-8, NOT Beijing time
SET TIMEZONE 'America/New_York';

The sign of fixed offsets follows the POSIX sign convention. See "POSIX Fixed-Offset Format Details" above.

After setting, the current connection uses this timezone for:

  • Timestamp column display (SELECT ts)
  • SELECT NOW() / SELECT NOW
  • Time-formatting functions such as TO_ISO8601(ts)
  • TODAY()
  • Natural-boundary calculations such as TIMETRUNCATE(..., 1d/1w/1n...) and INTERVAL

You can also set the timezone via C API taos_options_connection when establishing a connection, which has the same effect as SET TIMEZONE.

To use Beijing time on the current connection, the simplest approach is:

SET TIMEZONE 'Asia/Shanghai';

Query Current Timezone

SELECT TIMEZONE();

Returns the single effective timezone string for the current connection. The fallback chain is: connection-level SET TIMEZONE / C API value → client-global timezone snapshotted when the connection was created → system default timezone.

Configuration File

Configure the global timezone in taos.cfg:

timezone Asia/Shanghai
timezone UTC-8
timezone +08:00

Accepts IANA names, Windows standard timezone names (e.g., China Standard Time), and fixed-offset forms Z, ±HH, ±HHMM, ±HH:MM, UTC±H[:MM], UTC±HH[:MM]. GMT / GMT±... is not supported. If not configured, the timezone is detected from the operating system.

  • Server-side taos.cfg: used as the fallback for server-side calculations when the connection timezone is not set through SET TIMEZONE.
  • Client-side taos.cfg: affects only client-side local time formatting (e.g., SELECT ts output), not server-side calculations.

Note: Fixed-offset strings follow the POSIX sign convention (see "POSIX Fixed-Offset Format Details"). The sign meaning is consistent across all entry points (SET TIMEZONE, ALTER LOCAL, taos.cfg). Use IANA names to avoid confusion.

Differences between ALTER LOCAL 'timezone ...' and SET TIMEZONE ...:

  • SET TIMEZONE only affects the current connection. It is lost on reconnect.
  • ALTER LOCAL 'timezone ...' modifies the global config of the current client process. It only affects connections created after the change; existing connections are not affected.

First Day of Week

SET FIRST_DAY_OF_WEEK [v3.4.2]

Set the first day of the week for the current connection:

SET FIRST_DAY_OF_WEEK 0;  -- Sunday
SET FIRST_DAY_OF_WEEK 1; -- Monday (default)

Valid range is 0-6: 0=Sunday, 1=Monday, ..., 6=Saturday.

Query Current First Day of Week [v3.4.2]

SELECT FIRST_DAY_OF_WEEK();

Returns the current first-day-of-week setting for the connection as an integer 0..6, where 0=Sunday, 1=Monday, ..., 6=Saturday.

Configuration File [v3.4.2]

Configure in client-side taos.cfg:

firstDayOfWeek 4

Can also be changed dynamically within the current client process with ALTER LOCAL 'firstDayOfWeek' '<0..6>'. This only affects connections created after the change; existing connections keep their snapshot values.

The default value is 4 (Thursday), for backward compatibility with the historical Unix epoch modulo week alignment. If not explicitly configured, the client attempts to read the OS first-day-of-week setting at startup; if that fails, it falls back to 4.

To have weekly aggregations start on Monday:

SET FIRST_DAY_OF_WEEK 1;

For Sunday, set it to 0.

Scope of Effect [v3.4.2]

firstDayOfWeek affects all operations using w (week) as the time unit:

  • TIMETRUNCATE(ts, 1w) alignment day
  • INTERVAL(1w) window start day
  • PERIOD(1w) trigger day [v3.4.3]
  • SLIDING(1w) trigger day [v3.4.3]

Time Functions

TO_ISO8601

SELECT TO_ISO8601(ts) FROM t;                        -- uses connection timezone
SELECT TO_ISO8601(ts, '+09:00') FROM t; -- specified fixed offset (ISO 8601 sign)
SELECT TO_ISO8601(ts, 'UTC+09:00') FROM t; -- equivalent, 'UTC' prefix is stripped
SELECT TO_ISO8601(ts, 'America/New_York') FROM t; -- specified IANA timezone [v3.4.2]

Sign convention: TO_ISO8601 is the only entry point that uses the ISO 8601 sign convention — local = UTC + offset, meaning '+08:00' denotes east-8 (Beijing time). The following forms are fully equivalent: '+0800', '+08:00', 'UTC+8', 'UTC+0800', 'UTC+08:00'. All other entry points (SET TIMEZONE, taos.cfg, TO_CHAR, TIMETRUNCATE, etc.) use POSIX sign convention (+ = west).

When using an IANA timezone, the output offset varies automatically with DST:

SET TIMEZONE 'America/New_York';           -- [v3.4.2]
SELECT TO_ISO8601('2026-01-15 12:00:00'); -- ...T12:00:00-05:00 (EST, winter)
SELECT TO_ISO8601('2026-07-15 12:00:00'); -- ...T12:00:00-04:00 (EDT, summer)

TIMETRUNCATE

Truncate a timestamp to the specified unit boundary.

SELECT TIMETRUNCATE(ts, 1d) FROM t;                          -- truncate to 00:00:00 of the day
SELECT TIMETRUNCATE(ts, 1w) FROM t; -- truncate to first day of week 00:00:00
SELECT TIMETRUNCATE(ts, 1n) FROM t; -- truncate to 1st of month [v3.4.2]
SELECT TIMETRUNCATE(ts, 1q) FROM t; -- truncate to 1st of quarter [v3.4.2]
SELECT TIMETRUNCATE(ts, 1y) FROM t; -- truncate to Jan 1st [v3.4.2]
SELECT TIMETRUNCATE(ts, 1d, 'America/New_York') FROM t; -- specify timezone [v3.4.2]

Supported natural time units:

UnitMeaningTruncation ruleVersion
dDayAlign to 00:00:00 of the daySupported
wWeekAlign to 00:00:00 of the first day of week (determined by firstDayOfWeek)Supported; respects firstDayOfWeek since v3.4.2
nMonthAlign to 00:00:00 of the 1st of the monthv3.4.2
qQuarterAlign to 00:00:00 of the 1st month of the quarter (Q1=Jan, Q2=Apr, Q3=Jul, Q4=Oct)v3.4.2
yYearAlign to 00:00:00 of January 1stv3.4.2

Examples:

SELECT TIMETRUNCATE('2026-03-15', 1n);   -- 2026-03-01 00:00:00 [v3.4.2]
SELECT TIMETRUNCATE('2026-05-15', 1q); -- 2026-04-01 00:00:00 [v3.4.2]
SELECT TIMETRUNCATE('2026-08-15', 1y); -- 2026-01-01 00:00:00 [v3.4.2]

Third parameter (timezone):

ValueBehaviorVersion
0Use UTC (legacy)Supported
1Use connection timezone (legacy)Supported
'Asia/Shanghai'Use specified IANA timezonev3.4.2
'+08:00'Use specified fixed offsetv3.4.2
OmittedUse connection timezoneSupported

TIMEZONE()

SELECT TIMEZONE();

Returns the single timezone string currently in use by the connection.

  • If SET TIMEZONE has been executed, returns the connection-level timezone.
  • Otherwise, returns the client-global timezone snapshotted when the connection was created; if not configured, falls back to the system default.
  • ALTER LOCAL 'timezone' only affects connections created afterward; it does not change the TIMEZONE() result of existing connections.

To verify whether SET TIMEZONE has taken effect:

SELECT TIMEZONE();
SELECT TO_ISO8601(NOW());

Examples:

  • After SET TIMEZONE 'Asia/Shanghai', TIMEZONE() returns Asia/Shanghai.
  • Without SET TIMEZONE, returns the client-global timezone snapshotted at connection creation.
  • After ALTER LOCAL 'timezone Asia/Shanghai', existing connections are unaffected; only new connections use the new config.

INTERVAL Queries

INTERVAL supports natural time unit window splitting:

SELECT _wstart, COUNT(*) FROM meters
INTERVAL(1n) -- monthly windows [v3.4.2]
FILL(PREV);

SELECT _wstart, AVG(voltage) FROM meters
INTERVAL(1q) -- quarterly windows [v3.4.2]
FILL(NULL);

SELECT _wstart, SUM(energy) FROM meters
INTERVAL(1w) -- weekly windows (respects firstDayOfWeek) [v3.4.2]
FILL(LINEAR);

Supported natural time units:

UnitWindow boundaryVersion
dLocal timezone 00:00:00 each daySupported
wLocal timezone 00:00:00 on the first day of week (determined by firstDayOfWeek)v3.4.2
nLocal timezone 00:00:00 on the 1st of each monthv3.4.2
qLocal timezone 00:00:00 on the 1st of the first month of each quarterv3.4.2
yLocal timezone 00:00:00 on January 1st of each yearv3.4.2

Multi-interval windows:

INTERVAL(2q)   -- half-year window: [Jan, Jul), [Jul, next Jan) [v3.4.2]
INTERVAL(3n) -- quarterly window (equivalent to 1q): Jan/Apr/Jul/Oct [v3.4.2]
INTERVAL(2w) -- bi-weekly window [v3.4.2]

DST handling: Windows always align to local wall-clock time. On DST transition days, the physical duration of a window may change (e.g., a 1d window on spring-forward day is 23 hours). This is correct behavior.

Leap year / variable-length months: Window widths automatically adapt to actual day counts (e.g., a February window is 28 or 29 days). FILL boundaries advance month-by-month / quarter-by-quarter.

Stream Timezone

Stream TIMEZONE Clause [v3.4.3]

Before v3.4.3, stream trigger-side natural time boundary alignment always used the server global timezone, with no way to specify an independent timezone for individual stream tasks. Starting from v3.4.3, a TIMEZONE clause is available for all trigger types:

-- PERIOD trigger: Tokyo timezone, weekly
CREATE STREAM weekly_tokyo TRIGGER PERIOD(1w) TIMEZONE 'Asia/Tokyo'
INTO tokyo_weekly AS SELECT AVG(current) FROM meters;

-- SLIDING trigger: New York timezone, quarterly
CREATE STREAM slide_ny TRIGGER SLIDING(1q) TIMEZONE 'America/New_York'
FROM meters
INTO ny_quarterly AS SELECT _tprev_ts, _tcurrent_ts, AVG(current) FROM %%trows;

-- INTERVAL trigger: London timezone, monthly window
CREATE STREAM monthly_uk TRIGGER INTERVAL(1n) SLIDING(1w) TIMEZONE 'Europe/London'
FROM meters
INTO uk_monthly AS SELECT _wstart, _wend, AVG(current) FROM %%trows;

-- EVENT trigger: computation side uses Tokyo timezone
CREATE STREAM event_tokyo TRIGGER EVENT_WINDOW(START WITH voltage > 220 END WITH voltage <= 220)
TIMEZONE 'Asia/Tokyo'
FROM meters PARTITION BY tbname
INTO event_out AS SELECT _twstart, _twend, AVG(current) FROM %%trows;

Frozen behavior: TIMEZONE is frozen into stream metadata at creation time. Subsequent changes to the global timezone do not affect existing stream tasks.

When TIMEZONE is not specified: Resolved in order of connection timezone → server global timezone → OS timezone, then frozen.

Stream Timezone Effects

Affected areaDescription
Trigger side (PERIOD/SLIDING/INTERVAL)Calendar boundary alignment for natural units (d/w/n/q/y) uses the frozen timezone
Computation side (AS subquery)INTERVAL natural unit window splitting uses the frozen timezone and firstDayOfWeek

Stream Trigger Natural Unit Support

The following tables list supported time units for PERIOD, SLIDING, and INTERVAL trigger types along with their versions:

PERIOD trigger:

UnitMeaningVersion
aMillisecondSupported
sSecondSupported
mMinuteSupported
hHourSupported
dDaySupported
wWeekSupported
nMonthSupported
yYearSupported
qQuarterv3.4.3

Offset examples:

PERIOD(1w, 1d)       -- trigger every Tuesday 00:00:00
PERIOD(1n, 14d) -- trigger on the 15th of each month 00:00:00
PERIOD(1y, 31d) -- trigger on February 1st each year 00:00:00
PERIOD(1q) -- trigger on the 1st of each quarter 00:00:00 [v3.4.3]
PERIOD(1q, 15d) -- trigger on the 16th day of each quarter [v3.4.3]

SLIDING trigger:

UnitMeaningVersion
aMillisecondSupported
sSecondSupported
mMinuteSupported
hHourSupported
dDaySupported
wWeekSupported
nMonthv3.4.3
qQuarterv3.4.3
yYearv3.4.3
SLIDING(1n)          -- monthly sliding trigger [v3.4.3]
SLIDING(1q) -- quarterly sliding trigger [v3.4.3]
SLIDING(1y) -- yearly sliding trigger [v3.4.3]
SLIDING(1q, 15d) -- trigger on the 16th day of each quarter [v3.4.3]

INTERVAL window trigger (applies to both interval_val and sliding_val):

UnitMeaningVersion
aMillisecondSupported
sSecondSupported
mMinuteSupported
hHourSupported
dDayv3.4.3
wWeekv3.4.3
nMonthv3.4.3
qQuarterv3.4.3
yYearv3.4.3
INTERVAL(1n) SLIDING(1w)    -- monthly window, weekly sliding [v3.4.3]
INTERVAL(1q) SLIDING(1n) -- quarterly window, monthly sliding [v3.4.3]
INTERVAL(1y) SLIDING(1q) -- yearly window, quarterly sliding [v3.4.3]
INTERVAL(1w) SLIDING(1d) -- weekly window, daily sliding [v3.4.3]

View Stream Timezone [v3.4.3]

SELECT stream_name, timezone, first_day_of_week FROM information_schema.ins_streams;

Timezone Source Quick Reference

ScenarioTimezone sourceVersion notes
Write INSERTConnection → Server global → OSConverts time strings to UTC; supported
Read SELECT tsConnection → Client global → OSFormats UTC to local time; connection-level fallback supported since v3.4.2 (previously OS timezone only)
Functions (TO_ISO8601 etc.)SQL parameter → Connection → Server global → OSFixed-offset parameter supported; IANA parameter since v3.4.2
TIMETRUNCATESQL parameter → Connection → Server global → OSd/w supported; n/q/y since v3.4.2; timezone string parameter since v3.4.2
INTERVAL query windowsConnection → Server global → OSd supported; w/n/q/y since v3.4.2
SHOW / EXPLAINConnection → Client global → OSConnection-level fallback supported since v3.4.2 (previously OS timezone only)
Stream trigger and computationServer global → OS; [v3.4.3] supports TIMEZONE clause → Connection → Server global → OS (frozen at creation)Before v3.4.3 uses server timezone; v3.4.3 supports freezing

Configuration Parameters

ParameterConfig fileTypeDefaultDescriptionVersion
timezoneServer/client-side taos.cfgStringOS detectedGlobal timezoneSupported
firstDayOfWeekClient-side taos.cfgInteger 0-64 (Thursday)First day of week; can also be changed dynamically via ALTER LOCALv3.4.2

Error Messages

Error scenarioError message
Invalid timezone string[0x26B2] Invalid timezone: '<value>'
firstDayOfWeek out of range[0x26B3] Invalid firstDayOfWeek: <value>, must be 0-6

Version Support Matrix

FeatureBefore v3.4.2v3.4.2v3.4.3
timezone config file (server/client)
TO_ISO8601 fixed-offset parameter
TIMETRUNCATE d/w truncation
INTERVAL query d window
TIMEZONE() function✅ (enhanced)
PERIOD trigger a/s/m/h/d/w/n/y
SLIDING trigger a/s/m/h/d/w
INTERVAL window trigger a/s/m/h
SET TIMEZONE
SET FIRST_DAY_OF_WEEK
firstDayOfWeek config parameter
TO_ISO8601 IANA timezone parameter
TIMETRUNCATE timezone string parameter
TIMETRUNCATE n/q/y truncation
INTERVAL query w/n/q/y windows
Plain column reads use connection timezone
SHOW/EXPLAIN use connection timezone
Stream TIMEZONE clause
Stream timezone/firstDayOfWeek freezing
PERIOD trigger q quarter
SLIDING trigger n/q/y
INTERVAL window trigger d/w/n/q/y
ins_streams timezone/first_day_of_week columns