能否从iPhone GPS获取原子钟时间戳?

9

我正在寻找一种可靠的获取时间的方式。它不能被篡改并且需要离线工作。因此不能使用网络时间,也不能在设置中使用用户时间,也不能使用自上次重启以来的BSD运行时间。我想知道GPS是否可以使用原子钟来工作,从而访问该信息。

谢谢


你知道 iPhone 在“飞行模式”下关闭 GPS 吗?此外,有很多地方你无法获得 GPS 信号,所以即使你可以访问时间组件(我预计不可通过API获取),也不能保证其可用性。 - kdgregory
没问题。如果GPS没有信号也没关系。我可以强制只在我之前测试过GPS可用性的位置采样未被篡改的时间。 - Maxm007
1
我甚至认为获取运营商时间也是可以接受的,但是 API 中似乎也没有这个选项。 - Maxm007
你说,“如果手机使用GPS作为时间同步源”。它是否会同步到GPS时间?你怎么知道? - user565139
5个回答

7

这段代码可以获取GPS时间:

#import <CoreLocation/CoreLocation.h>

CLLocation* gps = [[CLLocation alloc]
                       initWithLatitude:(CLLocationDegrees) 0.0
                       longitude:(CLLocationDegrees) 0.0];
NSDate* now = gps.timestamp;

然而它似乎不是防篡改的。

我在iPhone 4(iOS 6.1)上使用飞行模式尝试了这段代码,即使这时候也能正确给出时间。但不幸的是,这个时间似乎随着系统时钟的变化而变化。真糟糕。

有趣的是,我发现(仍处于飞行模式),如果您篡改系统时钟(在将“设置自动”切换到 off 后),然后将“设置自动”重新切换为 on ,该设备会毫不费力地恢复实际(原始)时间。 即使在循环手机电源之后,此方法也有效。因此,似乎设备内部维护了类似于防篡改时间的东西。但是如何访问它呢?

P.S. 2010年关于此的讨论。倒数第二条评论的作者曾尝试在避难所中进行此操作:因此可以确定该手机并未从任何外部来源获得原始时间。

附录,2013年7月

发现了几篇关于另一种时间测量方式的帖子(这里这里这里):系统内核启动时间。可以通过类似以下的调用来访问它:sysctlbyname("kern.boottime", &boottime, &size, NULL, 0);。不幸的是,即使没有重新启动,它也会随着用户调整的日期和时间而改变。另一个函数gettimeofday()同样依赖于用户定义的时间。


3
我查看了一下,并发现 gps.timestamp 返回的时间与 [NSDate date] 完全相同。 - kelin
实际上,时间戳属性返回“确定此位置时的时间戳”。 - Matthieu Rouif

4

NSDate及其CF对应项都基于用户可控时间,因此不是防篡改的。

据我所知,没有直接获取GPS时间或运营商时间的开放API。但是,您可以检查mach_absolute_time以获取自上次启动以来未经篡改的时间,并可能将其用于至少了解自应用程序唤醒以来经过了多长时间(而不会在应用程序运行时潜在地被篡改)。

mach_absolute_time取决于设备的处理器。它返回自上次重启(也称为正常运行时间)以来的滴答数。为了以人类可读的形式获得它,您必须通过mach_timebase_info(一种比率)的结果进行修改,它将返回十亿分之一秒(或纳秒)。为了使其更易用,我使用以下类似的函数:

#include <mach/mach_time.h>

int getUptimeInMilliseconds()
{
    static const int64_t kOneMillion = 1000 * 1000;
    static mach_timebase_info_data_t s_timebase_info;

    if (s_timebase_info.denom == 0) {
        (void) mach_timebase_info(&s_timebase_info);
    }

    // mach_absolute_time() returns billionth of seconds,
    // so divide by one million to get milliseconds
    return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}

0
即便您可以从GPS获取时间,也应该知道 GPS时间并不完全等同于UTC。不过,iPhone中的GPS接收器可能会替您处理这个问题。

现今的GPS芯片还可以提供UTC时间,因此对GPS时间有两种解释:来自GPS的UTC时间和实际GPS时间(目前大约比UTC时间慢14秒)。 - AlexWien

-2

这会获取当前日期和时间:

NSDate *now = [NSDate date];

这将是您可以得到的最可靠的。iPhone 上的内部时钟将在获得访问 NTP 服务器的权限时进行更新。如果手机使用 GPS 作为时间同步源,它也将用于更新可以通过上述方法访问的同一系统范围内的时钟。
CoreFoundation 的等效代码类似于:
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();

返回与普通UNIX自纪元以来的秒时间戳相当的CoreFoundation。


[NSDate date] 返回的时间可以被用户更改。 - kelin

-2

时间测量的黄金标准是美国和全球各个政府时间观测站。它们提供原子时间,这在全球范围内使用。苹果应该使用这个。如果他们想要与手机塔同步,应该有一个备用的内部时间。如果塔或GPS系统发生故障,所有人都会留下错误的时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接