在项目中遇到需要同步服务器时间的需求,解决方案如下。
1.App启动后获取服务器当前时间时间戳ServerTimeStampA,获取成功后保存至本地,并同时保存客户端当前时间时间戳LocalTimeStampA;
2.在需要使用到服务器时间时,先获取客户端当前时间时间戳LocalTimeStampB,再获取interval = LocalTimeStampB - LocalTimeStampA,服务器时间时间戳即为:ServerTimeStampA + interval,将其转换为时间即可;
3.如果获取服务器时间失败,则视服务器时间与本地时间相同;
4.使用NSSystemClockDidChangeNotification监测系统时间发生改变 ,如果系统时间发生改变则重新获取一次服务器时间。
// 获取服务器时间并保持至本地
double serverTimeStamp = 1502534359727.2739; // 模拟服务器当前时间时间戳,精确到毫秒
[[NSUserDefaults standardUserDefaults] setDouble:serverTimeStamp forKey:kLastSaveServerTimeStamp];
double currentLocalTimeStamp = [[NSDate date] timeIntervalSince1970] * 1000;
[[NSUserDefaults standardUserDefaults]setDouble:currentLocalTimeStamp forKey:kLastSaveLocalTimeStamp];
[[NSUserDefaults standardUserDefaults] synchronize];
获取服务器时间有两种方法
方法一:服务端同学给一个获取服务器时间接口;
方法二:通过HTTP Header来获取服务器时间(注:时间格式以RFC-7231中定义的"HTTP日期"格式来发送,见下图)。
// 获取HTTP Header
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSDictionary *allHeaders = response.allHeaderFields;
HTTP Header
将HTTP Header中的时间转换为NSDate可使用NSDate+InternetDateTime.m
// 转换方法
NSDate *inputDate = [NSDate dateFromInternetDateTimeString:dateServer formatHint:DateFormatHintRFC822];
NSDate *inputDate = [NSDate dateFromRFC822String:dateServer];
为NSDate创建Category
// 服务器当前时间戳(精确到毫秒)
+ (double)serverCurrentTimeStamp{
// 最后保存的服务器时间戳
double lastSaveServerTimeStamp = [[NSUserDefaults standardUserDefaults] doubleForKey:kLastSaveServerTimeStamp];
// 最后保存服务器时间戳时的本地时间戳
double lastSaveLocalTimeStamp = [[NSUserDefaults standardUserDefaults] doubleForKey:kLastSaveLocalTimeStamp];
// 当前本地时间戳
double currentLocalTimeStamp = [[NSDate date] timeIntervalSince1970] * 1000;
if (lastSaveLocalTimeStamp != 0 || lastSaveServerTimeStamp != 0) {
return lastSaveServerTimeStamp + (currentLocalTimeStamp - lastSaveLocalTimeStamp);
}else{
// 如果没有获取到服务器时间,说明客户端还没开始用过,则视服务器时间与本地时间相同
return currentLocalTimeStamp;
}
}
// 服务器当前时间
+ (NSDate *)serverCurrentDate{
double serverTimeStamp = [NSDate serverCurrentTimeStamp] / 1000;
NSDate *serverDateZone = [NSDate dateWithTimeIntervalSince1970:(serverTimeStamp)];
NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
NSInteger interval = [timeZone secondsFromGMTForDate:serverDateZone];
NSDate *serverDate = [serverDateZone dateByAddingTimeInterval:interval];
return serverDate;
}
参考链接
1.时间与日期处理
2.通过AFNetworking获取服务器时间
3.iOS关于时间的处理
联系作者:简书·DH_Fantasy 新浪微博·DH_Fantasy
版权声明:自由转载-非商用-非衍生-保持署名(CC BY-NC-ND 3.0)
网友评论