The OPC HDA COM based specifications allowed a Client to programmatically request historical time periods as absolute time (Jan 01, 2006 12:15:45) or a string representation of relative time (NOW -5M). The OPC UA specification does not allow for using a string representation to pass date/time information using the standard Services.

OPC UA Client applications that wish to visually represent date/time in a relative string format shall convert this string format to UTC DateTime values before sending requests to the UA Server. It is recommended that all OPC UA Clients use the syntax defined in Clause A.1 to represent relative times in their user interfaces.

The format for the relative time is:

keyword+/-offset+/-offset…

where keyword and offset are as specified in Table A.1 below. Whitespace is ignored. The time string shall begin with a keyword. Each offset shall be preceded by a signed integer that specifies the number and direction of the offset. If the integer preceding the offset is unsigned then the value of the preceding sign is assumed (beginning default sign is positive). The keyword refers to the beginning of the specified time period. DAY means the timestamp at the beginning of the current day (00:00 hours, midnight). MONTH means the timestamp at the beginning of the current month, etc.

For example, “DAY -1D+7H30M” could represent the start time for data requested for a daily report beginning at 7:30 in the morning of the previous day (DAY = the first timestamp for today, -1D would make it the first timestamp for yesterday, +7H would take it to 7 a.m. yesterday, +30M would make it 7:30 a.m. yesterday (the + on the last term is carried over from the last term)).

Similarly, “MONTH-1D+5H” would be 5 a.m. on the last day of the previous month, “NOW-1H15M” would be an hour and fifteen minutes ago, and “YEAR+3MO” would be the first timestamp of April 1 this year.

Resolving relative timestamps is based upon what Microsoft has done with Excel, thus for various questionable time strings we have these results:

10-Jan-2001 + 1 MO = 10-Feb-2001

29-Jan-1999 + 1 MO = 28-Feb-1999

31-Mar-2002 + 2 MO = 30-May-2002

29-Feb-2000 + 1 Y = 28-Feb-2001

In handling a gap in the calendar (due to different numbers of days in the month, or in the year), when one is adding or subtracting months or years:

Month:If the answer falls in the gap then it is backed up to the same time of day on the last day of the month.

Year:If the answer falls in the gap (February 29) then it is backed up to the same time of day on February 28.

Note that the above does not hold true for cases of adding or subtracting weeks or days, but only for adding or subtracting months or years which may have different numbers of days in them.

Note that all keywords and offsets are specified in uppercase.

Table A.1 – Time keyword definitions

Keyword

Description

NOW

The current UTC time as calculated on the Server.

SECOND

The start of the current second.

MINUTE

The start of the current minute.

HOUR

The start of the current hour.

DAY

The start of the current day.

WEEK

The start of the current week.

MONTH

The start of the current month.

YEAR

The start of the current year.

Table A.2 –Time offset definitions

Offset

Description

S

Offset from time in seconds.

M

Offset from time in minutes.

H

Offset from time in hours.

D

Offset from time in days.

W

Offset from time in weeks.

MO

Offset from time in months.

Y

Offset from time in years.

In some cases Servers are required to return the first available data point for a historical Node; Clause A.2 recommends the way that a Client should request this information so that Servers can optimize this call, if desired. Although there are multiple calls that could return the first data value, the recommended practice will be to use the StartOfArchive Property.

If this Property isn’t available then use one of the following queries using ReadRawModifiedDetails parameters:

returnBounds=false

numValuesPerNode=1

startTime=DateTime.MinValue+1 second

endTime= DateTime.MinValue

Or:

returnBounds=false

numValuesPerNode=1

startTime=DateTime.MinValue

endTime= DateTime.MaxValue

__________