What time is it? Well That Depends...

6666
9
03-13-2019 06:24 PM
RJSunderman
Esri Regular Contributor
7 9 6,666

When someone asks you, "What time is it?", you are probably assuming he or she wants to know the local time where the two of you are right now. As I write this, the time now is Tuesday, March 12, 2019 at about 2:25 PM in Redlands, California, USA.

Typically, we do not qualify our answers so explicitly. We say "It's 2 o'clock" and assume it's understood that this is the time right now in Redlands, California. But that is sort of like answering a query about length or distance by simply saying "36". Is that feet, meters, miles, or kilometers?

Last weekend, here in California, we set our clocks ahead one hour to honor daylight savings time (DST). California is now observing Pacific Daylight Time (PDT) which is equal to UTC-7:00 hours. When we specify the time at which an event was observed, we should include the time zone in which the observation is made as well as whether or not the time reflects a local convention honoring daylight savings time.

When ArcGIS GeoEvent Server receives data for processing, event records usually include a date/time value with each observation. Often the date/time value is expressed as a string and does not specify the time zone in which the date/time is expressed or whether the value reflects a daylight savings time offset. These are sort of like the "units" (e.g. feet, meters, miles, or kilometers) which qualify a date/time value.

The intent of this blog is to identify when GeoEvent Server assumes a date/time value is expressed in Coordinated Universal Time (UTC) versus when it is assumed that a date/time expresses a value consistent with the system's locale. We'll explore a couple situations where this might be important and the steps you can take to configure how date/time values are handled and displayed.

Event data ingest should generally assume date/time values are expressed as UTC values

There are several reasons for this. In the interest of brevity, I'll simply note that GeoEvent Server is running in a "server" context. The assumption is that the server machine is not necessarily located in the same time zone as the sensors from which it is receiving data and that clients interested in visualizing the data are likewise not necessarily in the same time zone as the server or the sensors. UTC is the time standard commonly used around the world. The world's timing centers have agreed to synchronize, or coordinate, their date/time values -- hence the name Coordinated Universal Time.(1)

If you have ever used the ArcGIS REST Services Directory to examine the JSON representation of feature records which include a date/time field whose data type is esriFieldTypeDate, you have probably noticed that the value is not a string, it is a number; an epoch long integer representing the number of milliseconds since the UNIX Epoch (January 1, 1970, midnight). The default is to express the value in UTC.(2)(3)

When does GeoEvent Server assume the date/time values it receives are UTC values?

Out-of-the-box, GeoEvent Server supports the ISO 8601 standard for representing date/time values.(4)

It is unusual, however, to find sensor data which expresses the date/time value "March 12, 2019, 2:25:30 pm PDT" as 2019-03-12T14:25:30-07:00. So when a GeoEvent Definition specifies that a particular attribute should be handled as a Date, inbound adapters used by GeoEvent Server inputs will compare received string values to see if they match one of a few commonly used date/time patterns.

For example, GeoEvent Server, out-of-the-box, will recognize the following date/time values as Date values:

  • Tue Mar 12 14:25:30 PDT 2019
  • 03/12/2019 02:25:30 PM
  • 03/12/2019 14:25:30
  • 1552400730000

When one of the above date/time values is handled, and the input's Expected Date Format parameter does not specify a Java SimpleDateFormat expression / pattern, GeoEvent Server will assume the date/time value represents a Coordinated Universal Time (UTC) value.

When will GeoEvent Server assume a date/time value is expressed in the server machine's locale?

When a GeoEvent Server input is configured with a Java SimpleDateFormat expression / pattern the assumption is the input should convert date/time values it receives into an epoch long integer, but treat the value as a local time, not a UTC value.

For example, if your event data represents its date/time values as "Mar 12 2019 14:25:30" and you configure a new Receive JSON on a REST Endpoint  input to use the pattern matching expression MMM dd yyyy HH:mm:ss as its Expected Date Format property, then GeoEvent Server will assume the event record's date/time expresses a value consistent with the system's locale and will convert the date/time to the long integer value 1552425930000.

