Page 1 of 1
Date and time calculations in dzvents
Posted: Tuesday 29 January 2019 13:11
by rrozema
dzvents is my first contact with lua. I can understand lua's logic constructs and even the event based logic in dzvents. But the time and date functionality keeps eluding me. Can someone please post some sample code that illustrates the proper way to do these actions in dzvents?
I will give some examples of things i'd like to know:
- Test if a particular datetime is after (greater than) a given datetime.
- Calculate the datetime value that is n seconds after a given datetime. And calculate the datetime value that is n minutes, hours, days, weeks, months, years, etc after a given datetime.
- Calculate the datetime value that is n seconds before a given datetime.
- Calculate the number of seconds or minutes or hours or etc between 2 given datetime values.
- Calculate only the date part of a given datetime value.
Calculate only the time part of a given datetime value.
- Get the current time in UTC (no daylight saving time differences)
- Calculate the UTC equivalent for a given datetime plus timezone.
Re: Date and time calculations in dzvents
Posted: Tuesday 29 January 2019 17:40
by waaren
rrozema wrote: ↑Tuesday 29 January 2019 13:11
dzvents is my first contact with lua. I can understand lua's logic constructs and even the event based logic in dzvents. But the time and date functionality keeps eluding me. Can someone please post some sample code that illustrates the proper way to do these actions in dzvents?
Don't know if these example are a proper way of fiddling with date / times but atleast they are A way.
Code: Select all
-- timeExamples.lua
return {
on = {
timer = { "every minute"},
-- timer = { "never"},
},
logging = { level = domoticz.LOG_DEBUG,
marker = "timeExamples" },
execute = function(dz)
local Time = require('Time')
local now = Time() -- current time
local month
local today = dz.time.rawDate
local tonight = today .. " 23:59"
local function lpad(str, len, char)
if char == nil then char = ' ' end
return string.rep(char, len - #str) .. str
end
local function logWrite(str,level) -- Support function for shorthand debug log statements
dz.log(tostring(str),level or dz.LOG_DEBUG)
end
local function header(str)
logWrite("");logWrite(lpad("",80,"="));logWrite(lpad(str,42));logWrite(lpad("",80,"="))
end
local function isFirstTimeEarlier(firstTime,lastTime) -- Test if a particular datetime is after (greater than) a given datetime.
return firstTime.compare(lastTime).compare < 0
end
local function newdate(base,secs,minutes,hours,days,years)
local day, month, year = string.match('03-05-2014', '(%d%d)-(%d%d)-(%d%d%d%d)')
end
local function makeSeconds(sec, min, hour, day, month, year ) -- simplified (month=30, year=365)
if sec == nil then sec = 0 end
if min == nil then min = 0 else min = min * 60 end
if hour == nil then hour = 0 else hour = hour * 3600 end
if day == nil then day = 0 else day = day * 24 * 3600 end
if year == nil then year = 0 else year = year * 365 * 24 * 3600 end
return sec + min + hour + day + year
end
local function getTimezone() -- in seconds
local now = os.time()
return os.difftime(now, os.time(os.date("!*t", now)))
end
local function getTZOffset(timezone)
local h, m = math.modf(timezone / 3600)
return string.format("%+.4d", 100 * h + 60 * m)
end
header("From time()")
logWrite ("now ==>> " .. tostring(now))
logWrite ("now.year ==>> " .. tostring(now.year))
logWrite ("now.month ==>> " .. tostring(now.month))
logWrite ("now.day ==>> " .. tostring(now.day))
logWrite ("now.hour ==>> " .. tostring(now.hour))
logWrite ("now.min ==>> " .. tostring(now.min))
logWrite ("now.sec ==>> " .. tostring(now.sec))
logWrite ("now.isdst ==>> " .. tostring(now.isdst)) -- daylight saving time
header("From dz.time()")
logWrite ("now ==>> " .. tostring(dz.time))
logWrite ("now.year ==>> " .. tostring(dz.time.year))
logWrite ("now.month ==>> " .. tostring(dz.time.month))
logWrite ("now.day ==>> " .. tostring(dz.time.day))
logWrite ("now.hour ==>> " .. tostring(dz.time.hour))
logWrite ("now.min ==>> " .. tostring(dz.time.min))
logWrite ("now.sec ==>> " .. tostring(dz.time.sec))
logWrite ("now.isdst ==>> " .. tostring(dz.time.isdst)) -- daylight saving time
logWrite ("now.isUTC ==>> " .. tostring(dz.time.isUTC)) -- UTC time
header("from dz.time")
logWrite ("current ==>> " .. tostring(dz.time.raw))
logWrite ("today ==>> " .. tostring(today))
logWrite ("tonight ==>> " .. tostring(tonight))
header("constructed time objects")
local pastTime = Time('2016-3-12 07:35:00')
local futureTime = Time('2022-5-10 07:35:00')
local playTime = Time(dz.time.raw)
logWrite ("pastTime ==>> " .. tostring(pastTime.raw))
logWrite ("futureTime ==>> " .. tostring(futureTime.raw))
logWrite ("Playtime ==>> " .. tostring(playTime.raw))
header("check times")
logWrite("pastTime > now ? ==>> " .. tostring(isFirstTimeEarlier(pastTime,playTime)))
logWrite("futureTime > now ? ==>> " .. tostring(isFirstTimeEarlier(futureTime,playTime)))
header("Time calculations")
-- os.time calculates the number of seconds since 1/1/1970 00:00:00 given a time object
logWrite("now ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTime)))
-- os.date formats the number o seconds from os.time in the requested format
logWrite("now + 120 sec ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTime) + makeSeconds(nil,2)))
logWrite("now + some time ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTime) + makeSeconds(1,2,3,4,5,6))) -- plus 6 years, 5 months etc
logWrite("now - some time years ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTime) - makeSeconds(1,2,3,4,5,6))) -- minus 6 years, 5 months etc
header("Time deltas")
logWrite("years between now and future ==>> " .. dz.utils.round(pastTime.compare(futureTime).days / 365,1))
logWrite("months between now and future ==>> " .. dz.utils.round(pastTime.compare(futureTime).days / 30,1))
logWrite("days between now and future ==>> " .. pastTime.compare(futureTime).days)
logWrite("hours between now and future ==>> " .. pastTime.compare(futureTime).hours)
logWrite("minutes between now and future ==>> " .. pastTime.compare(futureTime).minutes)
logWrite("seconds between now and future ==>> " .. pastTime.compare(futureTime).seconds)
header("parts of date")
logWrite("Datepart only ==>> " .. playTime.rawDate)
logWrite("Timepart only ==>> " .. playTime.rawTime)
header("UTC stuff")
local playTimeUTC = os.date("!*t")
logWrite("UTC Time ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTimeUTC)))
logWrite("UTC Time ISO ==>> " .. playTime.getISO())
logWrite("UTC Time diff ==>> " .. getTimezone() / 3600)
logWrite("UTC Time diff ==>> " .. getTZOffset(getTimezone()))
logWrite("UTC Time calc ==>> " .. os.date("%A, %d %B %Y (%H:%M:%S)",os.time(playTime) - makeSeconds(getTimezone())))
logWrite("")
end
}
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 6:43
by rrozema
Very helpful @waaren. Thank you
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 11:12
by dannybloe
Why don't you use dzVents
Time object for this. Afaik it can do all of the above. Especially when you use the compare function.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 12:11
by rrozema
I agree, that api looked promising, however i did try it and it didn't quite work as expected at the time. I think it was because of the many different date/time storage formats lua provides... At least to me it wasn't clear how to get done what i needed. I will try again and let you know what i find.
I didn't get the compare to work at first. From waaren's example i now see how it is supposed to work, but the syntax looks too complex to me. I'm much more familiar with something like having a property function <object>.gt(<another object>) returning true or false. Plus other variants like .gte() for greater-than-or-equal, .lt() for less-than, .lte() for less-than-or-equal, .eq() for equal and .neq() for not-equal.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 12:55
by dannybloe
The .compare attribute of the compare() results should give you just that information I believe. I created the Time object and the compare function so you don't have to deal with Lua's horrible date/time support.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 13:24
by rrozema
I know that now. But it is not intuitive: I couldn't figure out how to work with it without an example of how to use it. And even now it still looks overcomplicated with a conpare() function and an additional compare property.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 13:26
by dannybloe
Well, it's one line of code. But if that's too complicated then I'd say use the Lua functions. You'll love them :-p
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 13:30
by rrozema

thanks. I'm just suggesting that further improvements may be possible.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 15:01
by dannybloe
I know

Ideas and pull-request are always welcome.
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 21:50
by papoo
in Time documentation i dont see timestamp support. is there a way to use with? (to use with some APi for example)
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 22:12
by waaren
papoo wrote: ↑Sunday 03 February 2019 21:50
in Time documentation i dont see timestamp support. is there a way to use with? (to use with some APi for example)
Try
same as
Re: Date and time calculations in dzvents
Posted: Sunday 03 February 2019 23:13
by papoo
thanks, work fine
Re: Date and time calculations in dzvents
Posted: Thursday 02 April 2020 12:03
by Piacco
Hello,
I'm trying to get the actual month and the past month as an string.
But I'm getting this error:
2020-04-02 11:55:41.607 Error: dzVents: Error: (3.0.1) Get actual and past month: ...oticz/scripts/dzVents/generated_scripts/Actual_Month.lua:18: attempt to call a string value (field 'monthName')
Could someone explain me what is going wrong
Code: Select all
return
{
on = {
devices = { 'Tussenruimte'} ,
},
logging =
{
level = domoticz.LOG_DEBUG,
marker = "Get actual and past month"
},
execute = function(dz, device)
os.time(dz.time)
local ActualMonth = dz.time.monthName()
local PastMonth = dz.time.monthName(-1)
dz.log(ActualMonth)
dz.log(PastMonth)
end
}
Greetings,
Piacco
Re: Date and time calculations in dzvents [Solved]
Posted: Thursday 02 April 2020 13:09
by waaren
Piacco wrote: ↑Thursday 02 April 2020 12:03
I'm trying to get the actual month and the past month as an string. Could someone explain me what is going wrong
You try to use an attribute as a function.
Code: Select all
return
{
on =
{
devices =
{
'Tussenruimte'
},
},
logging =
{
level = domoticz.LOG_DEBUG,
marker = 'Get actual and past month',
},
execute = function(dz)
local ActualMonth = dz.time.monthName -- monthName is attribute so do not use ()
dz.log('Actual month is ' .. ActualMonth, dz.LOG_DEBUG)
-- addDays is a method (function) of dz.time . It returns a time object
local someTime = dz.time.addDays(-1 * dz.time.day) -- make a new time object current minus today's days (is last day of previous month)
local lastMonth = someTime.monthName
dz.log('Last month is ' .. lastMonth, dz.LOG_DEBUG)
end
}
Re: Date and time calculations in dzvents
Posted: Wednesday 08 April 2020 21:50
by Piacco
Thanks again Waaren
Now I can go on with my script
Re: Date and time calculations in dzvents
Posted: Saturday 27 February 2021 20:36
by Piacco
I have a little script to wake up my chickens. It works well, I just want to make it a little bit smarter.
When the time between sunset and sunrise is more than 13 hours, then the light does not need to be switched on.
Has dzVents the possibility to extract sunrise and sunset?
ps. What happend when sunrise is equal to 6 o'clock, is the light turned on and off?
Code: Select all
return {
on = {
timer = {
'at 06:00',
'at 20:00',
'at sunrise',
'at sunset',
},
},
logging = { level = domoticz.LOG_DEBUG, marker = 'Kipenhok' },
execute = function(dz)
if dz.time.matchesRule("between 06:00 and sunrise") == true then -- lamp aan tussen 6 uur en zonsopkomst
dz.devices('Kippenhok').switchOn().checkFirst()
end
if dz.time.matchesRule("at sunrise") == true then -- lamp uit na zonsopkomst
dz.devices('Kippenhok').switchOff().checkFirst()
end
if dz.time.matchesRule("between sunset and 20:00") == true then -- lamp aan tussen zonsondergang en 20 uur
dz.devices('Kippenhok').switchOn().checkFirst()
end
if dz.time.matchesRule("at 20:00") == true then -- lamp uit om 20 uur
dz.devices('Kippenhok').switchOff().checkFirst()
end
end
}
edit: I have changed the script, i tink this should be working
Code: Select all
return {
on = {
timer = {
-- 'every minute',
'at 06:00',
'at 20:00',
'at sunrise',
'at sunset',
},
},
logging = { level = domoticz.LOG_DEBUG, marker = 'Kippenhok' },
execute = function(dz)
local checkTimeInMinutesSunrise = 6 * 60 + 30 -- 6:30
local checkTimeInMinutesSunset = 19 * 60 + 30 -- 19:30
local timeDifferenceSunsetSunrise = dz.time.sunsetInMinutes - dz.time.sunriseInMinutes
local checkHours = 13 * 60 -- is 13 uur
if timeDifferenceSunsetSunrise < checkHours then -- Als tijd tussen zonopkomst en zonsondergang > 13 uur dan geen licht
if dz.time.matchesRule("at 06:00") then -- Lamp aan om 6 uur en zonsopkomst is niet om 6:30
if dz.time.sunriseInMinutes > checkTimeInMinutesSunrise then
dz.devices('Kippenhok').switchOn().checkFirst()
end
elseif dz.time.matchesRule("at sunrise") then -- lamp uit na zonsopkomst
dz.devices('Kippenhok').switchOff().checkFirst()
elseif dz.time.matchesRule("at sunset") then -- lamp aan tussen zonsondergang en 20 uur
if dz.time.sunsetInMinutes < checkTimeInMinutesSunset then
dz.devices('Kippenhok').switchOn().checkFirst()
end
elseif dz.time.matchesRule("at 20:00") then -- lamp uit om 20 uur
dz.devices('Kippenhok').switchOff().checkFirst()
end
end
end
}