Troubleshooting V6 UTC Date/Time and Interval Errors

Patricia Callen8 min read
HMI / SCADAOther ManufacturerTroubleshooting
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

Store the event timestamp and calculate elapsed time in UTC, but display the elapsed result as a numeric duration or string rather than with the Web channel Time format. This separates the instant being recorded from the interval being measured and prevents the Web time-zone layer from adding the local UTC offset to a duration. Keep local time-zone conversion only at the presentation boundary for timestamps and chart labels.

How do the symptoms identify the failing layer?

Look at the trend first. Determine whether the stored timestamp is wrong, the elapsed calculation is wrong, or only the rendered value is wrong. The reported installation showed three distinct symptoms: Now() appeared three hours ahead of the expected wall clock, subtracting two date/time channel values produced an initial three-hour interval, and changing formulas between Now() and UtcNow() could produce a six-hour displayed difference or a countdown from six hours.

Those observations point to mixed time domains and a presentation conversion. A true elapsed interval at the event must be zero. If the raw numeric result is zero while a dynamic text object displays 03:00:00, the calculation is correct and the time formatter is treating zero duration as midnight UTC before converting it to local time. If the raw result itself is nonzero, the operands were captured or interpreted in different time bases.

Signal Source or operation Wrong-value symptom Diagnostic meaning
Current instant Now() Displayed time differs from the expected wall clock by three hours Local and UTC interpretation is crossing the server/Web boundary
Current UTC instant UtcNow() Appears as system local time in Web output The Web layer is applying its configured time zone to a date/time value
Saved event instant SetVal(2, UtcNow()) Changes continuously or does not represent the button press An input formula is recalculating a value that should be latched only by the command
Elapsed value Current UTC instant minus saved UTC instant Starts at three or six hours, or counts down The interval is being formatted as a clock time, the wrong channel is referenced, or the operands use different time bases
Chart start date startDate= in the chart request The previous day opens between local midnight and UTC midnight An empty date is being resolved as “today” in the wrong time domain

Why can zero elapsed time display as three hours?

A timestamp and an interval can share the same numeric storage type without sharing the same meaning. A date/time number represents a point on a calendar. Applying a date/time orTime display format to a duration tells the renderer to interpret that magnitude as a clock value.

The server in this configuration stores incoming time as UTC. The Web application applies its selected time zone when it renders values typed or formatted as date/time. When a zero-day interval is passed through that path, it can be treated as the UTC clock origin for the represented day and shifted by the local offset. A three-hour zone therefore makes a zero interval look like 03:00:00. The arithmetic did not create three hours; the renderer attached an offset to a value that was never a timestamp.

The same mechanism explains why switching expressions without tracing every operand can double the apparent error. UtcNow()-Now() compares values with different semantics, while the Web layer can then apply another conversion during display. Tuning formulas does not fix this type boundary. Measure the operands numerically and remove time formatting from the interval channel before changing offsets.

What should the signal chain look like?

The button command should latch one UTC event timestamp. A continuously evaluated calculation should compare the current UTC timestamp with that saved event timestamp. The final display should receive seconds or text, not a value marked as a time-of-day.

  1. Measurement: Read the current instant with UtcNow().
  2. Event capture: On the button command, write that instant once with SetVal(2, UtcNow()). Remove any input formula from the saved-event channel; continuous recalculation would destroy the latch.
  3. Controller calculation: Subtract the saved instant from the current instant on the server. Keep both operands in UTC.
  4. Engineering-unit conversion: Convert the resulting TimeSpan to total seconds, or multiply a raw day fraction by 86,400 when the expression engine returns a day-based numeric value.
  5. Final presentation: Show the numeric duration as seconds/minutes or convert it to a string. Do not assign the interval channel the Web Time format.

One supplied formula sequence writes channel 2 but later proposes UtcNow() - Val(1). That channel reference is ambiguous. The subtraction must reference the channel that actually holds the latched event time; with the stated command, that is channel 2. A separate current-time channel is unnecessary unless another object must display it.

How do you implement a duration that Web will not shift?

The direct method stores elapsed seconds as a number. The script below converts two channel values from OLE Automation date representation, subtracts them as DateTime values, and returns whole total seconds:

public double TsTotalSec(int cnl1, int cnl2)
{
    DateTime date1 = DateTime.FromOADate(Val(cnl1));
    DateTime date2 = DateTime.FromOADate(Val(cnl2));
    TimeSpan interval = date1 - date2;
    return (long)interval.TotalSeconds;
}

Call it from the elapsed channel with the two channels that contain the current and saved timestamps:

TsTotalSec(1, 2)

