Multiplying LTime in TIA Portal Overflow Limits and Safe Patterns

David Krause13 min read
SiemensTechnical ReferenceTIA Portal
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview: Why Multiply a Time Value?

Multiplying an LTime value is a recurring question in Siemens TIA Portal programming because the IEC 61131-3 LTime data type is fundamentally a 64-bit signed integer scaled to nanoseconds. Engineers frequently need to compute derived quantities such as:

  • Energy = average power × duration (scaling time-of-day or pulse-width totals)
  • Distance = velocity × elapsed time (motion tracking, conveyor length estimation)
  • Cost = rate per hour × runtime (machine operating cost dashboards)
  • Totalized throughput = flow rate × interval (batch reporting)

In every case, the conceptual operation is Duration × Rate, not Time × Time. The naive expression Result := LTime * LTime; in SCL (Structured Control Language) compiles and executes but produces numerically meaningless output whenever the operands exceed a few seconds, because the result exceeds the LINT representation range. This article documents the numeric limits, the exact overflow thresholds, the supported TIA Portal functions, and field-proven safe-coding patterns for any product that involves an LTime operand.

Engineering rule of thumb: If you find yourself typing LTime * LTime, you almost certainly want LTime * Real (or LReal * LTime) instead, with one operand converted to a numeric duration in seconds.

LTime Data Type: Numeric Foundation

The LTime data type is defined in IEC 61131-3 Third Edition and implemented by Siemens as a 64-bit signed integer with an implicit time base of one nanosecond. The TIA Portal online help describes the format as LTime#<numeric_value>d<h>m<s>ms<us>ns, where each suffix is optional and the underlying storage is always a LINT.

Attribute Value
Storage size 64 bits (8 bytes)
Base data type LINT (signed)
Time base 1 ns
Minimum value -9 223 372 036 854 775 808 ns ≈ -106,751 d 23 h 47 m 16.854 s
Maximum value +9 223 372 036 854 775 807 ns ≈ +106,751 d 23 h 47 m 16.854 s
Approximate range in days ±8.64 × 1013 ns/day → ±106,751 days ≈ ±292 years
First introduced (Siemens) S7-1500 CPU FW 1.0; S7-1200 CPU FW 4.2; TIA Portal V13 SP1
Display in watch table Date/time format or nanosecond integer

Compare this to the older TIME (32-bit) data type, which covers only ±2,147,483,647 ms ≈ ±24.8 days. The introduction of LTime was driven by long-duration batch timers, GPS-synchronized timestamping (with 100 ns precision per SIMATIC Time-of-Flight applications), and high-resolution motion profiles on the S7-1500 platform.

Overflow Math: When Does LTime * LTime Fail?

The numeric ceiling is the LINT maximum 9,223,372,036,854,775,807 ≈ 9.22 × 1018. To determine whether a multiplication overflows, compute the product of the two operand magnitudes and compare against this ceiling. Convenient reference points:

Operand A Operand B Product (ns²) Status
1 s = 109 ns 1 s 1018 Within range (≈ 10.85 % of max)
1 s 4 s 4 × 1018 Within range (≈ 43 %)
3 s 3 s 9 × 1018 Borderline overflow on signed multiply
10 s 10 s 1020 Overflow (10,000 % of max)
1 day 1 day 7.46 × 1027 Overflow by ~9 orders of magnitude
1 ms 1 s 1015 Safe (≈ 0.011 % of max)
1 ms 1 ms 1012 Safe
100 ms 100 ms 1016 Safe (≈ 0.1 % of max)
1 s 1 min 6 × 1019 Overflow

The threshold is roughly 3 s × 3 s = 9 s². Above that, the signed 64-bit product wraps and the CPU returns a result whose absolute value, sign, and interpretation are all undefined from an engineering standpoint. SCL does not raise an exception; the runtime silently stores a wrapped LINT and the HMI may display a negative or nonsensical duration.

Field observation: Operators often report "the timer reads -2147483648 s" or shows a date in 1969 after a year-end rollover. The root cause is almost always an unsigned/signed wrap from a multi-day product fed into a 32-bit TIME variable.

How the SCL Compiler Handles LTime × LTime

In TIA Portal V16 and later, the SCL compiler performs implicit type promotion according to the rules in the TIA Portal Help: "Type conversion of arithmetic expressions":

  1. If both operands are LTime, the compiler treats them as LINT and emits a signed 64-bit multiplication.
  2. The result type is LTime, but the underlying bits are raw LINT.
  3. No overflow check is inserted; the runtime simply writes the low 64 bits of the true mathematical product (modulo 264), then interprets the bits as a signed value if negative.

