Is there any way to get actual current Date irrespective of system time and date?

Apple Recommended

Replies

Seen this 5 yr. old SO thread? Hint: server based is your friend.


https://stackoverflow.com/questions/14964318/how-can-i-get-the-actual-date-and-time-if-the-device-date-and-time-are-inaccurat

You’ll need to get it from a server, either your own or one (whose security) you trust.

What’s your high-level goal here? KMT et al are correct in that getting a timestamp from a trusted server is the only guaranteed solution to this problem. If that doesn’t work for you then there may be other paths you can take, but this depends on your specific requirements. If you can outline those requirements here, I’d be happy to elaborate.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

We have a option to mark attendance from application. So for that we need the current time to mark attendance. And if user is offline still he can mark attendance and this will sync later. So in this case if some one changes the system time, we can not get the actual time. In this way user can fake his attendance. We need a solution to get actual current time even if the user is offline. Or need to know if the time is mannually set or autometically so that we can restrict user. Please help.

As I mentioned earlier there’s no general solution to this problem, but there are steps you can take to improve the situation, either by tracking system clock changes or by detecting attempts to cheat.

There are basically two sources of time on iOS [1]:

  • Wall time, as returned by gettimeofday and things layered on top of that like NSDate

  • Mach absolute time, as returned by mach_absolute_time and things layered on top of that like CACurrentMediaTime

Neither of these will meet your requirements:

  • Wall time can be changed by the user, something you’ve already noticed

  • Mach absolute time gets reset when the device restarts, and stops ‘ticking’ when the device is asleep

Given the above, your only real option is to use the network to get a timestamp from some trusted source.


A common complaint about the above is that it does not work if the device has no Internet connection. Clearly that’s a problem for you, so I recommend that you file an enhancement request describing the trusted timestamp features that you need.

Please post your bug number, just for the record.


As to workarounds, the best workaround I’ve found so far is to exploit the fact that the kern.boottime sysctl variable is modified when a) the device restarts, and b) when the user adjusts the time [2]. So, when you have access to the network you should record a timestamp that consists of:

A. The value from your trusted source on the network

B. The value from gettimeofday (or NSDate)

C. The value of kern.boottime

Note You read the kern.boottime sysctl variable using sysctlbyname. For an example of how to do this, check out this post.

Later on, if you no longer have access to the network, you can call gettimeofday again (B'), and use the difference between A and B to calculate A'. You can then get kern.boottime again (C') and, if C' is approximately equal to C, you know that you can reasonably trust A'.

IMPORTANT I recommend that you ignore small changes to kern.boottime to avoid problems when the system does its regular time synchronisation. Some of that is done using adjtime, which doesn’t affect kern.boottime, but that’s not guaranteed to always be the case.

Of course, you should use the network for your default timestamp source and only rely on the above if you can’t get to the network.

The drawback to this approach is that, if the user restarts their device, your app won’t be able to get a trusted time value until they bring the device back on to the network. Ultimately you’ll have to decide if that’s an acceptable tradeoff.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"

[1] There are other sources of time (like GPS time, on devices with GPS, and the cellular network time, on devices with cellular) but neither of these are accessible via an API.

Also, moderns version of iOS have various clocks available via clock_gettime. While these don’t change the story for you, they can be useful in other situations. For example, CLOCK_MONOTONIC_RAW is like mach_absolute_time but it increments while the device is asleep (technically, it’s adjusted as the device comes out of sleep).

Dude. You are a godsend to this community. 👍

Thanks for the kind words. But actually I’m kinda cheating here (-: I didn’t have to research and write the above from scratch; it’s basically a copy’n’paste of a DTS response I sent to a developer last year.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

There is TrueTime.swift on GitHub: https://github.com/instacart/TrueTime.swift

It uses the NTP based approach