New timestamp class

For only tutorials. If you would like to post a tutorial here, first post it elsewhere (scripts, general, etc.) and private message me (Administrator) a link to the thread. I'll move it for you.
Post Reply
Message
Author
User avatar
Administrator
Site Admin
Posts: 5317
Joined: Sat Jan 05, 2008 4:21 pm

New timestamp class

#1 Post by Administrator » Thu Jan 01, 2015 1:53 pm

Time is something we work with very often in our scripts, but has historically been a bit of a bother to manage cleanly. So, today, I decided to write up a class to handle it that is roughly based off Carbon for PHP.

To use this module, you need to require it at the top of your main script like so:

Code: Select all

require('timestamp');
This new class, Timestamp, supports method-chaining. That is, function calls to modify its time value will return a new object instead of actually modify the calling object. This means we can do something like this:

Code: Select all

local later = Timestamp:now():addhours(1):addMinutes(30);
This will give us a Timestamp object that is 'now' plus an hour and a half. It also supports adding/subtracting everything else you could want: seconds, days, months, years. You can also create arbitrary timestamps for any date and time you can think of. Or get the timestamp for now, today, yesterday, or tomorrow.


Here's an example:

Code: Select all

	local now = Timestamp:now();
	print("Now:\t", now);

	local past = now:subSeconds(30);
	print("-30 sec:", past);
	print("\t\tIs past?", past:isPast(), past:diffForHumans(), "\n");

	local later = now:addHours(12):addMinutes(90):addSeconds(32);
	print("Later:\t", later);

	local today = Timestamp:today();
	print("Today:\t", today);

	local yesterday = Timestamp:yesterday();
	print("Yesterday:", yesterday);

	local nextMonth = now:addMonths(1);
	print("Next month:", nextMonth);

	local arbitrary = Timestamp(2016, 6, 12, 8, 52);
	print("Arbitrary:", arbitrary);

	print("Year-month:", arbitrary:format("%Y-%m"));

	print("Now less than arbitrary?", now < arbitrary);
Output:

Code: Select all

Now:            2015-01-01  12:38:51
-30 sec:        2015-01-01  12:38:21
                Is past?        true    30 seconds ago

Later:          2015-01-02  02:09:23
Today:          2015-01-01  00:00:00
Yesterday:      2014-12-31  00:00:00
Next month:     2015-02-01  12:38:51
Arbitrary:      2016-06-12  08:52:00
Year-month:     2016-06
Now less than arbitrary?        true
When adding/subtracting months, it properly keeps track of how many days are in each month instead of just assuming some number. If you add/subtract any number that overflows its bounds (such as adding 13 months when there are only 12 in a year), it will also increment the required fields.

The isPast() method will be quite handy. Very often we want to trigger some event(s) after some time has past. Instead of:

Code: Select all

doSomethingTimestamp = os.time() + 3;

...

if( os.time() > doSomethingTimestamp ) then
  doSomething();
end
We can simply:

Code: Select all

doSomethingTimestamp = Timestamp:now():addSeconds(3);

...

if( doSomethingTimestamp:isPast() ) then
  doSomething();
end

What other features do you think could be useful?

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: New timestamp class

#2 Post by rock5 » Thu Jan 01, 2015 9:00 pm

How about the difference between 2 times? Eg.

Code: Select all

start = Timestamp:now()
...
print("Elapsed time: ",Timestamp:now()-start)
So I take it this is now very accurate, no fractions of a second?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5317
Joined: Sat Jan 05, 2008 4:21 pm

Re: New timestamp class

#3 Post by Administrator » Fri Jan 02, 2015 11:29 am

Sure, difference between times makes sense, but I wasn't sure how to go about it. Returning a new Timestamp doesn't make sense there as it would act like like some time around 1970 (UNIX/POSIX timestamps all count the number of seconds since the epoch). Returning the number of seconds difference between the two should work though. We could also have diffInMinutes(), diffInHours(), diffInDays(), etc. functions. I think I also want to work in timezones.



This class does not use high-precision timers. There's one major problem with those: even though they use 64-bit integers, they run out of space very quickly and can only store up to a few years. Also, they depend entirely on things like the user's hardware and when it was booted up, so the timers are really only valid during runtime of a single process to keep track of very fine time differences. Things that they are terrible for: network applications (only valid on the originating machine), saving to file (may not be valid when reading it), working with real time values (ex. we want to compare the time to 5 o'clock), or displaying it to the user. POSIX timestamps take care of all those things much more readily.

Now, we could have a hybrid: internally use the high-precision timer to record fractions of a second and store that with the class. Time operations like now(), or difference functions could include the fractional seconds, but things like today(), or creating from an arbitrary date, would not bother with such granularity. Of course, again, the problem becomes whether or not this is actually necessary (at this point, why not just use the high-precision timer class?), and the problem of actually calculating it (because high-precision timers are again only useful for comparing against each other--not against an actual clock).

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: New timestamp class

#4 Post by rock5 » Fri Jan 02, 2015 2:07 pm

Returning diff in seconds seems adequate. 'time' seems to be adequate for timing things.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests