xcode 从 Apple 服务器获取日期和时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9075303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 23:09:52  来源:igfitidea点击:

Get Date and Time from Apple Server

iosxcode

提问by kraitz

I'm developing an app that can only be used during a certain time of the day. I can't get the local device time because the user can easily change the device time thereby allowing access to the application for any time of the day.

我正在开发一个只能在一天中的特定时间使用的应用程序。我无法获取本地设备时间,因为用户可以轻松更改设备时间,从而允许在一天中的任何时间访问应用程序。

Is there a way to get the current date and time from an Apple server (or if not,) is there any other way?

有没有办法从 Apple 服务器获取当前日期和时间(如果没有,还有其他方法吗?

采纳答案by Johan Karlsson

I think that you should be using an Internet time server. They are using a standardized protocol called NTP. The iOS has built-in support for reading NTP server time, but this is not accessible to you as an application developer. Either you implement this yourself, or you could maybe use an open source library, like ios-ntpor HS NTP. I have not used any of them myself. It is probably a good idea to check the position of the device and figure out the timezone, to get a real bulletproof solution.

我认为您应该使用 Internet 时间服务器。他们使用称为NTP的标准化协议。iOS内置支持读取 NTP 服务器时间,但作为应用程序开发人员的您无法访问。要么你自己实现,要么你可以使用开源库,比如ios-ntpHS NTP。我自己没有使用过它们中的任何一个。检查设备的位置并找出时区,以获得真正的防弹解决方案可能是一个好主意。

Here you could read more about the servers and stuff; NIST Internet Time Service

在这里你可以阅读更多关于服务器和东西的信息; NIST 互联网时间服务

Ideally, you should have a list of servers in the application. If one of them fails, you call the next NTP server in the list.

理想情况下,您应该在应用程序中有一个服务器列表。如果其中一个失败,则调用列表中的下一个 NTP 服务器。

回答by Karan Shah

- (NSDate *) CurrentDate 
{
    if ([self hasInternetConnectivity]) // this tests Internet connectivity based off Apple's Reachability sample code
    {
        NSSURL * scriptUrl = [NSURL URLWithString: @"http:// <yoursite>. Com / <the 2 line php script>. Php"];
        NSData * data = [NSData dataWithContentsOfURL: scriptUrl];

        if (data! = nil) {
            NSString * tempString = [NSString stringWithUTF8String: [data bytes]];
            NSDate * currDate = [NSDate dateWithTimeIntervalSince1970: [tempString doubleValue]];
            NSLog (@ "String returned from the site is:% @ and date is:% @", tempString, [currDate description]);
           return currDate;
             }
        else {
           NSLog (@ "nsdata download failed");
           return [NSDate date];
        }
    }
    else {
    NSLog (@ "InternetConnectivity failed");
        return [NSDate date];
    }
}

回答by huync

You can use that open source to get time from default NTP server, or choose your server: https://github.com/huynguyencong/NHNetworkTime

您可以使用该开源从默认 NTP 服务器获取时间,或选择您的服务器:https: //github.com/huynguyencong/NHNetworkTime

[[NHNetworkClock sharedNetworkClock] syncWithComplete:^{
        NSLog(@"%s - Time synced %@", __PRETTY_FUNCTION__, [NSDate networkDate]);
    }];

And use:

并使用:

NSDate *networkDate = [NSDate networkDate];

回答by Nerrolken

Karan's answer had some typos, and also failed to check for a response of "0" instead of just "nil". (I implemented it in my app and I got several false-positives from weak connections or unauthorized networks.)

Karan 的回答有一些拼写错误,并且也未能检查“0”而不是“nil”的响应。(我在我的应用程序中实现了它,我从弱连接或未经授权的网络中得到了几个误报。)

I've adapted it below, and added the corresponding server code for those who don't know what Karan was referring to. This is implemented as a category method in an NSDate extension, so you can call it using [NSDate verifiedDate];

我在下面对其进行了修改,并为那些不知道Karan指的是什么的人添加了相应的服务器代码。这是作为 NSDate 扩展中的类别方法实现的,因此您可以使用[NSDate verifiedDate];

+(NSDate*)verifiedDate {
    if([self hasInternetConnectivity]) {
        NSURL *scriptUrl = [NSURL URLWithString:@"http://[yourwebsite].com/timestamp.php"];
        NSData *data = [NSData dataWithContentsOfURL: scriptUrl];

        if(data != nil) {
            NSString *tempString = [NSString stringWithUTF8String:[data bytes]];

            if([tempString doubleValue] > 946684800) { // Date is at least later than 2000 AD, or else something went wrong
                NSDate *currDate = [NSDate dateWithTimeIntervalSince1970:[tempString doubleValue]];
                NSLog(@"verifiedDate: String returned from the site is: %@ and date is: %@", tempString, [currDate description]);
                return currDate;
            } else {
                NSLog(@"verifiedDate: Server returned false timestamp (%@)", tempString);
                return [NSDate date];
            }
        } else {
            NSLog(@"verifiedDate: NSData download failed");
            return [NSDate date];
        }
    } else {
        NSLog(@"verifiedDate: InternetConnectivity failed");
        return [NSDate date];
    }
}

And here's the server code, stored in your server's root folder as "timestamp.php"

这是服务器代码,作为“timestamp.php”存储在服务器的根文件夹中

<?php
    echo(time());
?>

回答by Eric Yuan

I believe your requirement can be met by some web services which return json data.

我相信一些返回 json 数据的 Web 服务可以满足您的要求。

One of them are jsontest.com: http://date.jsontest.com. Here is what it returns:

其中之一是jsontest.com:http://date.jsontest.com。这是它返回的内容:

{
   "time": "02:11:29 AM",
   "milliseconds_since_epoch": 1513563089492,
   "date": "12-18-2017"
} 

The "milliseconds_since_epoch" represents milliseconds since 1970, so it's easy to convert to Date,by using Date.init(timeIntervalSince1970: milliseconds_since_epoch/1000). Then we can use Calendarclass to get local time.

"milliseconds_since_epoch" 表示自 1970 年以来的毫秒数,因此使用Date.init(timeIntervalSince1970: milliseconds_since_epoch/1000). 然后我们可以使用Calendarclass 来获取本地时间。

回答by JustForHelp

Here is my code, using 2 different web services in case one of them is down:

这是我的代码,使用 2 个不同的 Web 服务,以防其中一个出现故障:

NSString *urlString = [NSString stringWithFormat:@"http://date.jsontest.com"];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSError *error;

NSNumber *milliSecondsSince1970 = nil;

if (data != nil) {
    NSDictionary *json =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    milliSecondsSince1970 = [json valueForKey:@"milliseconds_since_epoch"];

    NSLog(@"milliSecondsSince1970 = %@", milliSecondsSince1970);
}
else {
    urlString = [NSString stringWithFormat:@"https://currentmillis.com/time/seconds-since-unix-epoch.php"];
    url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    data = [[NSData alloc] initWithContentsOfURL:url];

    if (data!=nil) {

        NSString *dbleStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        double dble = [dbleStr doubleValue]*1000;
        milliSecondsSince1970 = [NSNumber   numberWithDouble:dble];
        NSLog(@"milliSecondsSince1970 currentMillis = %@", milliSecondsSince1970);
    }

    else {
        double dateIntervalInSecondsSince1970 = [NSDate date].timeIntervalSince1970*1000;
        milliSecondsSince1970 = [NSNumber numberWithDouble:dateIntervalInSecondsSince1970] ;

        NSLog(@"milliSecondsSince1970 NSDate = %@", milliSecondsSince1970);
    }

}

回答by Στ?ργιο? Ρ?ζο?

If you don't want use other web services you can validate the receipt every time the user opens the app , apple will return to you a json file which includes current gmt , I use the receipt to check for subscription status and I fetch the time from this file

如果您不想使用其他网络服务,您可以在每次用户打开应用程序时验证收据,苹果将返回给您一个包含当前 gmt 的 json 文件,我使用收据检查订阅状态并获取时间从这个文件