You can use the EpochConverter online utility to show equivalent date/time string values for this long integer value. Notice in the illustration below that the value 1552425930000 (expressed in epoch milliseconds) is equivalent to both the 12th of March, 2019, at 9:25 PM Greenwich Mean Time (GMT) and 2:25 PM Pacific Daylight Time (PDT):

EpochConverter online utility

The utility's conversion notes that clocks in my time zone are currently seven hours behind GMT and that daylight savings time is currently being observed. You should note that while GMT and UTC are often used interchangeably, they are not the same.(5)

What if I have to use a SimpleDateFormat expression, because my date/time values are not in a commonly recognized format, but my client applications expect date/time values will be expressed as UTC values?

You have a couple of options. First, if you have the ability to work with your data provider, you could request that the date/time values sent to you specify a time zone as well as the month, day, year, hour, minute, second (etc.).

For example, suppose the event data you want to process could be changed to specify "Mar 12 2019 14:25:30 GMT". This would enable you to configure a Receive JSON on a REST Endpoint  input to use the pattern matching expression MMM dd yyyy HH:mm:ss zzz as its Expected Date Format property since information on the time zone is now included in the date/time string. The input will convert the date/time string to 1552400730000 which is a long integer equivalent of the received date/time string value.

Using the EpochConverter online utility to show the equivalent date/time string values for this long integer value, you can see that the Date value GeoEvent Server is using is a GMT/UTC value:

If the data feed from your data provider cannot be modified you can use GeoEvent Server to compute the proper UTC offset for the ingested "local" date/time value within a GeoEvent Service.

Because GeoEvent Server handles Date attribute values as long integers, in epoch milliseconds, you can use a Field Calculator to add (or subtract) a number of milliseconds equal to the number of hours you need to offset a date/time value to change its representation from "local" time to UTC.

The problem, for a long time, was that you had to use a hard-coded constant value in your Field Calculator's expression which rendered your GeoEvent Service vulnerable twice a year to time changes if your community started and later stopped observing daylight savings time. Beginning with the ArcGIS GeoEvent Server 10.5.1, the Field Calculator supports a new wrapper function that helps address this: currentOffsetUTC()

A Field Calculator, running within a GeoEvent Service on my local server, evaluates currentOffsetUTC() and returns the value -25200000, the millisecond difference between my local system's current date/time and UTC. Currently, here in California, we are observing Pacific Daylight Time (PDT) which is equal to UTC-7:00.

Even though GeoEvent Server assumes date/time values such as "Mar 12 2019 14:25:30" (received without any time zone "units") represent local time values -- because a pattern matching expression MMM dd yyyy HH:mm:ss must be used to interpret the received date/time string values -- I was able to calculate a new date/time value using a dynamic offset and output a value which represents the received date/time as a UTC value. All I had to do was route the event record, with its attribute value ReportedDT (data type: Date) through a Field Calculator configured with the expression:  ReportedDT + currentOffsetUTC()

How do I configure a web map to display local time rather than UTC time values

When recommending that date/time values should generally be expressed as UTC values, a frequent complaint when feature records updated by GeoEvent Server are visualized on a web map, is that the web map's pop-up values show the date/time values in UTC rather than local time.

It is true that, generally, we do not want to assume that a server machine and sensor network are both located in the same time zone as the localized client applications querying the feature record data. That does not mean that folks in different time zones want to perform the mental arithmetic needed to convert a date/time value displayed by a web map's pop-up from UTC to their local time.

In the past I have recommended data administrators work around this issue using a Field Calculator to offset the date/time, as I've shown above, by a number of hours to "falsely" represent date/time values in their database as local time values. I say "falsely" because most map/feature services are not configured to use a specified time zone. For a long time it wasn't even possible to change the time zone a map/feature service used to represent its temporal data values. There are web pages in the ArcGIS REST API which still specify that feature services return date/time values only as epoch long integers whose UTC values represent the number of milliseconds since the UNIX Epoch (January 1, 1970, midnight). So even if a map/feature service is configured to use a specific time zone, we should not expect all client applications to honor the service's specification.