If channel 1 is removed, replace its argument with the actual channel or expression that supplies the current UTC instant. Preserve operand order: current minus saved produces an increasing positive duration; reversing the operands produces a negative value that decreases.

For a dynamic text object, convert the seconds to a TimeSpan string:

public string TsFromSeconds(double Sec)
{
    return TimeSpan.FromSeconds(Sec).ToString();
}

The proposed display formula is:

SplitAscii(()=> TsFromSeconds(Val(3)))

Configure the destination as ASCII String with String format. With data length 3, the string occupies channels 4, 5, and 6. TimeSpan.ToString() may include fractional seconds when the duration contains them, so inspect the rendered text rather than assuming a fixed field width.

TimeSpan does not provide the proposed ToOADate() conversion. That correction matters because an interval should not be forced back into a calendar-date encoding. Store TotalSeconds as the transport value and apply string formatting only at the display.

How should the procedure be commissioned?

  1. Remove the continuously evaluated input formula from the event-time channel. A button press must be the only operation that updates the saved timestamp.
  2. Use SetVal(2, UtcNow()) as the button output formula when channel 2 is the event-time channel.
  3. Read the saved channel immediately after pressing the button. Confirm that its raw numeric value remains fixed while the current UTC value advances.
  4. Calculate current UTC minus the saved UTC value. If the expression engine returns a fraction of a day, display that raw number temporarily; zero at the event confirms correct arithmetic.
  5. Convert the day fraction to seconds with seconds = day_fraction * 86400, or use TsTotalSec to obtain TotalSeconds directly.
  6. Configure the elapsed channel as an ordinary numeric value. Remove the Time format from that channel.
  7. If the operator needs a clock-like duration, feed the seconds to TsFromSeconds and display the resulting ASCII string.
  8. Retain the configured local time zone for actual event timestamps and charts. Do not move the whole Web application to UTC merely to correct one interval display.

How do you verify the correction?

Press the button and observe raw values before formatted objects. The saved UTC timestamp must change once. The elapsed numeric channel must start at zero or within the scan/update latency and then increase monotonically. A second button press must replace the saved timestamp and return the elapsed value to zero.

Compare the elapsed channel after a measured period with an independent stopwatch. Test across a local hour boundary and local midnight because those transitions expose date truncation and time-zone conversion. If the local UTC offset changes seasonally at the installation, repeat the test across that transition; UTC subtraction should remain continuous because neither stored operand changes time domain.

Then inspect the mnemonic display. The event timestamp may be converted to local wall time by Web, but the duration string must match the numeric seconds and must not gain the local offset. If the number is right and the string is wrong, correct only the string conversion or display mapping. If both are wrong, inspect the saved timestamp, current timestamp, operand order, and referenced channel numbers.

Which recurring pitfalls should be avoided?

Do not correct a duration by subtracting a fixed three-hour offset. That may hide one workstation’s symptom but changes the measured interval and fails when the Web client, server, or communicator operates in another time zone. A time-zone offset belongs to timestamp presentation, never elapsed-time arithmetic.

Do not use Unix time merely to escape the formatter unless the surrounding interface already requires it. It adds conversion steps but does not solve a Web object that interprets the result as time-of-day. The decisive change is carrying the interval as numeric seconds or plain text.

Chart navigation is a related but separate path. The reported chart request opened with an empty date parameter such as http://localhost:10008/ChartPro/ChartPro?cnlNums=103&startDate=, and an empty date was treated as today. From local midnight until UTC reached midnight, navigation from a mnemonic opened the previous day; selecting Today manually opened the intended date. Setting the Web time zone did not correct that behavior in the reported setup.

Capture the generated chart address, the local and UTC timestamps, the navigation origin, and the installed Webstation and Charts Pro versions. Test whether the fault occurs only when opening from the mnemonic or also from the tabular view. An explicit correct start date isolates empty-date resolution from archive data and channel configuration.

FAQ

Why does V6 show three hours when the elapsed time is zero?

The elapsed value is being rendered with a date/time or Time format, so Web applies its local UTC offset. Store the duration as total seconds and display it numerically or through TimeSpan.FromSeconds(...).ToString().

Why does the elapsed timer count down from six hours?

Check that both operands use UTC, that the subtraction is current minus saved, and that the formula references the channel written by SetVal(2, UtcNow()). Remove Time formatting before interpreting the result.

Why does the chart open yesterday after local midnight?

An empty startDate= can resolve “today” against UTC while the operator is already in the next local day. Stop local adjustments when an explicit date works but mnemonic navigation still generates the wrong day; record the Webstation and Charts Pro versions, request URL, local/UTC times, and screenshots. Escalate that reproducible navigation defect through the manufacturer’s official support channel and ask whether an update addresses empty-date handling.

Back to blog