Equivalently, in TIA Portal:

// Compiles in SCL, but the result is meaningless for large operands
VAR
    a : LTime := LT#1d2h30m0s0ms0us0ns;
    b : LTime := LT#0d0h0m15s0ms0us0ns;
    r : LTime;
END_VAR

r := a * b;  // r overflows; expected ≈ 1.27e21, wraps to ≈ 4.3e18

Ladder logic (LAD) and Function Block Diagram (FBD) do not even expose a generic MUL block for LTime; the standard MUL instruction expects integer or real types. In graphic editors, you must first convert both operands to LINT using LTime_TO_LINT, multiply, and then convert back to LTime — at which point the wrap occurs identically.

Standard Library Functions That Touch LTime

The TIA Portal Standard Library / TIA Portal Help: "LTime — conversion functions" documents the supported conversions. The relevant ones for multiplication work:

Function From To Use
LREAL_TO_LTIME LReal (s) LTime (ns) Best entry point for product calculations
LTIME_TO_LREAL LTime (ns) LReal (s) Convert duration before multiplying
LTIME_TO_LINT LTime (ns) LINT (ns) Bit-level operations, hashing, modular math
DWORD_TO_LTIME DWORD LTime Legacy 32-bit time ingestion
LTIME_TO_STRING LTime String Display on HMI without overflow exposure
LTIME_TO_DINT / LREAL_TO LTime DInt / LReal Aggregation and trending

Note that there is no LTIME_MUL standard FB in the TIA Portal basic library. For motion applications, the S7-1500 Motion Control library (LBC) performs time × velocity calculations internally with LReal intermediates to avoid this exact overflow class.

Safe Multiplication Patterns

Pattern 1 — Convert Duration to LReal Seconds, Multiply, Convert Back

This is the canonical solution. The key insight is that the time dimension carries units (seconds, minutes, days), and once one operand is converted to a unitless LReal, the multiplication becomes an ordinary real-time product that never overflows LTime because the LReal intermediate absorbs the magnitude.

// "Total energy = power_kW * runtime_seconds"
FUNCTION_BLOCK FB_EnergyTotalizer
VAR
    nRatedPower_kW : LReal := 12.5;
    tRunTime       : LTime;
    tStartTime     : LTime;
    nEnergy_kWh    : LReal;
END_VAR

// Read current runtime from IEC_TIMER or user logic
tRunTime := tNow - tStartTime;

// Convert LTime (ns) to LReal seconds by dividing by 1.0e9
nEnergy_kWh := nRatedPower_kW * LTIME_TO_LREAL(tRunTime) / 3600.0;

No overflow occurs because the LReal intermediate is ~104932 in magnitude — essentially unlimited for process values. The maximum LReal in TIA Portal is approximately 1.7976931348623158 × 10308, far larger than any conceivable plant throughput.

Pattern 2 — Scale Inputs into a Safe Range Before Multiplying

When you specifically need the result expressed in nanoseconds (for instance, to feed an LTime tag that drives an HMI animation curve), scale the inputs first:

// "Cycle length = packets * packet_period_ns"
VAR
    nPackets     : LInt := 1200000000;   // 1.2 billion packets
    tPacketTime  : LTime := LT#0d0h0m0s1ms0us0us; // 1 ms = 1,000,000 ns
    tTotal       : LTime;
END_VAR

// Direct product would overflow (1.2e9 * 1e6 = 1.2e15 ns — still safe!)
// But to be defensive, reduce to LReal:
tTotal := LREAL_TO_LTIME(
              DINT_TO_LREAL(nPackets) *
              LTIME_TO_LREAL(tPacketTime) * 1.0e9);

The 1.0e9 converts the seconds intermediate back into nanoseconds for LREAL_TO_LTIME. Round-trip accuracy for values below 253 ns (≈ 104 days) is exact; above that, the IEEE-754 double begins to lose sub-nanosecond precision.

Pattern 3 — Use a Scale Factor and Integer Multiplication

If the operands are guaranteed small (for example, both below 100 ms), an LInt × LInt multiplication stays inside the safe zone, but never use it for arbitrary inputs:

VAR CONSTANT
    cSampleRate_ns : LInt := 100000; // 100 µs
END_VAR

VAR
    nSamples       : LInt := 50000;  // 5 seconds worth
    tWindow        : LTime;
