PDA

View Full Version : [Programming] Determine Difference in Time



pr6i6e6st
May 4th, 2020, 08:42
edit: almost have it, bust still off. when a day changes, my current date in minutes comes back as less than my startdate in minutes for some reason. so once the calendar has been changed and it hits midnight, it returns the difference to be greater than 1440 minutes then sets the time to start over for another cycle.



--Timer Functions--
function setStartTime(rActor, sFirst)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
nStartTime = getCurrentDateinMinutes(rActor);
DB.setValue(nodeActor, "" .. sFirst .. ".starttime", "number", nStartTime);
Debug.console("setStartTime called; nStartTime = ", nStartTime);
end

function getStartTime(rActor, sFirst)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
nStartTime = getCurrentDateinMinutes(nRound)
FetchStartTime = DB.getValue(nodeActor, "" .. sFirst .. ".starttime", 0);

return FetchStartTime;
end

function getCurrentDateinMinutes()
local nMinutes = DB.getValue("calendar.current.minute");
local nHours = DB.getValue("calendar.current.hour");
local nDays = DB.getValue("calendar.current.day");
local nMonths = DB.getValue("calendar.current.month");
local nYears = DB.getValue("calendar.current.year");
Debug.console("getCurrentDateinMinutes called; nMinutes, nHours, nDays, nMonths, nYears =", nMinutes, nHours, nDays, nMonths, nYears);

nHoursinMinutes = convertHourstoMinutes(nHours);
nDaysinMinutes = convertDaystoMinutes(nDays);
nMonthsinMinutes = convertMonthssnowtoMinutes(nMonths);
nYearsinMinutes = convertYearsnowtoMinutes(nYears);
Debug.console("getCurrentDateinMinutes called; nHoursinMinutes, nDaysinMinutes, nMonthsinMinutes, nYearsinMinutes =", nHoursinMinutes, nDaysinMinutes, nMonthsinMinutes, nYearsinMinutes);

nDateinMinutes = nHoursinMinutes + nDaysinMinutes + nMonthsinMinutes + nYearsinMinutes + nMinutes;
Debug.console("getCurrentDateinMinutes called; nDateinMinutes =", nDateinMinutes);

return nDateinMinutes;
end
--Compare times --
function isTimeGreaterThan(rActor, sFirst, nCompareBy)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
local nStartTime = getStartTime(rActor, sFirst);
local nCurrentTime = getCurrentDateinMinutes();

local nDifference = nCurrentTime - nStartTime;
Debug.console("isTimeGreaterThan called; nDifference, nCurrentTime, nStartTime = ", nDifference, nCurrentTime, nStartTime);
if nDifference > nCompareBy then
return true;
elseif nDifference <= nCompareBy then
return false;
end
end

function getTimeDifference(rActor, sFirst, nCompareBy)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
local nStartTime = DB.getValue(nodeActor, "" .. sFirst .. ".starttime", 0);
local nCurrentTime = getCurrentDateinMinutes();

nDifference = nCurrentTime - nStartTime;
Debug.console("isTimeGreaterThan called; nDifference, nCurrentTime, nStartTime = ", nDifference, nCurrentTime, nStartTime);
return nDifference;
end


--convert time functions --
function convertHourstoMinutes(nNumber)
local nMinutesTotaled = nNumber * 60;
return nMinutesTotaled;
end
function convertMinutestoHours(nNumber)
local nHoursTotaled = nNumber / 60;
return nHoursTotaled;
end
function convertHourstoDays(nNumber)
local nDaysTotaled = nNumber / 24);
return nDaysTotaled;
end
function convertDaystoHours(nNumber)
local nHoursTotaled = nNumber * 24;
return nHoursTotaled;
end
function convertMinutestoDays(nNumber)
local nHoursTotaled = convertMinutestoHours(nNumber);
local nDaysTotaled = convertHourstoDays(nHoursTotaled);
return nDaysTotaled;
end
function convertDaystoMinutes(nNumber)
local nDaysinHours = convertDaystoHours(nNumber);
local nMinutesTotaled = convertHourstoMinutes(nDaysinHours);
return nMinutesTotaled;
end
function convertMonthtoHours(nNumber)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");

nDays = getDaysInMonth(nNumber);
nHoursTotaled = convertDaystoHours(nDays);
Debug.console("convertMonthtoHours called; nMonth, nYear, nDays, nHoursTotaled = ", nMonth, nCount, nDays, nHoursTotaled);
return nHoursTotaled;
end
function convertMonthtoMinutes(nNumber)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");

nDays = getDaysInMonth(nMonth);
nMinutesTotaled = convertDaystoMinutes(nDays);
Debug.console("convertMonthtoMinutes called; nMonth, nYear, nDays, nMinutesTotaled = ", nMonth, nYear, nDays, nMinutesTotaled);
return nMinutesTotaled;
end
function convertYeartoHours(nNumber)
local nYearinDays = 365;
bisLeapYear = isLeapYear(nNumber);
if bisLeapYear == true then
nYearinDays = nYearinDays + 1;
end
nYearinHours = nYearinDays * 24;
return nYearinHours;
end
function convertYeartoMinutes(nNumber)
local nYearinHours = convertYeartoHours(nNumber);
nYearinMinutes = nYearinHours * 60;
return nYearinMinutes;
end

function convertYearsnowtoMinutes(nYear)
local nYearCount = 0;
local nYearinDays = 365;
local nLeapYear = 0;
local nDaysTotaled = 0

for i=1,nYear do
if nYearCount < nYear then
nYearinHours = convertYeartoHours(i);
nMinutesTotaled = nMinutesTotaled + convertHourstoMinutes(nYearinHours);
nYearCount = nYearCount + 1;
end
end
return nMinutesTotaled;
end
function convertMonthssnowtoMinutes(nMonth)
local nCount = 0;
local nMinutes = 0;

for i=1,nMonth do
if nCount < nMonth then
nMinutes = convertMonthtoMinutes(nCount) + nMinutes;
nCount = nCount + 1;
end
Debug.console("convertMonthsnowtoMinutes called; nCount, nMonth, nMinutes =", nCount, nMonth, nMinutes);
end
return nMinutes;
end

--extra calculations --
function getDaysInMonth(nMonth)
local nYear = DB.getValue("calendar.current.year", 0);
local nDays = DB.getValue("calendar.data.periods.period" .. nMonth .. ".days", 0);

if nMonth == 2 then
local nYear = DB.getValue("calendar.current.year", 0);
if (nYear % 400) == 0 then
nVar = 1;
elseif (nYear % 100) == 0 then
nVar = 0;
elseif (nYear % 4) == 0 then
nVar = 1;
end
else
nVar = 0;
end
nDays = nDays + nVar;

return nDays;
end

function isLeapYear(nYear)
return nYear%4==0 and (nYear%100~=0 or nYear%400==0)
end


thanks for any advice and suggestions guys! you've helped me get this far, and i feel like i've vastly improved since i began!

pr6i6e6st
May 4th, 2020, 15:34
edit: i've got it! it works! i've edited the control/script to reflect what currently works
original text---
i've tried using it with this control and script, and it will get to the ColdConditionManager.Roll(nodeActor) but it's not taking into account the time difference for some reason? so it just rolls every time the minute changes, but i've got game.turn set to 10.



<number_ct_crosslink name="hungry" source="conditions.hungry">
<anchored to="isstressed" position="above" offset="30,-40" />
<invisible />
<script>
function onInit()
DB.addHandler("calendar.current.day", "onUpdate", onSourceChanged);
DB.addHandler("calendar.current.hour", "onUpdate", onSourceChanged);
DB.addHandler("calendar.current.minute", "onUpdate", onSourceChanged);
DB.addHandler("combattracker.round", "onUpdate", onSourceChanged);
onCheckTime();
end

function onCheckTime()
nDay = DB.getValue("calendar.current.day");
nMinute = DB.getValue("calendar.current.minute");
nHour = DB.getValue("calendar.current.hour");
end

function onClose()
DB.removeHandler("calendar.current.day", "onUpdate", onSourceChanged);
DB.removeHandler("calendar.current.hour", "onUpdate", onSourceChanged);
DB.removeHandler("calendar.current.minute", "onUpdate", onSourceChanged);
end
function onValueChanged()
local rActor = ActorManager.resolveActor(window.getDatabaseNode() );
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
if getValue() == 1 then
sFirst = "hungry";
CharManager.setLastDay(nodeActor, sFirst);
end
end
function onSourceChanged()
local rActor = ActorManager.resolveActor(window.getDatabaseNode() );
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
if DB.getValue(nodeActor, "conditions.hungry", 0) == 1 then
sFirst = "hungry";
TimeLimit = 10000 * DB.getValue(nodeActor, "game.turn", 0);
TimeStapDifference = CharManager.getDateDifference(nodeActor, sFirst);
if CharManager.isTimeGreaterThan(nodeActor, sFirst, TimeLimit) then
ColdConditionManager.Roll(nodeActor);
CharManager.setLastDay(nodeActor, sFirst);
end
end
end

</script>
</number_ct_crosslink>

pr6i6e6st
May 5th, 2020, 03:20
Eureka!

pr6i6e6st
May 5th, 2020, 05:23
or would a function that converts the whole date to minutes be more accurate? like this? because i'm having trouble nailing down when an hour changes when we want to look at minutes with the other code



function convertDatetoMinutes()
DayinMinutes = ((DB.getValue("calendar.current.day", 0) * 24) * 60);
HourinMinutes = (DB.getValue("calendar.current.day", 0) * 60);

DateinMinutes = MonthinMinutes + DayinMinutes + HourinMinutes;
return DateinMinutes;
end

superteddy57
May 5th, 2020, 06:56
This is some good work. Sorry not sure what would be better, but wanted to drop a line that this is some good stuff. Keep up the good work.

pr6i6e6st
May 5th, 2020, 21:26
This is some good work. Sorry not sure what would be better, but wanted to drop a line that this is some good stuff. Keep up the good work.

thank you!

now, i almost have it really figured out with this new function. i can't understand what i'm doing wrong that i can't get the days to add up. the following script seems to do everything just fine. it counts all the days in each month up to the current month, but it's not adding them together for some reason?



function getDaysInMonth(nMonth)
local nYear = DB.getValue("calendar.current.year", 0);
local nDays = DB.getValue("calendar.data.periods.period" .. nMonth .. ".days", 0);

if nMonth == 2 then
local nYear = DB.getValue("calendar.current.year", 0);
if (nYear % 400) == 0 then
nVar = 1;
elseif (nYear % 100) == 0 then
nVar = 0;
elseif (nYear % 4) == 0 then
nVar = 1;
end
end

nVar = 0;
nDays = nDays + nVar;

return nDays;
end

function isLeapYear(nYear)
return nYear%4==0 and (nYear%100~=0 or nYear%400==0)
end


function getThatinSeconds(nRound, nTurn, nShift)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");
local nDays = 0;
local nDaysCount = 0;


local nCount = 0;
Debug.console("getThatinSeconds called; nMonth, nLeapYear = ", nMonth, nLeapYear);

for i=1,nMonth do
if nCount < nMonth then
nDays = getDaysInMonth(nCount) + nDays;
nCount = nCount + 1;
Debug.console("getThatinSeconds called; nMonth, nCount, nDays = ", nMonth, nCount, nDays);
end

DB.setValue("monthindays", "number", nDaysCount);
end

DayinSeconds = (((nDays) * 24) * 60) * 60;
HourinSeconds = (DB.getValue("calendar.current.hour", 0) * 60) * 60;
MinuteinSeconds = DB.getValue("calendar.current.minute", 0) * 60;
RoundinSeconds = DB.getValue("combattracker.round") * nRound;