For now, let's assume our published feature service's JSON specification follows the default and client apps expect UTC values returned when they query the map/feature service. If we use GeoEvent Server to falsely offset the date/time values to local time, the data values in our geodatabase are effectively a lie. Sure, it is easy to say that all client applications have been localized, and assume all server machines, client applications, and reporting sensors are all in one time zone; all we are trying to do is get a web map to stop displaying date/time values in UTC.

But there is a better way to handle this problem. Testing the latest public release (10.6.1) of the Enterprise portal web map and ArcGIS Online web map I found that pop-ups can be configured with custom expressions which dynamically calculate new values from existing feature record attributes. These new values can then be selected as the attributes to show in a web map's pop-up rather than the "raw" values from the feature service.

Below are the basic steps necessary to accomplish this:

  1. In your web map, from the Content tab, expand the feature layer's context menu and click Configure Pop-up.
  2. On the lower portion of the Configure Pop-up panel, beneath Attribute Expressions, click Add.
  3. Search the available functions for date functions and build an expression like the one illustrated below.

Web Map | Custom Attributes

Assign the new custom attribute a descriptive name (e.g. localDateTime) and save the attribute calculation. You should now be able to select the dynamic attribute to display along with any other "raw" attributes from the feature layer.

Web Map | Custom Pop-up

References:

(1)  UTC – Coordinated Universal Time

(2)  ArcGIS for Developers | ArcGIS REST API

(3)  ArcGIS for Developers | Common Data Types | Feature object

(4)  World Wide Web Consortium | Date and Time Formats

(5)  timeanddate.com - The Difference Between GMT and UTC

(6)  ArcGIS for Developers | ArcGIS REST API | Enterprise Administration | Server | Service Types

9 Comments
AdamRepsher_BentEar
Occasional Contributor

Hi @RJSunderman -
If I have published feature services with the Time Zone undefined (in the past, ArcGIS Server then assumed UTC) and then upgrade to 10.9, does the addition of the new timeReferenceUnknownClient parameter affect me in GeoEvent?  Or another change that this was made to account for?

I believe that this parameter was created in to allow ArcGIS Server to return the time that is saved in a Date field with no assumption of the end user's time zone - basically letting the end user get the time that is recorded in the datastore/enterprise geodatabase/filegeodatabase.  Therefore, if I neglect to create a service with the Time Zone defined as UTC that is actually collecting data in UTC, will the end-user then just get back UTC values by default and not see a change to their local time zone?

I may also be making this way too simple - or overcomplicating it.  That happens.

Thank you,
--Adam

RJSunderman
Esri Regular Contributor

Hey Adam --

Thank you for highlighting these new server-side (datesInUnknownTimeZone) and client-side (timeReferenceUnknownClient) properties.

Checking with the development team, I was told that service publishers, beginning with the 10.9 release, can now set datesInUnknownTimeZone to TRUE when publishing a feature service (the default for this property is FALSE).

If an application sends a query, addFeatures, or updateFeatures request and does not explicitly set the timeReferenceUnknownClient query parameter to TRUE in the request -- and the service was published with its datesInUnknownTimeZone parameter set TRUE -- the client will receive an HTTP error code response. This is to protect client applications querying newer 10.9(+) services which make use of the new specification from receiving unexpected data.

Services you publish using GeoEvent Manager at 10.9 / 10.9.1 will continue to use the default setting of FALSE for the datesInUnknownTimeZone parameter. ArcGIS Server feature services and Enterprise portal hosted feature layers will not change the default for this property when services are upgraded from 10.8.x to the 10.9.x release. Therefore, applications sending client queries should expect to receive the same epoch long integer values from feature services and hosted feature layers they have been receiving regardless of whether the services are (pre-upgrade) 10.8.x services or have been upgraded to the 10.9.x release.

