JS Scripting DateTime formatting

I have a system which uses a lot of TTS to make announcements before certain datetime events occur. I have had rules in DSL and Jython where converting some datetime items (typically Astro events) into strings for TTS notifications. However, I’m struggling with getting it to work in ECMA 2021.

This is working:

var currentTime = ZonedDateTime.now().toLocalTime().format(DateTimeFormatter.ofPattern("h:mm a")).toString();

and it allows me to pass a time like “11:57 a.m.” to a string for TTS processing. However, in the same rule I am trying to convert an Astro time to the same format and it won’t work. I’ve tried a few things, including:

var nightTime = time.toZDT(items.getItem("AstroSunNight_StartTime")).format(DateTimeFormatter.ofPattern("h:mm a"));

which throws a java.lang.StackOverflowError error.

The following works, but I will only provide 24 hour clock time (ie, 19:30) instead of the 12 hour am/pm time. I’d like to keep the 12 hour time for purposes of TTS:

var nightTime = time.toZDT(items.getItem('AstroSunNight_StartTime')).toLocalTime().toString();

I’m sure it’s my syntax, but I can’t seem to find the right way to do this.

Your close with:

I think the only issue is that DateTimteFormatter is not directly accessible. It is made available through the time object, however. So, instead of just


you need


That appeared to have stopped the stack overflow error - much thanks. I had to install the @js-joda/locale plugin due to another error:

Pattern using (localized) text not implemented, use @js-joda/locale plugin!

I installed the locale plugin and required it in the rule, but now I’m getting another error:

TypeError: null has no such function "localeString"

The offending code is:

var nightTime = time.toZDT(items.getItem("AstroSunNight_StartTime")).toLocalTime().format(time.DateTimeFormatter.ofPattern("h:mm a")).withLocale(Locale.US).toString();

The same error occurs if I omit .toLocalTime()… as follows:

var nightTime = time.toZDT(items.getItem("AstroSunNight_StartTime")).format(time.DateTimeFormatter.ofPattern("h:mm a")).withLocale(Locale.US).toString();

or if I try to skip .withLocale(Locale.US), .toString(), or both.

Appreciate the input. At least I’m off of the stack overflow error…

Which one? And do you import timezone too like described here?

There was an attempt to figure out a good way to solve this local string formatting problem in a transparent way but unfortunately making all the locales available by default would have added dozens of MB to the size of the add-on and that was deemed too much.

Hi - did you ever find a solution for this? I’m also experiencing this error.

The issue is with the “a” formatter pattern, so this command works fine:

time.toZDT().format(time.DateTimeFormatter.ofPattern('hh:mm M/d/yyyy'))

but once you change the pattern to:

time.toZDT().format(time.DateTimeFormatter.ofPattern('hh:mm a M/d/yyyy'))

The error occurs. So, we can’t use the am/pm modifier in date formatting. Any solutions would be helpful, thanks!