-
Notifications
You must be signed in to change notification settings - Fork 0
Value Semantics
Read this before assigning to a field.
Pine's user-defined types are reference types. Everything on this page follows from that one fact, and it is the only way this library can end up holding a date its own constructor would have refused.
t.DateTime a = t.new_datetime(2025, 6, 15)
t.DateTime b = a
b.Month := 3 // a.Month is now 3 as well
This applies to every type here without exception: DateTime, Period,
Interval, Session and DstRule.
Two ways out:
-
.copy(), Pine's built-in shallow copy, when you want an independent record. - The withers, which copy for you and validate on the way through.
t.DateTime b = a.with_month(3) // a is untouched
Prefer the wither. It is shorter, and unlike a raw field assignment it cannot produce a record the constructor would have rejected.
Most fields accept every value their type can hold, and setting one on an instance you own is safe. These are the exceptions, because other functions read them as a promise:
DateTime: Year, Month, Day, Hour, Minute, Second, MS.
Together they have to name a real moment. Set Month to 2 on a 31st and the
record holds 31 February, a date new_datetime would have refused, and every
adjuster downstream inherits it.
t.DateTime d = t.new_datetime(2025, 1, 31)
d.Month := 2 // d is now 31 February
t.DateTime fixed = d.normalized() // 2025-02-28
normalized() repairs a day past the end of its month. It returns na if
something other than the day is out of range, because a Month of 13 is a typo
rather than an overflow.
Session: StartMin, EndMin, DayMask, and the break pair. Minutes must
be within a day, the mask must be 7 bits, and the break must be set as a pair
and ordered strictly inside the window. new_session enforces all of it. A
negative mask makes the weekday test meaningless rather than merely empty, and a
hand-set break can put a hole where the market actually trades.
Interval: FromMS must not exceed ToMS. new_interval orders them for
you.
Everything else is safe to set directly: DateTime.UTC, Session.Name, Tz
and Cal, and Period and DstRule in full. Session.EarlyClose is the odd
one, meaningful only alongside a Cal to read closes from, which is why
new_session refuses the flag on its own.
There is no derived weekday field to keep in sync. weekday() computes from the
calendar on every call and cannot go stale.
Pine's .new() takes named arguments and every field here has a default, so a
partly specified record needs no wrapper function and no long positional call:
t.Period.new(Months = 3) // three months, no years, no days
t.DstRule.new(StartMonth = 4, EndMonth = 9)
t.Interval.new(ToMS = ms)
DateTime is the exception. Prefer new_datetime, which validates the field
set as a whole, or try_new_datetime when the input is untrusted and you want
na instead of a raise.
In Pine this is a type error, not reference equality. Use the explicit methods:
-
equals()compares field by field. Available onDateTime,PeriodandInterval. -
same_instant()compares twoDateTimes by the moment they denote, so12:00+00:00and07:00-05:00are the same instant and are not equal records. -
compare(),is_before(),is_after()for ordering.
Previous: Civil and Exact Arithmetic · Next: Error Model · Reference: API-DateTime
std_time v1 · API Index · Task Index · Scope and Limitations · Verification
Calendar data current to the horizons on Versioning and Data Currency. Shanghai, Bombay and Singapore answer exactly through 2026.
MPL-2.0 · Copyright (c) 2026 Jesse Sanford · published on TradingView as The_Peaceful_Lizard
Start here
The model
- Core Concepts
- Civil and Exact Arithmetic
- Value Semantics
- Error Model
- Time Zones
- Exchange Calendars
- Trading Days and Day Counts
- Expiries
- Sessions
- Formatting and Parsing
- Choosing the Right Tool
- Pitfalls
Recipes
Reference
- API Index · Task Index
- DateTime
- Session
- Zone
- Exchange
- Period · Interval
- Weekday · Enums
- Free functions
- Glossary
The fine print