END_VAR

tWindow := LINT_TO_LTIME(nSamples * cSampleRate_ns);  // 5e9 ns → safe
Boundary rule: If either operand may exceed 3 s in LTime units, do not multiply two LTime/LInt values directly. Switch to LReal intermediates.

Pattern 4 — Modular Products with Modular Reduction

For cyclic tasks where only the modulo-N product matters (for example, distributing pulses into a 24-hour window), apply the modulo early:

// Total running time mod 24 hours, so it never exceeds 86,400,000,000,000 ns
tInDay := LT#24h;
tModulo := tInDay;        // 8.64e13 ns
tElapsed := (tNow - tShiftStart) MOD tModulo;

Step-by-Step: Refactoring a Naive LTime × LTime Expression

  1. Identify the physical units of each operand. Write down seconds, minutes, or days for every input. If you cannot name a unit, the operand is not really a duration.
  2. Compute the order of magnitude of the product. Multiply the typical magnitudes. If it exceeds 1018, plan for an LReal intermediate.
  3. Convert the LTime operand to LReal seconds. Use LTIME_TO_LREAL. The resulting LReal is in seconds with 1 ns resolution (≈ 15 significant decimal digits).
  4. Perform the multiplication in LReal. Combine with the rate, scaling factor, or other operand in LReal arithmetic.
  5. Convert the LReal result back to LTime only if the output must be a duration. Use LREAL_TO_LTIME; remember this multiplies seconds by 109 internally.
  6. Add an overflow guard if the result drives a critical actuator. Compare the magnitude against LT#30d and clamp with a safe value.
  7. Verify in the PLCSIM or HMI watch table with boundary inputs: minimum, nominal, and ten times nominal. Confirm sign and magnitude are correct.

Verification: Unit Tests in PLCSIM

Before deploying any LTime multiplication logic, exercise the function block with deterministic inputs in S7-PLCSIM V17+:

Test Input A Input B Expected Result Status
Boundary low LT#1ns LT#1ns LT#1ns² interpretation → LT#0s Pass / convention
Nominal LT#500ms Rate 0.25 kW 0.125 Wh Pass with LReal
Just below overflow LT#2s LT#2s LT#4s (should be safe, but verify) Pass
Just above overflow LT#4s LT#4s Wrap → invalid Must use LReal pattern
1 day × 1 day LT#1d LT#1d Wrap → invalid Must use LReal pattern
1 ms × 1 hr (indirect) LT#1ms 3600000 ms rate 3600 s Pass with LReal

A useful PLCSIM trick is to monitor the raw LINT view of the result variable. Right-click the tag in the watch table and select "Display format → Hex / Decimal"; if the value flips between large positive and large negative jumps when input nudges by a small amount, the multiplication has wrapped and you have an overflow.

Comparison: LTime vs. TIME vs. DInt vs. LReal

Property TIME LTIME DINT LREAL
Bits 32 64 32 64
Signed Yes Yes Yes Yes (mantissa + exponent)
Range ±24.8 days (ms) ±292 years (ns) ±2.1 × 109 ±1.8 × 10308
Resolution 1 ms 1 ns 1 ≈ 15–17 digits
Used for multiplication? Rarely safe Only with small operands Common Preferred for derived quantities
HMI display d / h / m / s / ms d / h / m / s / ms / µs / ns Integer Floating point

Rule: if the result is a duration (something you would display on a clock or feed to a timer), the output type should be LTime; if the result is a quantity (energy, cost, distance, mass), the output should be LReal. Mixing the two roles is the most common source of LTime overflow bugs.

Diagnostic Checklist for LTime Multiplication Issues

Symptom Likely Cause Fix
Result negative after one positive multiply Signed wrap-around Convert to LReal, multiply, convert back
Result reads "0" for two nonzero operands Wrap to exactly 0 modulo 264 Same — overflow protection via LReal
Result in HMI shows date in 1969 / 2096 Wrapped LINT interpreted as nanoseconds from epoch Verify operand units; clamp with MAX_LTIME
PLC goes to STOP with SF LED Division by zero in LREAL_TO_LTIME Guard against zero operands
Watch table shows "????" or invalid value LTime display can't render >292 years Limit operand magnitude; use LReal output
SCL warning: "Operand of type LTime is not supported" Compiler cannot infer promotion (pre-V13 SP1) Upgrade TIA Portal to V16+ or upgrade CPU FW

