Forum

> > CS2D > Scripts > Math function to calculate days
Forums overviewCS2D overview Scripts overviewLog in to reply

English Math function to calculate days

7 replies
To the start Previous 1 Next To the start

old Math function to calculate days

Mami Tomoe
User Off Offline

Quote
Hello all friends from around the world, hope you're doing well! (this greeting does not include non friends (to be a friend all you have to do is believe))

I've got a problem where I created (manually after a lot of trial and error...) a script that counts down using a seconds variable and this is how I calculate the UI that represents the countdown:

1
2
3
local hours = ((reset_counter - (reset_counter % 3600)) / 3600)
local minutes = math.floor((reset_counter - (hours * 3600)) / 60)
local seconds = (reset_counter - (hours * 3600)) % 60

I'm quite worried about how this looks to someone who's decent at math, anyways it did the trick until I needed the script to present days as well! And I know it's going to take me hours to make it work so I'm wondering if anyone here has enough free time to guide me on how to make this more efficient and make it calculate days as well!

TL;DR: Use a seconds variable to calculate days, hours, minutes and seconds.

old Re: Math function to calculate days

Bowlinghead
User Off Offline

Quote
What about having 3 variables for the time (hours, minutes, seconds)?
Instead of calculating the display-time each time you need it, calculate it once and save it.
Here is something similiar:
Code >

old Re: Math function to calculate days

DC
Admin Off Offline

Quote
Does os.date work in CS2D? I'm not sure. But if it does you can use it this way:
os.date('!*t', YOUR-TIME-IN-SECONDS)

which will give you a fancy table.
See http://lua-users.org/wiki/OsLibraryTutorial

Otherwise it's quite trivial to get the total number of days from a duration in seconds with simple math:

1
2
local dayInSeconds = 24*60*60
local days = reset_counter / dayInSeconds

If you want that day value NOT to affect the rest of your values you have to subtract it from the reset_counter value. Same way as you did it with the other formulas.

I would recommend to write everything in a more comprehensive way (more lines but each line is shorter and easy to understand):
1
2
3
4
5
6
7
8
9
10
11
12
local minInSecs = 60
local hourInSecs = 60 * minInSecs
local dayInSecs = 24 * hourInSecs

local t = reset_counter
local days = math.floor(t / dayInSecs)
t = t - (days * dayInSecs)
local hours = math.floor(t / hourInSecs) 
t = t - (hours * hourInSecs)
local minutes = math.floor(t / minInSecs) 
t = t - (minutes * minInSecs)
local seconds = t

Untested. But I hope that helps to understand more easily how it works.

Edit:
user Bowlinghead's approach can be legit as well. It highly depends on the use case though.

The biggest risk when "counting" time continuously however is that you will be off from the REAL time more and more because there are always micro delays. This won't be a huge problem if you just count over a short time frame. It will become a huge problem though when you count over a longer period of time and expect legit real time values.

You should NEVER (!) use any of CS2D's time hooks (e.g. cs2d lua hook ms100 or cs2d lua hook second or cs2d lua hook minute) to "count" time. They never run perfectly at time X. There are always tiny delays caused by CPU spikes etc. These delays can silently add up to a big delay when "counting" time.

Best practice for measuring (real!) time EXACTLY over whatever period you want:
Get the system time via
os.time()
twice:
1) First: at the START time you want to measure something (save this in a variable)
2) Second: at the CURRENT time (or end time) you want to measure something

Your duration will then always be CURRENT-START (or END-START)
edited 5×, last 16.04.20 07:08:32 pm

old Re: Math function to calculate days

Mami Tomoe
User Off Offline

Quote
@user DC: Is the time difference for a week long countdown using the second hook going to be more than like 5 minutes? If not then this wont bother me.

Also is there a way to make a countdown using os.time?
I want a simple countdown that'll cause a round restart every week (that can be changed later to even a month if I feel like it)

> Needs to be efficient
> Needs to be able to display days,hours,minutes,seconds later


@user Bowlinghead: Your approach is great but it's too much for what I need...

old Re: Math function to calculate days

DC
Admin Off Offline

Quote
a week = 7 * 24 * 60 * 60 seconds = 604800 seconds

Assuming CS2D runs at 60 FPS all the time the inaccuracy per second hook call can be up to 1000 / 60 = 16.667 ms (worst case for perfect 60 FPS). 16.667 because one main loop iteration can take up to that time at 60 FPS and any time hook can only be executed at one specific point in the main loop.

604800 * 16.667 ms = ~10080201 ms = 10080 sec = 168 min = 2.8 HOURS!

But 16.667 is worst case for 60 FPS. It's probably more like half of it.
2.8 h / 2 = 1.4 h. Still a huge lot.

I hope I did the math right. I'm not 100% sure. But it sounds legit.

Note: It can be even worse if the server doesn't hit perfect 60 FPS all the time!

So no, it's WAY worse than 5 minutes. Just don't count time like that. Especially not with second hook or even quicker ones. The minute hook would, of course, add up 60 times less imprecision so it would cause much less trouble.

Still using absolute timestamps as explained above is the only right way to do it. It's done like that everywhere with everything for very good reasons

old Re: Math function to calculate days

DC
Admin Off Offline

Quote
user Mami Tomoe has written
Also is there a way to make a countdown using os.time?
I want a simple countdown that'll cause a round restart every week (that can be changed later to even a month if I feel like it)

> Needs to be efficient
> Needs to be able to display days,hours,minutes,seconds later

Sorry missed that part.
Yes, that's possible. I basically already explained how to do that.

Do this whenever you want to reset the timer to 0:
local resetTime = os.time()


To get the elapsed time you simply do
local elapsedTime = os.time() - resetTime


Now you can use your or my code above which calculates days/hours/mins/secs from the time in seconds value and display it the way you want.

If you want to update that display each second you can still use cs2d lua hook second to do so. The difference is that you only use the hook to display the time. You don't use it anymore to manually count the time. That's not necessary because you are working with a start timestamp (resetTime) and the current time (os.time()).

This way you won't have any errors which add up over time.
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview