The way that Ephemeris works, or to be more specific the way that the JollyDay library it’s built upon, it’s designed to keep track of recurring holidays or recurring types of days that occur every week. It doesn’t really make any sense to add a year to a holiday. Given that the XML file is “owned” by the JollyDay library I don’t see a year being added but you never know. You could file a feature request issue and see what they say. Note that OH 4.2 will bring in a new version of JollyDay.
I thought you could add data to the calendar entry that the iCal binding could parse out and update an Item with. If not, you could put the year in the calendar entry perhaps.
I think your best bet will be to store the actual birthday somewhere: calendar entry name, separate Item, Item metadata, etc. Then it’s a simple calculation to get the number of years.
In JS Scripting, assuming it’s a separate Item, it could look something like this:
var holidayName = actions.Ephemeris.getBankHolidayName(0, '/etc/openhab/ephemeris/birthdays.xml');
if(holidayName !== null) {
// Assuming the label of the Item storing the actual date matches the descriptionPropertiesKey in the XML
const dtItem = items.getItems().filter( item => item.label == holidayName)[0];
const delta = time.Duration.between(time.toZDT(dtItem), time.toZDT());
const numYears = delta.get(time.ChronoUnit.YEARS);
}
var marie, date, d, y, cleanedM, cleanedD, M;
// Get in informative String build out of datetime.
function age(date) {
d = (time.ChronoUnit.DAYS.between(date,(time.ZonedDateTime.now())));
y = (time.ChronoUnit.YEARS.between(date,(time.ZonedDateTime.now())));
M = (time.ChronoUnit.MONTHS.between(date,(time.ZonedDateTime.now())));
cleanedM = (time.ChronoUnit.MONTHS.between(date,time.ZonedDateTime.now().minusYears(y)));
cleanedD = (time.ChronoUnit.DAYS.between(date,time.ZonedDateTime.now().minusMonths(M)));
return [y,' Jahre ',cleanedM,' Monate ',cleanedD,' Tage.','\r\n','Oder auch:',d,' Tage.','\r\n','Dieses Jahr wird es ein ',date.plusYears(y + 1).format(time.DateTimeFormatter.ofPattern('E'))].join('');
}
marie = (time.toZDT(items.getItem('birthday_marie')));
console.warn((age(marie)));
There is a challenge with joda-js, the underlying library that implements everything you find under time. To include all the locale stuff would be many megabytes of additional data, most of which is not used for most users. So the Helper Library doesn’t ship with every locale.
You’ll also need to import it into your rule too using a require.
var Locale = require('@joda-js/locale_de').Locale.GERMANY;
Then if time.DateTimeFormatter doesn’t recognize the locale automatically you’ll want to use the LocaleDatetimeFormatter.