Printing now(), different output, I am confused

So I am processing and printing time.

Depending on where I use it, output is different.

I want to understand what is the general rule, so I can code properly.

below is what I experienced:

	timeNow = system.date.now()
	
	#passing to label
	self.getSibling("Label").props.text = timeNow
	#output: "2023-12-20T03:09:27.322Z"
	
	#passing to console
	system.perspective.print(timeNow)
	#output: 2023-12-19 21:09:27.322
	
	#passing to dataset, render=date
	headers = ['timeNow']
	rows = [[timeNow]]
	ds = system.dataset.toDataSet(headers, rows)
	self.getSibling("Table").props.data = ds
	#output: 12/20/2023 11:09:27

how did dataset display as 12/20/2023 11:09:27

Why even the label component displays double quote? hmm..

So I tried recreating what you are seeing. Using the type() function to check if something funky is going on with data types in the background I found out the underlying data always stays a java.util.date.

My guess is that how ignition handles displaying a java.util.date object in different components is inconsistent. You have a few ways of making sure you are displaying date time objects like you want, for example in the expression language dateFormat() and in the scripting library system.date.format.

On a side note, casting a java.util.date to a string using str() yields a decent result such as "Wed Dec 20 07:23:51 CET 2023"

Fyi, it's nothing to do with datasets. If I run this in the script console, I get two dates that are equal:

timeNow = system.date.now()

print timeNow
#output: Wed Dec 20 08:57:44 CET 2023

#passing to dataset
headers = ['timeNow']
rows = [[timeNow]]
ds = system.dataset.toDataSet(headers, rows)

print ds.getValueAt(0,0)
#output: Wed Dec 20 08:57:44 CET 2023

Could it not have something to do with time zones? Since you are going back and forth between Perspective and the script?

You get the timezone that applies at the point where the java.util.Date, which is itself purely UTC, is converted to a string. If in the gateway process, it will be the gateway's time zone. If in the designer (like the tag browser), it will be the designer's time zone. If in the perspective client using a native component's date formatting, it will be the session time zone. Perspective scripts and expressions run in the gateway. If you want those to use the session timezone, you have to apply it yourself, with Java.

This topic should help:

{ Read the whole thing. }

1 Like

Still confusing...
For education purpose,
I set gateway timezone, project timezone, client timezone, to different timezone.

Conclusion:
system.date.now() will assign UTC String

system.date.format() will do two things, UTC Time with gatewayOffset

Table component - will render UTC string to integer with "project time" offset

To get Client's time: I need to:

	#client time
	timeNow = system.date.now()
	
	deviceUtcOffset  = self.session.props.device.timezone.utcOffset
	gatewayUtcOffset = self.session.props.gateway.timezone.utcOffset
	
	offset = deviceUtcOffset - gatewayUtcOffset 
	
	#client time in UTC string with client offset
	clientTime = system.date.addHours(timeNow, offset)
	
	#apply date format (apply gateway offset and format it)
	clientTimeFormated = system.date.format(clientTime, "yyyy-MM-dd hh:mm:ss a")
	
	return clientTimeFormated

No, it does not. It returns a java.util.Date object. Not a string. Printing or logging it turns it into a string, for that purpose, at that point in your code.

Don't do this. Don't use date arithmetic to "fix" timezoneless date objects. Use zoned date formatting, as shown in the linked topic.

Don't use system.date.format() when trying to use a non-default time zone (non-default for the context the code runs in). Use zoned date formatting, as shown in the linked topic.

Don't print date/time objects, in general, unless you know the context they are in.