I do not have a 10.9.1 release candidate deployment I can use to check right now, so I would ask that you "trust but verify" what I've said above. You can examine an ArcGIS Server feature service's (or an Enterprise portal hosted feature layer service's) JSON specification by navigating to the service in the ArcGIS REST Services Directory and clicking the JSON link in the upper-left corner of the service's web page. I would look to see if the upgraded service's JSON specification has the datesInUnknownTimeZone parameter set TRUE or kept the FALSE default. I would then check that web applications (e.g web maps) you have configured display the expected date/time when looking at a feature record's attributes in a pop-up or table. I would also configure a GeoEvent Server input to query the ArcGIS Server feature service and/or Enterprise portal hosted feature layer you have upgraded to retrieve feature records and write those out to a JSON file. Use the https://www.epochconverter.com on-line utility to convert the epoch long integer GeoEvent Server has written out to its JSON data file to confirm the queried values. If you have any trouble with this, please open an incident with Esri Technical Support. (I will be running these same tests myself as I was previously unaware of the new service property and corresponding client query parameter.)

-- RJ

AdamRepsher_BentEar
Occasional Contributor

@RJSunderman 
Once again, thank you for taking the time to review this and give your analysis.  I will verify once I have 10.9.1 installed.

I have a number of clients who are starting to use GeoEvent Server, and I am thankful for your continued knowledge dumps!

--Adam

DENGD
by
New Contributor II

In my ArcGIS geoevent server 10.8.1, I have problem to convert the  Epoch time ( a double ) from Samsara input  connector to a datetime field in a feature service. In geoevent 10.4.1, it was automatically convert to date. So I just need to convert to EST time. I tried the epoch time in seconds and milliseconds.

Any suggestions how to convert Epoch time into a date in field calculator?????

RJSunderman
Esri Regular Contributor

At the 10.8.1 release there limited options for using a Field Calculator or Field Mapper processor to explicitly cast a data value from a numeric value to a Date. The inbound connector you are using, however, should be able to adapt the received value as a Date rather than as a Double or String.

If you can provide me a sample of the data being received and screenshots of how you've configured the inbound connector and the GeoEvent Definition that connector is using, I can probably suggest a way to adapt the Samsara data you are receiving.

-- RJ

DENGD
by
New Contributor II

@RJSunderman 

Here is the input connector. Whether or not set the date format on inbound connector did not matter. 

DENGD_0-1697457325363.png

In GEP 10.4.1 the time is long. In GEP 10.8.1, the time is double. If I add a field mapper to map the time to a date field, the datefield would be null. If I convert the double to long, then some row on the date field was 1/1/1970, most row of the date field were still null.

DENGD_1-1697458389270.png

That's was a test service that just wanted to get the time mapped to the date field correctly.

Thanks,

Debbie

 

RJSunderman
Esri Regular Contributor

Hello Debbie --

I am going to request we take any further troubleshooting through Esri Technical Support. From what you've shared I'm assuming that the GeoEvent Definition you've configured your Poll an External Website for JSON to create for you (e.g. SamsaraLocationsIN) recognized the attribute time in the data received from Samsara as a numeric value. When allowing an input to create a GeoEvent Definition for you, numeric values are adapted as a Double (because a Double is the most generic way to handle a numeric value).

If indeed the time in the Samsara data record is a 13-digit epoch expressing milliseconds -- not a 10-digit epoch expressing seconds -- then you should be able to simply copy the SamsaraLocationsIN GeoEvent Definition the input created for you and edit your copy to specify that the attribute value time should be adapted as a Date.

You should then delete the auto-generated SamsaraLocationsIN GeoEvent Definition and reconfigure your Poll an External Website for JSON input to use your copy of the GeoEvent Definition, the one you've tailored specifically to adapt time as a Date.

You also might want to review the comments in the following Esri Community article which present and discuss the adaption of different representations of date/time values:    Timestamps received from a sensor feed display differently in GeoEvent Sampler, ArcGIS REST Services...

DENGD
by
New Contributor II

@RJSunderman  I verified it is a 13 digits ("time":1.696794234181E12 in cvs outpot, 1696810519923 in JSON output OR feature service).  In  GEP 10.4.1, the inbound is 13 as long. In GEP 10.8.1, the inbound is 13 as double. I  will follow your instruction to make a copy, change the data type  to date to see.... tomorrow. Thank you!!

DENGD
by
New Contributor II

@RJSunderman  I updated the Time data type as long in the geoevent definition of  SamsaraLocationsIN then reconfigured the  input connector to use existing SamsaraLocationsIN geoevent definition. Then the time mapped into the feature service correctly. Thank you!!!!!!!!!!!