Edge Cases and Field-Proven Caveats

  • Negative LTime operands. SCL allows LT#-1s for difference calculations. Multiplying two negative LTime operands produces a positive wrap; multiplying operands of opposite sign produces a negative wrap. Convert to LReal before sign-aware math, or use absolute values explicitly.
  • Subnormals and signed zero. LREAL_TO_LTIME of +0.0 returns LT#0ns; of -0.0 returns LT#0ns. There is no negative zero in LTime semantics.
  • PLC and HMI display rounding. WinCC Unified and Comfort Panels display LTime to the nearest microsecond on the screen. The actual tag resolution is 1 ns; expect a rounding difference of up to 500 ns in displayed values.
  • Cross-platform portability. LTime exists in IEC 61131-3 Third Edition and is supported in CODESYS 3.5 and Beckhoff TwinCAT 3, but the conversion functions use different names (DATE_AND_TIME_TO_LTIME vs. LTIME_FROM_DT). If you are porting blocks, audit every conversion.
  • Real-time clock read. RD_SYS_T on S7-1500 returns LTime measuring ns since 1970-01-01 UTC. The absolute magnitude is ~1.7 × 1018 ns — already near the upper edge of LTime. Never multiply two RD_SYS_T values together; the result will wrap.
  • Grounding / isolation: If your overflowed LTime is read by a safety program, ensure the safety FB clamps the value. SIL-rated function blocks should treat any out-of-range time input as a fault per IEC 61508 SIL 2/3 guidelines.

Alternative Controllers and Cross-References

  • Allen-Bradley / Rockwell: The equivalent is the 64-bit LINT tag with manual scaling (microseconds or nanoseconds), and multiplication is straightforward because Logix Designer does not reserve a dedicated "long time" data type. See Logix 5000 Controllers General Instructions Reference.
  • CODESYS 3.5 / Beckhoff: LTIME is identical semantically; the recommended pattern is the same: convert one operand to LREAL in seconds before multiplying. TwinCAT 3 uses TIME() and LTIME() conversion functions from the Tc2_Utilities library.
  • Schneider Electric EcoStruxure: Modicon M340/M580 lack a native LTime type; durations are stored as TOD (time of day) or DINT in milliseconds.

FAQ

Can I directly multiply two LTime tags in TIA Portal SCL?

Yes, the SCL compiler accepts Result := LTimeA * LTimeB;, but the result is a 64-bit signed product. Any operand pair whose product exceeds about 9.2 × 1018 ns² (roughly two values above 3 s each) will wrap and produce a meaningless LTime. For safety, convert one operand to LReal seconds first.

What is the exact maximum value of LTime in a Siemens S7-1500?

LTime is a 64-bit signed integer scaled to nanoseconds. The maximum value is 9,223,372,036,854,775,807 ns, equivalent to approximately 106,751 days, 23 hours, 47 minutes and 16.854 seconds (about 292 years). Anything larger wraps to a negative value.

Why does my LTime multiplication return a negative duration?

The product exceeded the LINT ceiling and the signed bit wrapped from positive to negative territory. Convert at least one operand to LReal (seconds), multiply, and only convert back to LTime if the output really must be a duration tag. Otherwise keep the result in LReal.

Which CPU firmware supports the LTime data type?

S7-1500 CPUs support LTime from firmware V1.0 (all current variants). S7-1200 CPUs support LTime from firmware V4.2 (initial support) and V4.4 (full standard library functions). TIA Portal V13 SP1 or later is required on the engineering side; V16+ is recommended for best type-conversion diagnostics.

How do I multiply an LTime by a flow rate or power value?

Convert the LTime to LReal seconds using LTIME_TO_LREAL(tDuration), then perform ordinary LReal multiplication with the rate. For example, nEnergy_kWh := nPower_kW * LTIME_TO_LREAL(tRuntime) / 3600.0;. Avoid converting back to LTime unless you are feeding a timer input.

Is there a standard FB in TIA Portal for safe LTime arithmetic?

No dedicated LTIME_MUL FB exists. The recommended practice is to use the inline LReal conversion pattern shown above. For high-volume motion applications, the LBC (Library of Basic Controls) motion blocks internally handle time × velocity scaling using LReal, which you can replicate in user code.

Can I read the result of a wrapped LTime product and recover the original value?

No. Once the product exceeds 263 ns², the low 64 bits of the true mathematical product are stored, and the high bits are lost. There is no hardware flag or status bit. You must prevent the overflow upstream by either constraining inputs or using an LReal intermediate.

Back to blog