DateinMinutes = DayinMinutes + HourinMinutes + MinuteinSeconds + RoundinSeconds;
Debug.console("getThatinSeconds called; DayinMinutes, HourinMinutes, MinuteinSeconds, RoundinSeconds, DateinMinutes = ", DayinMinutes, HourinMinutes, MinuteinSeconds, RoundinSeconds, DateinMinutes );
return DateinMinutes;
end

function getThatinMinutes(nRound)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");
local nDays = 0;
local nCount = 0;
local nYearCount = 0;

Debug.console("getThatinMinutes called; nMonth, nLeapYear = ", nMonth, nLeapYear);
for i=1,nMonth do
if nCount < nMonth then
nDays = getDaysInMonth(nCount) + nDays;
nCount = nCount + 1;
Debug.console("getThatinMinutes called; nMonth, nCount, nDays = ", nMonth, nCount, nDays);
end
end
nDaysinYear = 365 + nLeapYear;
for i=1,nYear do
if nYearCount < nYear then
nLeapYear = isLeapYear(i);
nYearinDays = nYearinDays + nLeapYear;
nYearCount = nYearCount + 1;
end
end

nDays = nDays + nYearinDays;

DayinMinutes = ((nDays) * 24) * 60;
HourinMinutes = (DB.getValue("calendar.current.hour", 0) * 60);
RoundinMinutes = DB.getValue("combattracker.round", 0) * nRound / 60;

DateinMinutes = DayinMinutes + HourinMinutes + RoundinMinutes;
Debug.console("getThatinMinutes called; DayinMinutes, HourinMinutes, RoundinMinutes, DateinMinutes = ", DayinMinutes, HourinMinutes, RoundinMinutes, DateinMinutes);
return DateinMinutes;
end

function setStartTime(nodeChar, sFirst, nRound)
nStartTime = getThatinMinutes(nRound)
DB.setValue(nodeChar, "" .. sFirst .. ".starttime", "number", nStartTime);
Debug.console("setStartTime called; nStartTime = ", nStartTime);
end

function getStartTime(nodeChar, sFirst)
nStartTime = getThatinMinutes(nRound)
FetchStartTime = DB.getValue(nodeChar, "" .. sFirst .. ".starttime", 0);

return FetchStartTime;
end

function isTimeGreaterThan(nodeChar, sFirst, nCompareBy)
local nRound = DB.getValue(nodeChar, "game.round", 0);
local nStartTime = DB.getValue(nodeChar, "" .. sFirst .. ".starttime", 0);
local nCurrentTime = DB.getThatinMinutes(nRound);

local nDifference = nCurrentTime - nStartTime;
if nDifference >= nCompareBy then
return true;
else
return false;
end
end


edit: GOT IT! had to remove the Local from nDays when counting each month. SUPERB!

i've edited this post to have my full set of time counting functions

pr6i6e6st
May 6th, 2020, 20:37
alright, i ALMOST have it, i swear to god. the current problem is that my start time keeps coming out larger than my current time for some reason, apparently as soon as the day has changed. so somewhere i must be getting a negative value that is removing from my final returned time. this is what i have, any idea?



--Timer Functions--
function setStartTime(rActor, sFirst)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
nStartTime = getCurrentDateinMinutes(rActor);
DB.setValue(nodeActor, "" .. sFirst .. ".starttime", "number", nStartTime);
Debug.console("setStartTime called; nStartTime = ", nStartTime);
end

function getStartTime(rActor, sFirst)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
nStartTime = getCurrentDateinMinutes(nRound)
FetchStartTime = DB.getValue(nodeActor, "" .. sFirst .. ".starttime", 0);

return FetchStartTime;
end

function getCurrentDateinMinutes()
local nMinutes = DB.getValue("calendar.current.minute");
local nHours = DB.getValue("calendar.current.hour");
local nDays = DB.getValue("calendar.current.day");
local nMonths = DB.getValue("calendar.current.month");
local nYears = DB.getValue("calendar.current.year");
Debug.console("getCurrentDateinMinutes called; nMinutes, nHours, nDays, nMonths, nYears =", nMinutes, nHours, nDays, nMonths, nYears);

nHoursinMinutes = convertHourstoMinutes(nHours);
nDaysinMinutes = convertDaystoMinutes(nDays);
nMonthsinMinutes = convertMonthssnowtoMinutes(nMonths);
nYearsinMinutes = convertYearsnowtoMinutes(nYears);
Debug.console("getCurrentDateinMinutes called; nHoursinMinutes, nDaysinMinutes, nMonthsinMinutes, nYearsinMinutes =", nHoursinMinutes, nDaysinMinutes, nMonthsinMinutes, nYearsinMinutes);

nDateinMinutes = nHoursinMinutes + nDaysinMinutes + nMonthsinMinutes + nYearsinMinutes + nMinutes;
Debug.console("getCurrentDateinMinutes called; nDateinMinutes =", nDateinMinutes);

return nDateinMinutes;
end
--Compare times --
function isTimeGreaterThan(rActor, sFirst, nCompareBy)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
local nStartTime = getStartTime(rActor, sFirst);
local nCurrentTime = getCurrentDateinMinutes();

local nDifference = nCurrentTime - nStartTime;
Debug.console("isTimeGreaterThan called; nDifference, nCurrentTime, nStartTime = ", nDifference, nCurrentTime, nStartTime);
if nDifference > nCompareBy then
return true;
elseif nDifference <= nCompareBy then
return false;
end
end

function getTimeDifference(rActor, sFirst, nCompareBy)
local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
local nRound = DB.getValue(nodeActor, "game.round", 0);
local nStartTime = DB.getValue(nodeActor, "" .. sFirst .. ".starttime", 0);
local nCurrentTime = getCurrentDateinMinutes();

nDifference = nCurrentTime - nStartTime;
Debug.console("isTimeGreaterThan called; nDifference, nCurrentTime, nStartTime = ", nDifference, nCurrentTime, nStartTime);
return nDifference;
end


--convert time functions --
function convertHourstoMinutes(nNumber)
local nMinutesTotaled = nNumber * 60;
return nMinutesTotaled;
end
function convertMinutestoHours(nNumber)
local nHoursTotaled = nNumber / 60;
return nHoursTotaled;
end
function convertHourstoDays(nNumber)
local nDaysTotaled = nNumber / 24);
return nDaysTotaled;
end
function convertDaystoHours(nNumber)
local nHoursTotaled = nNumber * 24;
return nHoursTotaled;
end
function convertMinutestoDays(nNumber)
local nHoursTotaled = convertMinutestoHours(nNumber);
local nDaysTotaled = convertHourstoDays(nHoursTotaled);
return nDaysTotaled;
end
function convertDaystoMinutes(nNumber)
local nDaysinHours = convertDaystoHours(nNumber);
local nMinutesTotaled = convertHourstoMinutes(nDaysinHours);
return nMinutesTotaled;
end
function convertMonthtoHours(nNumber)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");

nDays = getDaysInMonth(nNumber);
nHoursTotaled = convertDaystoHours(nDays);
Debug.console("convertMonthtoHours called; nMonth, nYear, nDays, nHoursTotaled = ", nMonth, nCount, nDays, nHoursTotaled);
return nHoursTotaled;
end
function convertMonthtoMinutes(nNumber)
local nYear = DB.getValue("calendar.current.year", 0);
local nMonth = DB.getValue("calendar.current.month");

