Quote:cause they only get updated in draw...
millis() is updated independently of draw(), but you can check it only if draw() is there (either checking in draw or needing draw to activate keyboard/mouse events where you can also check it).
Now, indeed, that's only in draw() that you can check it reliably, since that's the heart beat of your sketch. In general, it is called more often than 1s, so it can work.
But I wouldn't use millis() % 1000 to check one second, indeed, because draw() isn't called that often. You have to use the good old
(millis() - timeSinceLastEvent >= 1000) pattern. So you get a precision equals to the current frame rate, which isn't so bad.
Do you really need super precise time beating (ie. below 17ms precision for the default 60FPS)?
Another solution to try is to spawn another thread, making it sleep for 1s, then calling the method of your choice. Although you can get a drift if that method takes time to process... Or the sleep time must be adjusted to clock time.