[Solved] Convert Timestamp to hours:minutes

I am trying to convert a timestamp (unix time) to a string with hours and minutes (hh:mm).

I wanted to use a function bloc and code this converstion with :

var timeux = payload.path.to.the.time.to.[0].convert * 1000;
var hh = timeux.getHours();
_var mm = timeux.getMinutes(); _
var goodTime = hh + “:” + mm;

My timestamp sits in the payload path.to.the.time.to.[0].convert

What I would like to understand since this is not clear in the docs :

Should the word payload be appenned to the complete path ?
I get an error because of the [0] in the path !

I would like to add this value to the path : path.to.today.correctTime.time : time being the key and the goodTime calculated above being the value. How can I perform this operation ?

Many thanks

First, you can convert your timestamp to a date format of your choosing without using a function node; instead, use a Mutate node and the {{formatDate}} Handlebars helper.

In the Mutate node, select “Set a new value”. Then, in the Value Template, enter {{formatDate (multiply path.to.the.time.to.[0].convert 1000) 'kk:mm'}}.

{{formatDate}} takes two arguments. The first is the value to format, which is your timestamp. We’re including a subhelper in here (the (multiply ...) part) to convert your timestamp from seconds to milliseconds. Note that if your timestamp is already in milliseconds, I recommend keeping the multiply subhelper in place but changing the 1000 to a 1, just to ensure that your timestamp is cast to a number.

The second argument is the Moment.js format string for how you want the date displayed. I believe kk:mm is what you want here based on the example you posted.

Then, in the Mutate node’s Destination Path, enter path.to.today.correctTime.time to insert the mutated value here.

To answer your original question, when using a function node, yes, payload must be included in your path (but not in any of the other nodes). But the reason you’re getting an error is you’re using Handlebars-style variable references in what is a straight Javascript editor. On top of that, you are not converting timeux to a Date object before getting the hours and minutes out of it.

So, you should change this line …
var timeux = payload.path.to.the.time.to.[0].convert * 1000;

… to this (note the missing period before the [0]) …
`var timeux = new Date(payload.path.to.the.time.to[0].convert * 1000);

Now your date methods will work, and then to add goodTime to your payload, just set a new property on the payload object:
payload.goodTime = goodTime;

@Dylan_Schuster

I’m having a bit of trouble formatting my time to the correct local time. For example, my timestamp in my workflow reads: "published_at":Tue Jul 25 2017 17:13:36 GMT-0400, which is correct for EST.

However, when I output this value using mutate and {{formatDate data.published_at 'kk mm'}}, I get: 21 13 , which is correct for UTC time, but I lose the local time in the formatting. What gives? Do I need to take the local offset and do something with that? I’ve read the moment.js docs on this, but it’s clear the entire library is not supported in Losant.

Any advice would be much appreciated! Thank you

There’s not an easy way to do what you’re looking for; there is, however, a somewhat convoluted way.

See this attached workflow (1.4 KB). We’re using Google’s Time Zone API to get the offset to apply to our current time. Time zone is determined using a latitude and longitude, which we’re defining in our workflow globals. Whether to apply daylight savings time is a function of the current time and that same location. We’re then using those values to calculate a local time, format it, and put the value on our payload using a Mutate Node.

I would recommend only calling the Google API every so often and storing / retrieving those offsets using the Store Value and Get Value nodes. Otherwise, you will have to add an API key to the Google request.

Ah, I see what you did there! Verrry crafty. So it’s possible I would only need to call this workflow at most once a day as the only thing that will change is DST. Thanks for your help!

I still don’t think I fully understand why converting the object to a string strips the local time settings. Because I feel like we’re duplicating some efforts here - clearly Losant already grabs the local time offset (perhaps via user IP?), but it seems there isn’t a way to access it.

The time as you’re seeing it in the debug log is being offset (localized) by your browser, not by Losant. When we deal with timestamps, everything is in UTC. When you, for example, push a virtual button, it’s not sending your browser’s timestamp up with the request. Does that make sense?

Ahhh, I get it. Thanks for explaining.

If you know the timezone, a method of determining daylight savings time without using Google APIs is to simply compare the current month and day to the DST dates. I have a Timer trigger run the following code in a Function node once a day and update a storage variable for use elsewhere in the workflow.

var UTCoffset = -5; // Eastern US standard time, adjust for your location
var now = new Date();
var month = now.getMonth() + 1; // Adjusted to match C
var weekday = now.getDay() + 1; // Adjusted to match C
var day = now.getDate(); 
var previousSunday = day - weekday + 1;

if (month < 3 || month > 11) {
	var UTCoffset = UTCoffset; 
}
else if (month > 3 && month < 11) {
	var UTCoffset = UTCoffset + 1; 
}
else if (month == 3) {
	var UTCoffset = (previousSunday >= 8)? UTCoffset + 1 : UTCoffset;
}
else {
	var UTCoffset = (previousSunday <= 0)? UTCoffset + 1 : UTCoffset;
}
payload.data.UTCoffset = UTCoffset;

This algorithm was based on a function (in C) posted by Ric DelMar to a Particle forum:

I use a Date/Time node to add this offset to a workflow timestamp in UTC to create one that’s in local time. A second Date/Time node can be used to format the timestamp into HH:mm or whatever is needed to pass into SMS, email, etc.

2 Likes