nDays = getDaysInMonth(nMonth);
nMinutesTotaled = convertDaystoMinutes(nDays);
Debug.console("convertMonthtoMinutes called; nMonth, nYear, nDays, nMinutesTotaled = ", nMonth, nYear, nDays, nMinutesTotaled);
return nMinutesTotaled;
end
function convertYeartoHours(nNumber)
local nYearinDays = 365;
bisLeapYear = isLeapYear(nNumber);
if bisLeapYear == true then
nYearinDays = nYearinDays + 1;
end
nYearinHours = nYearinDays * 24;
return nYearinHours;
end
function convertYeartoMinutes(nNumber)
local nYearinHours = convertYeartoHours(nNumber);
nYearinMinutes = nYearinHours * 60;
return nYearinMinutes;
end

function convertYearsnowtoMinutes(nYear)
local nYearCount = 0;
local nYearinDays = 365;
local nLeapYear = 0;
local nDaysTotaled = 0

for i=1,nYear do
if nYearCount < nYear then
nYearinHours = convertYeartoHours(i);
nMinutesTotaled = nMinutesTotaled + convertHourstoMinutes(nYearinHours);
nYearCount = nYearCount + 1;
end
end
return nMinutesTotaled;
end
function convertMonthssnowtoMinutes(nMonth)
local nCount = 0;
local nMinutes = 0;

for i=1,nMonth do
if nCount < nMonth then
nMinutes = convertMonthtoMinutes(nCount) + nMinutes;
nCount = nCount + 1;
end
Debug.console("convertMonthsnowtoMinutes called; nCount, nMonth, nMinutes =", nCount, nMonth, nMinutes);
end
return nMinutes;
end

--extra calculations --
function getDaysInMonth(nMonth)
local nYear = DB.getValue("calendar.current.year", 0);
local nDays = DB.getValue("calendar.data.periods.period" .. nMonth .. ".days", 0);

if nMonth == 2 then
local nYear = DB.getValue("calendar.current.year", 0);
if (nYear % 400) == 0 then
nVar = 1;
elseif (nYear % 100) == 0 then
nVar = 0;
elseif (nYear % 4) == 0 then
nVar = 1;
end
else
nVar = 0;
end
nDays = nDays + nVar;

return nDays;
end

function isLeapYear(nYear)
return nYear%4==0 and (nYear%100~=0 or nYear%400==0)
end

pr6i6e6st
May 7th, 2020, 22:00
Yeah, I’m still struggling with this. I can’t quite understand entirely what’s happening but I think the process is somehow calculating the time change strangely. Say, if the day changes, it will calculate the hour up to 24 then again when it changes to 0. So I’m terms of minutes and the order of the process, it thinks we’ve lost an hour. That’s a theory anyway but I’m not sure how to eliminate that.

damned
May 7th, 2020, 23:42
Put more debug in your code - tonnes of it - until you find the glitch...?

pr6i6e6st
May 8th, 2020, 17:39
Put more debug in your code - tonnes of it - until you find the glitch...?
Alright, so here’s what appears to be the problem. I was using handlers for each facet of time (one for minutes, one for hours, one for days, months, years). And it seems that, say, when hours hit 24, before they revert to 0 but seemingly after the hour has been increased, is when we check and set our times if the time in minutes is greater. So it’s like 6 hours and 60 minutes instead of 5 hours and 0 minutes, so our “start time” comes out larger than our current time when we check the next facet.

So I need some kind of gate that waits until all value changes have completed before doing our check/set time processes. Or to use a function from the calendar manager as a trigger rather than value changes of individual facets. Any suggestion on how to accomplish that?

edit: added a data log. ignore the 246 error and the rads error and the recursive call. i know what they are and they don't deal with this part of the code.

here, we start our hungry condition which sets our time, and then we change the time by one minute, going from year 5, month 12, hour 23, minute 59 all the way to year 6, month 1, hour 0, minute 0. and it checks it every step of the way.

edit: so, figuring the issue is in our handlers, i'm getting more consistent results by creating a new database number to reference. basically, in the controls for changing time, after the function ends, i build a new number based on the final date. then use that as my handler. it means i have to put the setvalue in a couple spots but that's livable if it solves all my problems

Edit: the handlers did indeed appear to be my problem. Things seem to be working and I’m mostly through fixing it all in my ruleset.