Ignition Perspective Page to show the client System date and time

Is it possible to display the client computer/system date and time on perspective web page?

dateFormat(now(60000), "yyyy-MMM-dd HH:mm:ss a") showing the Gateway Server system date and time.

Under Browse Tags-> System -> Client Tags are not available for Perspective sessions.

Change the project property.

Project Properties > Perspective > General > Project Timezone > 'Client Timezone'

now() is going to use the Gateway's timezone, because that's where the script is executed. I suspect you'll need to get crafty with a transform for the binding where you adjust the time based on the session timezone (props.timeZoneId) before formatting it.

1 Like

Thanks, cmallonee. Can you explain little more detailed. I'm little new to ignition.

I'm actually out of the office until next week so I won't be able to supply a code example until then. In theory, you'll configure your binding to be an expression which contains only now(60000). In a transform of that binding, you'll need to use available date and time libraries to modify the incoming value based on the difference between the Gateway's timezone id (self.session.props.gateway.timezone.id), and that of the Session (self.session.props.timeZoneId) before finally either formatting this new value and returning it, or returning the modified value into yet another transform where you format it into the desired string pattern.

In the transform, I recommend converting the Date to an Instant, then to a ZonedDateTime object with the ZoneId selected by self.session.props.timeZoneId.

String conversion of the ZonedDateTime will use the client's timezone.

The transform would look like this:

from java.time import ZoneId
return value.toInstant().atZone(ZoneId.of(self.session.props.timeZoneId))

Thanks. It's working but formatting using Java methods is not working in perspective.
Can you share formatting logic example as well?

Sure. I recommend DateTimeFormatter.ofPattern(). But I would move the complexity to a project script module with a DateTimeFormatter instance with your preferred pattern saved as a top level variable. Like so, perhaps:

from java.time import ZoneId
from java.time.format import DateTimeFormatter

defaultFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm")

def zonedFormat(ts, zoneid, format=None):
	formatter = defaultFormatter if format is None else DateTimeFormatter.ofPattern(format)
	return ts.toInstant().atZone(ZoneId.of(zoneid)).format(formatter)

If that is a project script named zoneHelper, then your transform becomes just:

return zoneHelper.zonedFormat(value, self.session.props.timeZoneId)

Use the optional third argument to supply a different format pattern.

3 Likes

It worked finally. I had to make few changes to the suggested code. Thanks

def transform(self, value, quality, timestamp):
	from java.time import ZoneId
	from java.time.format import DateTimeFormatter
	
	defaultFormatter = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss a")
	zoneid=self.session.props.device.timezone.id
#	def zonedFormat(ts, zoneid, format=None):
	#formatter = DateTimeFormatter.ofPattern(defaultFormatter)
	client_time = value.toInstant().atZone(ZoneId.of(zoneid)).format(defaultFormatter)
	return client_time

I strongly recommend you use a project library script as I showed. Imports and pattern creation are heavy-weight operations in jython that you don't want to be doing on every execution of the transform.

Ok, Sure. Modified the logic.
Thanks!