//開機時間 #define SWStartTime @"startTime" //服務器時間 #define SWServerTime @"serverTime" //登錄時的待機時長 #define SWSinceNow @"sinceNow"
1.獲取待機時長
<br>/**
* 待機時間(從系統啟動的那一刻開始獲取的時間間隔)
*/
+ (time_t)uptime
{
struct timeval boottime;
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
size_t size = sizeof(boottime);
time_t now;
time_t uptime = -1;
(void)time(&now);
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
{
uptime = now - boottime.tv_sec;
}
return uptime;
}
2.存儲服務器時間及待機時長
/**
* 存儲服務器時間及待機時長
*
* @param serverTime 服務器時間
*/
+ (void)firstTimeWithLogin:(NSString *)serverTime
{
NSTimeInterval timer = (NSTimeInterval)[self uptime];
NSString *sinceNow = [NSString stringWithFormat:@"%f",timer];
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
//存儲登錄時獲取的服務器時間
[UserDefaults setObject:serverTime forKey:SWServerTime];
//存儲登錄時獲取的待機時長
[UserDefaults setObject:sinceNow forKey:SWSinceNow];
}
3.獲得當前的時間(以服務器時間為基准)
+ (NSDate *)dateOfNow
{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
//取出登錄時獲取的服務器時間
NSString * serverText = [UserDefaults objectForKey:SWServerTime];
NSDate *FirstServer = [formatter dateFromString:serverText];
NSString *firstText = [UserDefaults objectForKey:SWSinceNow];
CGFloat first = firstText.floatValue;
NSTimeInterval timer = (NSTimeInterval)[self uptime];
CGFloat second = (CGFloat)timer;
//差值
CGFloat finaly = second - first;
NSTimeInterval interval = (NSTimeInterval)finaly;
//最後的時間
NSDate *finalyDate = [FirstServer dateByAddingTimeInterval:interval];
return finalyDate;
}
4.深度探討 為什麼獲取待機時間不用SystemUptime這種方法? 答案 :SystemUptime這種獲取待機時間的方式在我們設備深度睡眠的時候,獲取的值會有誤差,而上面我所用的方法不會。親測!!! 如果我要獲取手機的開機時間,怎麼辦? 答案 :
/**
* 獲得開機時間
*/
+ (NSString *)getUpTime{
NSString * proc_useTiem;
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, 0};
size_t miblen = 4;
size_t size;
//返回0,成功;返回-1,失敗
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
do
{
size += size / 10;
newprocess = realloc(process, size);
if (!newprocess)
{
if (process)
{
free(process);
process = NULL;
}
return nil;
}
process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);
}
while (st == -1 && errno == ENOMEM);
if (st == 0)
{
if (size % sizeof(struct kinfo_proc) == 0)
{
int nprocess = size / sizeof(struct kinfo_proc);
if (nprocess)
{
for (int i = nprocess - 1; i >= 0; i--)
{
@autoreleasepool{
//進程的時間
double t = process->kp_proc.p_un.__p_starttime.tv_sec;
double s = process->kp_proc.p_un.__p_starttime.tv_usec;
double finaly = t + s *0.000001;
//將其轉為具體時間
proc_useTiem = [self timeWithBoot:finaly];
}
}
free(process);
process = NULL;
return proc_useTiem;
}
}
}
return nil;
}
/**
* 轉為具體時間
*/
+ (NSString *)timeWithBoot:(double)interval
{
NSDateFormatter *format = [[NSDateFormatter alloc]init];
format.timeZone = [NSTimeZone timeZoneWithName:@"shanghai"];
[format setDateStyle:NSDateFormatterMediumStyle];
[format setTimeStyle:NSDateFormatterShortStyle];
//注意先後順序
[format setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
NSString *bootTime = [format stringFromDate:date];
return bootTime;
}