Local time as string

Hi @all,
in an app I want to updatea string capability with the local time (YYYY-mm-DD HH:MM).
The new Date() instance returns the UTC time. So how can I convert it to the local time when new date().getTimezoneOffset() return 0 instead of the real timezone offset?
Is there another way to get the local time respecting timezone?

You can get something like DD/mm/YYYY, HH:MM:SS like this:

const tz  = this.homey.clock.getTimezone();
const now = new Date().toLocaleString('en-GB', { timeZone: tz });

If you want more control, you need to use an external library like moment or luxon, which is basically what Athom suggests when I posted about this issue.

I believe that the reason for Athom to break Date for all SDK3 apps is that when a user changes their Homey’s location/timezone, already-running apps will still be using the previous timezone, which may cause issues. I guess people changing Homey locations happens so often that it warranted causing a ball-ache for all developers using times/dates.

3 Likes

Thanks!
I’ve seen the the .getTimezone() but didn’t know that I can use this string value in toLocaleString(). So thanks for the exampme. I’ll test it later.

With timezone I get the local time. But the locales (en-GB, de-DE) are not working in the way I hoped.
en-US seams to be ok, but with en-GB and de-DE I get MM/DD/YYYY. It should be DD.MM.YYYY.
So I’m shifting the values into a new var in correc order.

Are you sure? I would expect the other way around (US showing month first, day second, and European showing day first, month second). At least that’s how it’s working for me.

I would expect it, too.

But with this example…

const tz  = this.homey.clock.getTimezone();
    var options =     { 
      hour12: false, 
      timeZone: tz,
      hour: "2-digit",
      minute: "2-digit",
      day: "2-digit",
      month: "2-digit",
      year: "numeric"
  }; 
    console.log(new Date().toLocaleString('de-DE', options)); 
    console.log(new Date().toLocaleString('en-US', options)); 
    console.log(new Date().toLocaleString('en-GB', options));

I get this output:
grafik

Ah yes, you’re right. I tested with Node 14 but Homey still runs Node 12, which doesn’t seem to support localized formats.

Node 14:

1.5.2021, 12:34:56
5/1/2021, 12:34:56
01/05/2021, 12:34:56

Node 12:

5/1/2021, 12:34:56
5/1/2021, 12:34:56
5/1/2021, 12:34:56

I know this is an old topic, but maybe Athom made some changes…

Is there an easy way to get the local time with the latest firmware versions? I now need to include a package like luxon and that seems like a waste of resources for such a simple task.

TIA

You still have to use Luxon or another workaround to retrieve the local time. And yes, it’s a waste of resources.

1 Like

@Le_Cactus Do you mean in Flows or in HomeyScript or another way?
String format, but how should it look like?

Given he’s talking about Luxon, I assumed from an app.

Yup

I found the following function to be a bit more practical than using a big library like luxon:

  function tolocalTime(homeyTime) {
    const tz = this.homey.clock.getTimezone();
    const localTime = new Date(homeyTime.toLocaleString('en-US', { timeZone: tz }));
    return localTime;
  }

Of course, the returned time should not be stored and used in calculations but it is good for accessing the .getHours() and .getDate() functions for detecting new days and new months at least.

1 Like

Please note that the function above was not robust with regards to entering Winter time. For a single hour every year it will be one hour off. The code below will be more robust but it could probably be simplified a bit:


function toLocalTime(homeyTime, homey) {
  const tz = homey.clock.getTimezone();
  const homeyTimeHourAgo = new Date(homeyTime.getTime() - 3600000);
  const localeStringNow = homeyTime.toLocaleString('en-US', { timeZone: tz });
  const localeStringHourAgo = homeyTimeHourAgo.toLocaleString('en-US', { timeZone: tz })
  const localTime = new Date(localeStringNow);
  if (localeStringNow === localeStringHourAgo) {
    localTime.setTime(localTime.getTime() + 3600000);
  }
  return localTime;
}

…so, if you stole the code above, you have 22 hours left to fix it before it breaks :rofl:

Morale is: stick with luxon or any other big library that knows how to deal with time rather than to experiment with homey time yourself :crazy_face: