Page 1 of 1

Date and leap year handling in dzvents

Posted: Sunday 10 August 2025 9:15
by Gingerpale
How can I make this script below working correctly at leap years? Now it always adds 364 days to calculate the end contract date as I am using addDays. If I could use addYears it would be easier I guess but that attribute doesn't exist. Maybe there's an easier way.

Code: Select all

return {
	on = {
           timer = { 'every minute'}, -- for testing only, else use 'at 00:00'
	   },
 	logging = {
           level = domoticz.LOG_DEBUG,
           marker = "timer"
    	   },
        
	execute = function(domoticz)
       	   local Time = require('Time')
           local contractStartDate = Time(domoticz.variables("Energy_Contract_Start").date.rawDate .. ' 00:00:00')
           domoticz.log('Contract Start Date: ' .. contractStartDate.rawDate, domoticz.LOG_INFO) -- e.g. 2025-07-15
           local contractEndDate = contractStartDate.addDays(364) -- make a new time object '1 year - 1 day' later. This fails at leap years!
           domoticz.log('Contract End Date: ' .. contractEndDate.rawDate, domoticz.LOG_INFO) -- e.g. 2026-07-14

           if domoticz.time.rawDate == contractEndDate.rawDate then -- e.g. "2026-07-14"
               domoticz.log('Energy contract ends today!', domoticz.LOG_INFO)
           else
               domoticz.log('Energy contract does not end today', domoticz.LOG_INFO)
           end
	end
}

Re: Date and leap year handling in dzvents  [Solved]

Posted: Sunday 10 August 2025 9:30
by madpatrick
Maybe this works

You can check the 29 februari as a leap year

Code: Select all

execute = function(domoticz)
    local Time = require('Time')
    local contractStartDate = Time(domoticz.variables("Energy_Contract_Start").date.rawDate .. ' 00:00:00')
    domoticz.log('Contract Start Date: ' .. contractStartDate.rawDate, domoticz.LOG_INFO)

    -- Extract year, month, day from start date
    local year = contractStartDate.year + 1
    local month = contractStartDate.month
    local day = contractStartDate.day

    -- Handle Feb 29 for non-leap years
    if month == 2 and day == 29 then
        -- Check if new year is leap year
        if not (year % 400 == 0 or (year % 4 == 0 and year % 100 ~= 0)) then
            day = 28
        end
    end

    -- Create new end date as string YYYY-MM-DD and time 00:00:00
    local endDateString = string.format('%04d-%02d-%02d 00:00:00', year, month, day)
    local contractEndDate = Time(endDateString)

    domoticz.log('Contract End Date: ' .. contractEndDate.rawDate, domoticz.LOG_INFO)

    if domoticz.time.rawDate == contractEndDate.rawDate then
        domoticz.log('Energy contract ends today!', domoticz.LOG_INFO)
    else
        domoticz.log('Energy contract does not end today', domoticz.LOG_INFO)
    end
end

Re: Date and leap year handling in dzvents

Posted: Sunday 10 August 2025 11:10
by Gingerpale
Hi madpatrick,
This works perfectly. Many thanks for the swift reply.