If you find any bugs, please let me know. It picked up Good Friday
var int year = now.getYear
var int a = year % 19
var int b = year / 100
var int c = year % 100
var int d = b / 4;
var int e = b % 4;
var int f = (b + 8) / 25;
var int g = (b - f + 1) / 3;
var int h = (19 * a + b - d - g + 15) % 30;
var int i = c / 4;
var int k = c % 4;
var int L = (32 + 2 * e + 2 * i - h - k) % 7;
var int m = (a + 11 * h + 22 * L) / 451;
var int month = (h + L - 7 * m + 114) / 31;
var int day = ((h + L - 7 * m + 114) % 31) + 1;
var boolean holiday = false
var String holidayName = null
var org.joda.time.DateTime easterSunday = parse(year+"-"+month+"-"+day)
var dayOfWeek = now.getDayOfWeek
var org.joda.time.DateTime newYears = parse(year+"-01-01")
if(newYears.getDayOfWeek == 0 || newYears.getDayOfWeek == 6)
newYears= parse(year+"-01-03")
var org.joda.time.DateTime newYears2 = parse(year+"-01-02")
if(newYears2.getDayOfWeek == 0 || newYears2.getDayOfWeek == 6) // saturday, we add 2 days, sunday we also add 2 days, since 1st is pushed to monday
newYears2= parse(year+"-01-04")
var org.joda.time.DateTime waitangiDay= parse(year+"-02-06")
if(waitangiDay.getDayOfWeek == 0)
waitangiDay= parse(year+"-02-07")
else if(waitangiDay.getDayOfWeek == 6)
waitangiDay= parse(year+"-02-09")
var org.joda.time.DateTime anzacDay= parse(year+"-04-25")
if(anzacDay.getDayOfWeek == 0)
anzacDay= parse(year+"-04-27")
else if(anzacDay.getDayOfWeek == 6)
anzacDay= parse(year+"-04-27")
// queens birthday, first monday in june
var org.joda.time.DateTime queensBirthday = parse(year+"-06-01")
if(queensBirthday.getDayOfWeek == 0)
queensBirthday= parse(year+"-06-02")
else if(queensBirthday.getDayOfWeek != 1){
queensBirthday= parse(year+"-06-0"+ (8 - queensBirthday.getDayOfWeek))
}
// labour day, 4th Monday in October...
var org.joda.time.DateTime octoberOne = parse(year+"-10-01")
var org.joda.time.DateTime labourDay = octoberOne.withDayOfWeek(1)
if(labourDay.isBefore(octoberOne))
labourDay = labourDay.plusWeeks(4)
else
labourDay = labourDay.plusWeeks(3)
var org.joda.time.DateTime xmasDay = parse(year+"-12-25")
if(xmasDay.getDayOfWeek == 0 || xmasDay.getDayOfWeek == 6)
xmasDay= parse(year+"-12-27")
var org.joda.time.DateTime boxingDay = parse(year+"-12-26")
if(boxingDay.getDayOfWeek == 0 || boxingDay.getDayOfWeek == 6) // saturday, we add 2 days, sunday we also add 2 days, since xmasd day is pushed to monday
boxingDay= parse(year+"-12-28")
var int dayOfYear = now.getDayOfYear
if (dayOfYear==newYears.getDayOfYear) {
holidayName = "new_years_day" // New Year
holiday = true
}
else if (dayOfYear==newYears2.getDayOfYear) {
holidayName = "day_after_new_years"
holiday = true
}
else if (dayOfYear==easterSunday.getDayOfYear-2) {
holidayName = "good_friday"
holiday = true
}
else if (dayOfYear==easterSunday.getDayOfYear) {
holidayName = "easter_sunday"
holiday = true
}
else if (dayOfYear==easterSunday.getDayOfYear+1) {
holidayName = "easter_monday"
holiday = true
}
else if (dayOfWeek == 1 && Math::abs(dayOfYear - parse(year+"-01-29").getDayOfYear) <= 4) {
holidayName = "auckland_anniversay_day"
holiday = true
}
else if (dayOfYear==waitangiDay.getDayOfYear) {
holidayName = "waitangi_day"
holiday = true
}
else if (dayOfYear==queensBirthday.getDayOfYear) {
holidayName = "queens_birthday"
holiday = true
}
else if (dayOfYear==labourDay.getDayOfYear) {
holidayName = "labour_day"
holiday = true
}
else if (dayOfYear==xmasDay.getDayOfYear) {
holidayName = "christmas" // New Year
holiday = true
}
else if (dayOfYear==boxingDay.getDayOfYear) {
holidayName = "boxing_day"
holiday = true
}
if (holidayName!=null) {
postUpdate(SpecialDay,holidayName)
}
if (holiday) {
postUpdate(Holiday,ON)
}
else {
postUpdate(Holiday,OFF)
}
I do this slightly differently, I setup a Google account for my house and then subscribe to the NZ public holidays calendar in that account;
I also subscribe to a Canterbury Anniversary calendar to get Show Day down here.
Then I have a little python script running at just after midnight which queries the calendar and checks for any events on that day, if it finds one it updates openHAB to say it is a public holiday.
yeah I was thinking of a calendar, but seeing as the days are easy to compute (well easter’s the tricky one, but the sample script took care of that), I figured its easier to use a script. I just never record any things like personal holidays in calendars, only appointments so the benefits of a calendar vs a script doesnt really apply to me. But I can easily see how it can to some.
Finally got around to implementing your script-based method of getting NZ public holidays. I ended up porting it to python so thought I would share it here in case anyone else was interested. Thanks for sharing!
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import date
from datetime import timedelta
import requests
# openHAB details
host = 'localhost'
port = 8080
username = 'user'
password = 'password'
holidayitem = 'VT_Holiday'
holidaynameitem = 'VT_Holiday_Name'
def update_item(item, value):
if item is not None:
url = 'http://%s:%s@%s:%d/rest/items/%s/state' % (username, password, host, port, item)
headers = { 'Content-Type': 'text/plain' }
requests.put(url, headers=headers, data=value)
def push_to_monday(date):
if date.weekday() == 5:
return date + timedelta(days=2)
if date.weekday() == 6:
return date + timedelta(days=1)
return date
def push_consecutive_to_monday(date):
date2 = date + timedelta(days=1)
if date.weekday() == 5 or date.weekday() == 6:
date += timedelta(days=2)
if date2.weekday() == 5 or date2.weekday() == 6:
date2 += timedelta(days=2)
return date, date2
def calculate_easter_sunday(year):
a = year % 19
b = year / 100
c = year % 100
d = b / 4
e = b % 4
f = (b + 8) / 25
g = (b - f + 1) / 3
h = (19 * a + b - d - g + 15) % 30
i = c / 4
k = c % 4
L = (32 + 2 * e + 2 * i - h - k) % 7
m = (a + 11 * h + 22 * L) / 451
month = (h + L - 7 * m + 114) / 31
day = ((h + L - 7 * m + 114) % 31) + 1
return date(year, month, day)
def calculate_holidays(year):
holidays = {}
# monday = 0, sunday = 6
newyears1, newyears2 = push_consecutive_to_monday(date(year, 1, 1))
holidays[newyears1] = 'New Years Day'
holidays[newyears2] = 'Day After New Years Day'
waitangiday = push_to_monday(date(year, 2, 6))
holidays[waitangiday] = 'Waitangi Day'
eastersunday = calculate_easter_sunday(year)
goodfriday = eastersunday - timedelta(days=2)
eastermonday = eastersunday + timedelta(days=1)
holidays[goodfriday] = 'Good Friday'
holidays[eastermonday] = 'Easter Monday'
anzacday = push_to_monday(date(year, 4, 25))
holidays[anzacday] = 'Anzac Day'
# queens birthday, first monday in june
queensbirthday = date(year, 6, 1)
if queensbirthday.weekday() == 6:
queensbirthday += timedelta(days=1)
elif queensbirthday.weekday() != 0:
queensbirthday += timedelta(days=7 - queensbirthday.weekday())
holidays[queensbirthday] = 'Queens Birthday'
# labour day, 4th monday in october
labourday = date(year, 10, 1)
while labourday.weekday() != 0:
labourday += timedelta(days=1)
labourday += timedelta(weeks=3)
holidays[labourday] = 'Labour Day'
# show day, second friday after the first tuesday in november
showday = date(year, 11, 1)
while showday.weekday() != 1:
showday += timedelta(days=1)
showday += timedelta(days=10)
holidays[showday] = 'Show Day'
xmasday, boxingday = push_consecutive_to_monday(date(year, 12, 25))
holidays[xmasday] = 'Xmas Day'
holidays[boxingday] = 'Boxing Day'
return holidays
def test(years):
for year in years:
print "Holidays for %s..." % (year)
holidays = calculate_holidays(year)
for holiday in sorted(holidays):
print "%s is %s" % (holiday, holidays[holiday])
# testing
#test(range(2010, 2019))
# get the holidays for this year
today = date.today()
holidays = calculate_holidays(today.year)
# check if today is a holiday
if today in holidays:
update_item(holidayitem, 'ON')
update_item(holidaynameitem, holidays[today])
else:
update_item(holidayitem, 'OFF')
update_item(holidaynameitem, '')
from datetime import date
import holidays
if date.today() in holidays.CA(prov='BC'):
#code to update holiday switch to true
else:
#code to update holiday switch to false