[Glk] System clock

I’d find a system clock function useful, so was thinking we could start listing some use cases so Zarf can decide on the spec change more easily.

Firstly it would be good to have a ms timer. This could fit into a signed 32 int fine… we wouldn’t need to care about bigger time intervals.

A second function should provide the full time. This won’t fit into a single int so we can’t use unix time, so it would probably be better to return each part of time as a separate number. UTC time should be returned. Parts to include: Year, Month, Day, Day Of Year (1-365), Day of Week (0-6), Hour (0-23), Minute, Second, ms, time zone delta (in seconds?)

(Keeping in mind that I won’t be able to jump into these question for real for two months…)

When you say an “ms timer”, do you mean finer granularity for timed events? I hadn’t thought of that, but it makes sense. It’s easy to add to old interpreters, even if you don’t want to take effort – just drop resolution.

For providing the clock time, I do want to offer the Unix time. It’s the easiest way to compute “how long have you been playing” type questions. 32 bits is shy, but if we return an unsigned integer, it’ll be okay until 2106? We’ll have to warn people to use unsigned comparison, of course, which is a nuisance.

I definitely want to offer a time-tuple API as well. I think you’ve named the standard C structure, which is what we should use.

Does the API need to offer common operations on these values? To-string, from-string, deltas on tuples? These could be done in game code, but they’re traditionally a nuisance and offered by the OS/library.

Unix time starts on like January 1st, 1979 or so, right? We could just pick a more recent date. We’d be able to not require unsigned, the spec would be good longer, and the conversion is just a subtraction or addition with a constant number, which the spec would say.

January 1st, 1970: by 1979 Unix was already everywhere. :slight_smile: But yes, a more recent offset would seem sensible.

Combining these two ideas: if we were going to move the epoch anyway, we could put zero in the future, then we could use signed values but still use all 32 bits. Too tricksy?

I think to-string and from-string get complicated. It won’t be common to print an ISO-whatever-it-is date in a game, except maybe to a data file. So to be useful you really need a format string. If you go that far, you might as well just add printf instead (or a cut-down version of it). Plus if you print day and month names you have to decide what language they are in.

If they could be done in game code, they could be done in a game extension. Not all games will make heavy use of that API’s whiz-bang features, so I see no real need to lay yet another requirement on the 'terp authors et al about it.

Clever. I might ask that the new epoch still be on the first of January, that way in case there’s confusion and a UNIX function is called on value by accident, the wrong answers will still have the month & day right. It’s easier to intuit what’s going on if only the year is too far forward than if the whole date is completely different.

If any given signed 32-bit epoch is good for +68 years, then starting the counter in 2010 would only take us to 2078, which is well short of 2106.

Personally I’m not that excited about even the 2106 date, unless we think the IF of the 22nd century will have forced a move to 64-bit VMs. It just seems like a misstep to build in an expiration date, such that games relying on modern Glk functionality could behave erratically a century from now. That’s not so much time if you consider that the history of IF already spans 34 years.

What about a scheme where the library could return both seconds since the epoch, and the modified Julian day on which that epoch commenced? Then the library could select an epoch such that elapsed values would stay within a 32 bit range, and the game could correctly identify the real calendar dates if desired.

Okay, I agree that to-string and from-string are too much work.

I’m not a fan of shifting the base date either.

Variable epoch? Oy. Plus, converting Unix to MJD looks like a hassle.

How about this: Unix epoch, but scale the base date. You call get_current_time(x), and this returns the Unix time divided by x (truncated to 32 bits). (Signed division, so we can represent old years.) If x is 1, it’s just truncation. If x is 60, you get minutes since the epoch. Since the most common use case is “how long have I been playing?”, this provides an easy way to get that answer in minutes, and it won’t break until the year 6000. If you really need a 64-bit Unix time, you can get it in two calls with a little math.

We’d also need calls to convert this scaled form to a tuple, and vice versa.

Well I’m hoping we can reach consensus earlier than then. These should be easier to specify than to implement.

Yeah I want them for some performance tests. I had originally been thinking to use timers, but if we can get sub-second data that would be even better.

Another option would be to offer 64 bit unix time in two words. Library code could handle comparisons.

I think the library could do to/from-string for tuples, as well as deltas, but turning a tuple into unix time might be useful. As would turning an arbitrary unix time into a tuple too. If you had those functions then maybe don’t provide tuple time in the api, just convert it.