Pine Script Sessions and Time Zones: Exchange Time, IANA Zones and DST
Changing the chart clock to Tokyo does not make Pine hour values or time() use Tokyo time. Pine cannot read the chart timezone, and time functions use the symbol exchange timezone by default. A fixed UTC offset can also drift by one hour through DST. This guide does not recommend a trading session; it makes Pine’s bar classification reproducible.
Who this guide is for: Pine developers debugging shifted session trades, DST changes or timestamped Strategy Tester exports
Key points to understand first
- Record chart display time, exchange time and the explicit calculation timezone as separate assumptions.
time()tests a bar opening against a session;time_close()lets you inspect the closing boundary separately.- Audit time, days, overnight behavior, bar alignment and timeframe—not only the visible session label.
- Use an IANA identifier for a regional local-time session when DST and historical rule changes must be followed.
- Attach entry/exit timestamps, timezone, session string and day definition to files used for time-of-day analysis.
Display time and classification time can differ
- 01Chart timezone
Visual axis and labels
Not accessible to Pine - 02Exchange timezone
Symbol-local calendar and defaults
syminfo.timezone - 03Explicit IANA timezone
The session clock selected by the strategy
time(…, timezone)
DSTAmerica/New_York alternates between UTC−5 and UTC−4. A fixed UTC−4 string is not year-round New York time.
Every session specification needs an owner clock
“09:30–16:00” is incomplete. Add timezone, days, whether the opening or closing timestamp is tested, overnight behavior and the target timeframe. When timezone is omitted, time() and time_close() use the exchange timezone represented by syminfo.timezone by default.
| Clock | What it controls | Pine access | Common error |
|---|---|---|---|
| Chart timezone | Visible axis and labels | Not readable by scripts | Expecting a chart change to alter strategy logic |
| Exchange timezone | Default symbol-local calendar | Available as syminfo.timezone | Assuming local computer time is the default |
| Explicit timezone | The local clock used by a time/session call | Passed as a timezone argument | Treating a fixed UTC offset as a region |
Save chart timezone with screenshots and calculation timezone with strategy settings.
Choose time, time_close and calendar functions by job
| Component | Returns | Session-audit use | Caveat |
|---|---|---|---|
| time | Bar-open UNIX timestamp | Test opening membership | Timestamp is absolute; session inputs are interpreted in a timezone |
| time_close | Bar-close UNIX timestamp | Test the closing boundary | Can be na on some price-based charts |
| hour()/dayofweek() | Calendar values in a selected timezone | Logs, day gates and boundary labels | Bare variables use exchange time |
| syminfo.timezone | Exchange IANA identifier | Display and record the default clock | It is not the chart timezone |
| timenow | Current script execution time | Runtime metadata | It is not each historical bar time |
A timezone changes calendar interpretation, not the absolute meaning of a UNIX timestamp.
not na(time(timeframe.period, session, timezone)) is a common opening-membership test. If the bar must close inside as well, test time_close() separately. A one-hour bar opening at 15:30 and closing at 16:30 can open inside a 09:30–16:00 session but not be fully contained.
Decode time, days, overnight spans and bar alignment
A time-based session string follows the general form HHmm-HHmm:days. Day digits run from 1 for Sunday through 7 for Saturday; 23456 represents Monday through Friday. Multiple periods can be comma-separated. input.session() makes hours editable; a separate day input keeps the weekday assumption explicit.
| Example | Meaning | Boundary test |
|---|---|---|
| 0930-1600:23456 | Weekdays 09:30–16:00 in the selected timezone | Does the timeframe have a 09:30 bar? |
| 1700-1700:23456 | An overnight session from 17:00 to next 17:00 | Which trading day owns the overnight bars? |
| 0900-1130,1230-1500:23456 | Two periods around a midday break | Inspect 11:30 and 12:30 bars |
| 0000-0000:1234567 | 24 hours on all days | Symbol data can still contain closures |
Named exchange sessions and time-based session strings are different concepts.
When a session endpoint does not align with the chart timeframe, time functions can construct internal bars for the requested timeframe. Align endpoints to chart-bar boundaries when possible, or plot both opening and closing membership so the discrepancy is visible.
Use IANA identifiers for regional local time
UTC-4 is a fixed offset. America/New_York describes a region whose offset changes between UTC−4 and UTC−5 with daylight saving time. They coincide during part of the year but are not interchangeable.
| Specification | Follows DST | Best suited to | Risk |
|---|---|---|---|
| UTC/GMT offset | No | Research fixed to a UTC clock | Regional session drifts seasonally |
| IANA identifier | Yes | New York, London and other local clocks | Verify identifier and intended region |
| syminfo.timezone | Follows the exchange definition | Symbol-local exchange time | The clock changes when the symbol changes |
Official Pine guidance recommends IANA when local regional time and DST must align.
- Test the week before DST
Record the same weekday and local-hour membership.
- Test the transition week
Highlight bars where fixed UTC and IANA disagree.
- Test the week after
Recheck session endpoints and the first eligible entry.
- Switch exchange symbols
Confirm whether exchange or explicit regional time was intended.
| Probe | Ordinary week | Transition week | Decision |
|---|---|---|---|
| Before session start | Local time, UTC time, eligibility | The same three fields | Excluded before local start |
| At session start | First eligible bar | First eligible bar | Same local time under IANA |
| Before session end | Last open-inside bar | Same relative position | Explain any alignment difference |
| At session end | Open/close membership | Open/close membership | Same endpoint convention |
| Fixed-UTC control | Difference from IANA | Bars shifted by one hour | Audit detects the drift |
This is not a price or return comparison. It tests whether one local-session definition produces the same classification through the seasonal clock change.
Pair the same weekday, local time and chart timeframe in an ordinary week and the transition week. Store UNIX timestamp, exchange rendering, IANA rendering, fixed-UTC rendering and time/time_close results. Retain the fixed-offset version as a control that should drift by one hour so the test demonstrates that it can detect a DST defect.
Expose hours, days and the IANA zone as inputs
This educational strategy keeps hours, days and timezone separate and permits entries only when the bar opens in session. It closes an open position when the session ends. The moving-average cross is a mechanics test, not a recommended market or session.
//@version=6
strategy("IANA session filter audit", overlay = true,
initial_capital = 100000, margin_long = 100, margin_short = 100)
string hoursInput = input.session("0930-1600", "Session hours")
string daysInput = input.string("23456", "Session days",
options = ["23456", "1234567"])
string timezoneInput = input.string("America/New_York", "Session time zone",
options = ["America/New_York", "Europe/London", "Asia/Tokyo", "Etc/UTC"])
string sessionString = hoursInput + ":" + daysInput
bool opensInSession = not na(time(timeframe.period, sessionString, timezoneInput))
bool sessionEnded = not opensInSession and opensInSession[1]
float fast = ta.ema(close, 20)
float slow = ta.ema(close, 50)
bool longSignal = ta.crossover(fast, slow)
if opensInSession and longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long)
if sessionEnded and strategy.position_size != 0
strategy.close_all(comment = "Session end")
bgcolor(opensInSession ? color.new(color.teal, 88) : na)
plot(fast, "Fast", color.aqua)
plot(slow, "Slow", color.orange)Verify endpoint alignment, overnight behavior and price-based charts separately.
For an audit build, format the same bar timestamp in exchange time, Etc/UTC and the selected IANA zone in a table or Pine Log. This reveals display/classification confusion. Keep production drawings minimal while preserving the selected timezone in Inputs and documentation.
sessionEnded becomes true only when the script evaluates the first outside-session bar. strategy.close_all() then creates a market order during that calculation, while a standard simulated fill occurs at the next available tick. Preserve session endpoint, outside-bar open/close, order creation and fill as four timestamps. A process-on-close variant is a separate version and still does not guarantee a live broker fill at the endpoint.
Test bar-open and bar-close session membership separately
The mini calculator works on a simplified 24-hour clock and returns opening-endpoint and closing-endpoint membership separately. Those memberships do not prove which boundary was crossed or how many crossings occurred. Enter values after converting them to one local timezone; the calculator does not perform timezone or DST conversion.
duration = (end − start + 24) mod 24open offset = (bar open − start + 24) mod 24opens inside = open offset < durationbar close = (bar open + bar minutes ÷ 60) mod 24Declare whether start=end means a 24-hour session and use one consistent endpoint convention.- Does the first bar open exactly at the session start?
- Does the final bar close beyond the session end?
- Do equivalent local bars remain eligible across DST?
- Are overnight entries assigned to the intended trading day?
- Is an expected boundary bar missing because the market was closed?
Attach a session-boundary probe sheet to timestamped output
- Freeze the clock
Save session string, days, IANA timezone and chart timeframe.
- Visualize boundaries
Inspect session start/end, opening membership and closing membership.
- Test three DST periods
Compare the first and last eligible bars before, during and after transition.
- Export the trade list
Attach entry/exit timestamp and timezone notes to the CSV/XLSX.
- Analyze conditionally
Use session, weekday and time-of-day analysis only when timestamp granularity exists.
Do not stop at a boundary screenshot; retain a session-boundary probe sheet. On an ordinary date and a DST-transition week, capture bars immediately before the start, exactly at the start, immediately before the end and exactly at the end, including IANA zone, session string, weekday, open/close timestamps and time()/time_close() results.
Bind the probe sheet and trade CSV with one version ID. Keep chart timezone as display metadata, exchange timezone as Pine’s default clock and explicit IANA as the strategy-selected clock. A version that fails any boundary probe is not eligible for session-performance comparison.
| Stage | Required timestamp | Failure boundary |
|---|---|---|
| Bar classification | Bar open, bar close and timezone | Confusing open-inside with close-inside |
| Session transition | Last inside and first outside bars | Missing bars delay detection |
| Order creation | Calculation that calls strategy.close_all | Equating it with the endpoint |
| Simulated fill | List-of-Trades exit time and price | Position remains open to the next tick |
| Comparison premise | Process-on-close, timeframe and session string | Changing several fields in one run |
Correct classification does not guarantee an in-session exit fill. Pass bar membership and order lifecycle separately.
Reproduce three cases: an ordinary week, an overnight session and a DST-transition week. For each, freeze the last inside and first outside bars, then record endpoint membership, sessionEnded, close-order creation and actual fill. Change only timeframe next and verify that missing or misaligned boundary bars remain explainable. Keep runs with correct classification but delayed fills as exit-design failures.
Bar-open and bar-close membership
Use decimal hours expressed in one local timezone to test opening-endpoint and closing-endpoint membership separately; this does not count boundary crossings.
duration=(b−a+24)%24, using 24 when zero; openOffset=(c−a+24)%24; close=(c+d/60)%24; closeOffset=(close−a+24)%24. Each endpoint uses offset
Frequently asked questions
Does changing the chart timezone change Pine session logic?
Normally no. Chart timezone is a visual setting unavailable to Pine. Time functions without an explicit timezone use the exchange timezone by default.
Are UTC-4 and America/New_York equivalent?
Not year-round. UTC-4 is fixed. America/New_York changes between UTC-4 and UTC-5 with daylight saving time.
Can a bar open inside a session but close outside it?
Yes. time() tests the opening side. On long or misaligned timeframes, inspect time_close() too and distinguish opens-inside from fully-contained.
Why does a 2200-0200 session span two calendar dates?
It starts at 22:00 in the specified timezone and ends after midnight at 02:00. Do not rely on the chart date label alone; record the session-start date, weekday rule and, when useful, time_tradingday so trades map to the intended trading day.
How should I audit a DST date when local time appears to skip or repeat an hour?
Select bars on both sides of the transition with an IANA timezone and place UTC timestamp, local display, bar open/close and session membership in the same probe sheet. A discontinuous local label alone does not prove a missing bar or duplicate fill.
Primary sources and verification links
- TradingView Pine Script — TimeOfficial chart/exchange timezone, IANA, DST and time-function behavior.
- TradingView Pine Script — SessionsOfficial session strings, days, named sessions and membership tests.
- TradingView Pine Script — Times, dates and sessions FAQOfficial detection and boundary examples.
- TradingView Pine Script — Strategies FAQOfficial strategy date and time filtering example.
Edited and published by: SG Group · Editorial approach: We prioritize official TradingView Help Center and Pine Script documentation, then use exchange, regulator and other primary materials for market and product context. Features, data, pricing and connection terms change, so verify the current interface and linked sources before use.
Important notice: This article provides general education about TradingView interfaces, charts, alerts, screeners, paper trading and Pine Script. It is not investment advice, a trading signal, a recommendation of any instrument, data source or broker, or a guarantee of future price or profit. Features, pricing, data, exchange coverage, notifications, order integrations and Pine Script behavior vary by plan, region, connection and date and may change. Before risking money, verify current TradingView documentation and the terms of the relevant data source and connected provider, then rehearse the workflow with fictional data or paper trading.

