Add a utc_now() function?

You know, it would seriously make my day if you guys added something like a utc_now() function that could be used as an alternative to the horrible builtin lua time apis.

All I want is a simple function for getting a utc timestamp, with no buggering about with timezones. Maybe getting better than 1-second precision would be nice too. Maybe you could slip such a function into the sys module?

Look at how difficult this is in pure lua:
http://lua.2524044.n2.nabble.com/os-time-and-timezones-td7461931.html

Honestly, the implementations that I’ve found are complex enough that I can’t even convince myself that they work in all cases…

And before anyone asks, I need absolute time, not just relative time values that can be used to calculate deltas (such as socket.gettime()).

Ultimately, I may decide that having a trusted timestamp is necessary, in which case I might have to do a request to an ntp server or something, though it would be nice to not rely on having an internet connection.

I’m guessing that this could be done using a native extension as well, once we have support for all platforms. Do you happen to know the platform specific functions involved?

1 Like
function utc_now()
	return os.time(os.date("!*t"));
end

print(utc_now())

Can someone who knows Lua better explain why this is bad?

in which case I might have to do a request to an ntp server or something

If time is super important and system time can’t be trusted this seems like the right thing to do.

1 Like

I’ve never looked into the formatting options for os.date(), but it seems as though “!*t” is what @ericsroy is after. ! = Coordinated Universal Time and *t = table with data parameters, and os.time() converts this into a timestamp.

But, judging from the link provided by ericsroy it seems as though the whole thing might have to be more complex than what you suggested.

BTW, what kind of app/game are you creating @ericsroy?

@Pkeod Actually, from what i’ve read, that solution isn’t quite right. Apparently, os.date("!*t") will give you utc time, but os.time always assumes that the provided time table is in your current time zone! Totally nuts, I know… Anyway, you might want to edit your post with a warning to that effect so people don’t copy-paste that solution into their games.

@britzl Yes, native extensions could provide me with a solution eventually. Not sure about the appropriate apis on all platforms, but for anyone interested, here’s how I usually get a utc timestamp (in milliseconds) on windows:

// FILETIME corresponding to unix epoch
// This constant came from the postgres source code.
static const uint64_t unixEpochOffset = 116444736000000000;

FILETIME ft = {};
GetSystemTimeAsFileTime(&ft);

ULARGE_INTEGER largeInt;
largeInt.HighPart = ft.dwHighDateTime;
largeInt.LowPart = ft.dwLowDateTime;

int64_t utcNowMs = (int64_t)((largeInt.QuadPart - unixEpochOffset) / 10000ull);

I’m assuming it’s far simpler than that on more unixy platforms, or in languages with good time apis.

I’m working on a idle/passive game, so it’s important that I be able to accurately measure the time since the app last ran, so I can fast-forward my simulation and provide the user with the rewards that have accrued since they’ve been away. If I worked in the local timezone, I might get bitten by daylight savings time.

And of course, you can imagine how a user might manipulate their device time to try to get more rewards - I’ll need to decide how much I care about this.

1 Like

If I were making a game that depends on time (either some casual clicker stuff or a mechanic that provides periodic rewards to a single-player game), I would probably utilise NTP servers with a fallback to device time in case the user doesn’t have an internet connection. I assume this would stop people who aren’t tech-savvy from cheating the system.

I have also devised a pretty neat trick that might be applicable to this scenario - how about letting the player reap rewards either way, but when they gain internet access run a routine that compares the last time they’ve played the game with current time provided by an NTP server? And afterwards, if the time on file is ahead of network time, punish them somehow :smiley:

Yes, I think you’re right, probably ntp with fallback to device is the way to go.

As for punishing them, I’m not sure… what if they legitimately changed their device time for some reason? (just got off a plane flight, etc). Since my players won’t be competing against one another, I think letting them cheat is probably fine. I still like the idea of a trusted NTP time though, just so the game doesn’t seem broken if the device time changes.

Maybe I’ll implement an NTP time checker using lua socket and share it with people here…

Good point. How about setting some bounds, e.g. if the time is ahead by more than a day or two?

Can you think of any other legitimate reasons on why to change device time other than simply moving between different timezones?

1 Like

Yeah - you wouldn’t expect more than a handful of hours difference for normal use cases. Good suggestion

You should be able to use LuaJIT’s FFI feature to call this code directly from Lua without going through a native extension.

What about other platforms? Is it kosher to call native functions via the FFI on iOS for example?

Here’s a module I wrote for doing NTP time checks with luasocket:

4 Likes