GPS History Blocks - {{formatDate }} handlebar templates

Hi guys,

I’m using the {{formatDate }} handlebar template to add content to the pin popup boxes. I’d like to have some control over the date display format, especially with respect to timezone and locale. Is there documentation for {{formatDate}}?

Thanks

Steve

Here’s the overall docs for our helpers:

https://docs.losant.com/workflows/accessing-payload-data/#format-helpers

The formatDate helper specifically uses the Moment.js format, which is documented here:

http://momentjs.com/docs/#/displaying/format/

So for for example, if you wanted the result to be 2018-05-23, you’d use the format:

{{ formatDate time 'YYYY-MM-DD' }}

Thanks Brandon,

The docs were helpful. But now I find that my problem is not formatting, it’s timezone. {{formatDate }} seems to use UTC as its timezone. The value being fed to formatDate is encoded as an ISO 8601 string with an offset from UTC. formatDate simply renders the date as local time for UTC, which is completely wrong. I need to be able to specify the timezone and then render as local time.

Ideally the timezone could be inferred from the lat-long pin location. You could use something like https://github.com/darkskyapp/tz-lookup

Any ideas how I can specify timezone?

It does not look like {{formatDate}} will allow you to render it with a specific timezone. The helpers are rendered by the browser, so they always appear local to whoever is looking at the dashboard. If I understand correctly, you’d like to show it rendered local to the timezone were the asset is physically located.

A workaround would be to use a workflow to add a string attribute to the device with the time formatted in whatever way you’d like. Workflows provide a lot more power to manipulate data.

I believe you can copy/paste all of moment.js into a function node and then use it.

var date = moment(payload.time);
date.zone("-04:00")
payload.data.formattedDate = date.format("...");

The workflow would trigger on device state, run the function node, and then use a Device State node to record the new formattedDate attribute on the same timestamp as the GPS.

It’s very important to understand that reporting state in a workflow that’s triggered on state will cause an infinite loop that we will detect and kill. You need to add a Conditional node after the trigger to check that your GPS coordinate is on the payload and that’s what triggered it.

Thanks for the workaround tip. I’d really like to avoid manipulating a date attribute purely for a view. To me localization is a presentation issue not a data issue.

FYI we’re based in NZ. We have some historic time data stored as strings in a Losant data table. Originally this was written in local time, ie. without any time zone information. We’ve since corrected this data to include a 12 hour offset and will be recording future dates in UTC.

We process these data table’s in a Losant workflow and use the dates to populate a device attribute. These attributes are encoded as a string in ISO 8601 UTC format. When we inspect these dates in the GPS map the results are out by 12 hours, ie. they are displayed at Z time. In other words, the browser’s locale is not taken into account.

But as I said, we’d much prefer the time zone to be inferred from the pin location. If I were to review data of a device located in Paris from a computer in NZ I’d like to know the local Paris time of the attribute or the UTC time of the attribute. But I wouldn’t want to know the NZ local time of the attribute. In other words, browser locale is unlikely to be correct in the general case.

I know this is an older thread, but it seems like the OP may not have actually tested the suggestion. I’m trying to use moment.js in a function node to produce a formatted timestamp string to insert into an SMS, (the transmission of which may be delayed several hours due to a waking-hours constraint):

var date = moment(payload.data.lowVoltsTime);
date.zone("-04:00");
payload.data.lowVoltsTimeFmt = date.format("kk:mm") + " on " + date.format("MMM Do");

On triggering I get the following error in the debugger:

FunctionNodeReferenceError 
moment is not defined at customFunction (RawFunctionNode:1:12)

Any ideas? Thanks!

You have to copy/paste all of moment.min.js into your Function Node above your actual code. Moment is not available in the Function Node by default. Here’s a quick test I did. You can see the resulting formatted strings in the Debug Log on the right. I tried a couple of utc offsets to make sure changing the timezone worked. As an FYI, the .zone function is deprecated and should be replaced with .utcOffset.

1 Like

@ADB2,

Also, we have a lot of Moment.js functionality in the Date/Time Node:

Thanks to you both, I appreciate the tips. I overlooked the fact that moment.js wasn’t built in to the workflow environment.