ios时间戳、NSDate、字符串转换显示、时差计算

开发中经常用到时间戳,*、/ 1000是秒和毫秒的换算。

1.当前时间

long long 类型时间戳: NSTimeInterval time=([[NSDate date] timeIntervalSince1970])*1000;

long long t = (long long)time;

String类型当前时间:NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"yyyyMMddHHmmss";//格式自定义

NSString *str = [formatter stringFromDate:[NSDate date]];

2.获取今日零点时间

(1)时间戳:

- (long long) todayStartTime {

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *now = [NSDate date];

NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:now];

NSDate *startDate = [calendar dateFromComponents:components];

return (long long)[startDate timeIntervalSince1970]*1000 ;

}
(2)String日期:

- (NSString) todayStartTime {

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]];

NSDate *startDate = [calendar dateFromComponents:components];

NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"yyyy:MM:dd:HH:mm:ss"];

return [dateFormatter stringFromDate:startDate];

}

3.时间戳和时间转换

我们需要显示日期,服务器给我们的是时间戳参考(1),给我们的是系统时间格式的字符串参考(2)、(3)

(1)时间戳转换成日期:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"yyyy/MM/dd HH:mm:ss";

//self.nowTime是13位时间戳,把时间戳先转换为NSDate,再转换为String展示

NSDate* date = [NSDate dateWithTimeIntervalSince1970:(double)self.nowTime/1000];

NSString *riQi = [formatter stringFromDate:date];
(2)String日期转换成long long时间戳:

//例如日期为string类型 model.createTime =@"Aug 1, 2017 10:53:20 AM"

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"MMM d, yyyy h:mm:ss a";

formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

NSDate* date = [formatter dateFromString:model.createTime];

NSTimeInterval time=([date timeIntervalSince1970])*1000;

long long t = (long long)time;
(3)将String类型日期变换格式依旧以String日期显示:

依旧以(2)中为例,只是在最后不转时间戳,将NSDate 转为要显示的日期

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"MMM d, yyyy h:mm:ss a";

formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

NSDate* date = [formatter dateFromString:model.createTime];

formatter.dateFormat = @"yyyy/MM/dd HH:mm:ss";

NSString *riQi = [formatter stringFromDate:date];

4.时间差展示

(1)展示模糊的时间 过去时间戳距离当前时间的时差  timeInterval 为秒级,毫秒级的自行/1000

//timeInterval过去的时间戳
+ (NSString *)getFriendlyDateString:(NSTimeInterval)timeInterval

 {

NSDate *theDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];

//算出时间戳的差值

NSTimeInterval diff = -theDate.timeIntervalSinceNow;

NSInteger minute = 60 ;// 1分钟

NSInteger hour = 60 * minute;// 1小时

NSInteger day = 24 * hour;// 1天

NSInteger month = 31 * day;// 月

NSInteger year = 12 * month;// 年

long r = 0;

if (diff > year) {

r = (diff / year);

return [NSString stringWithFormat:@"%ld年前",r];

}

if (diff > month) {

r = (diff / month);

return [NSString stringWithFormat:@"%ld个月前",r];

}

if (diff > day) {

r = (diff / day);

return [NSString stringWithFormat:@"%ld天前",r];

}

if (diff > hour) {

r = (diff / hour);

return [NSString stringWithFormat:@"%ld个小时前",r];

}

if (diff > minute) {

r = (diff / minute);

return [NSString stringWithFormat:@"%ld分钟前",r];

}

return @"刚刚";

}
(2)精确时间展示  秒级时间段时间戳转化为String

+(NSString*)getDetailYuTimeWith:(NSInteger)peroidTime{

NSInteger minute = 60 ;// 1分钟

NSInteger hour = 60 * minute;// 1小时

NSInteger day = 24 * hour;// 1天

NSInteger month = 31 * day;// 月

NSInteger year = 12 * month;// 年

//时间数

NSInteger nian = peroidTime/year;//有几年

NSInteger yue = (peroidTime-nian*year)/month;//有几月

NSInteger ri = (peroidTime-nian*year-yue*month)/day;//有几日

NSInteger shi = (peroidTime-nian*year-yue*month-ri*day)/hour;//有几时

NSInteger fen = (peroidTime-nian*year-yue*month-ri*day-shi*hour)/minute;//有几分

NSInteger miao = peroidTime-nian*year-yue*month-ri*day-shi*hour-fen*minute;//有几秒

if (nian!=0) {

return [NSString stringWithFormat:@"%zd年%02zd月%02zd天%02zd小时%02zd分%02zd秒",nian,yue,ri,shi,fen,miao];

}else if (yue!=0){

return  [NSString stringWithFormat:@"%02zd月%02zd天%02zd小时%02zd分%02zd秒",yue,ri,shi,fen,miao];

}else if (ri != 0){

return  [NSString stringWithFormat:@"%02zd天%02zd小时%02zd分%02zd秒",ri,shi,fen,miao];

}else if (shi!=0){

return  [NSString stringWithFormat:@"%02zd小时%02zd分%02zd秒",shi,fen,miao];

}else if (fen!=0){

return  [NSString stringWithFormat:@"%02zd分%02zd秒",fen,miao];

}else{

return  [NSString stringWithFormat:@"%02zd秒",miao];

}

}

以上关于时间的转换或封装,是个人经验,如有高手请指点,分享出来,希望大家可以在写代码的时候节约时间,不会把时间浪费在时间戳的问题上,有些时候时间戳的问题很折磨人,会浪费很多不必要的时间,比如去年的时候,因为sqlite3存储毫秒级时间戳崩溃,百思不得其解,最后发现13位的存储sq语句中字段应该用bigint类型才可以。

关于第4点,有个瑕疵就是时间段超过月会不精确,目前按30或31天粗略估算的,这个问题我想到了更好的方式解决,通过日历对比,如下

//定义格式化对象

let sharedDateFormater = DateFormatter()

var created_at:String?
//get 计算型属性

var timeText: String? {

//1.实例化日期格式化对象

//2.指定格式化符

sharedDateFormater.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"

//在真机上必须设置本地化信息否则转换失败

sharedDateFormater.locale = Locale(identifier: "en")

//3.将字符串转换日期对象

guard let sinaDate = sharedDateFormater.date(from: self.created_at ?? "") else {

return "穿越时空的少年"

}

//print(sinaDate)

//4.处理日期

//4.1 判断是否是今年 Calendar 提供非常丰富的日期处理函数

let calender = Calendar.current

let currentDate = Date()

let result = calender.dateComponents([.day,.year], from: sinaDate, to: currentDate)

if result.year == 0 {

//今年

if calender.isDateInToday(sinaDate) {

//今天

//获取当前时间和sinaDate秒的差值

let delta = currentDate.timeIntervalSince(sinaDate)

if delta < 60 {

//刚刚

return "刚刚"

} else if delta < 3600 {

return "\(Int(delta / 60))分钟前"

} else {

return "\(Int(delta / 3600))小时前"

}

} else if calender.isDateInYesterday(sinaDate) {

//昨天 昨天 HH:mm

sharedDateFormater.dateFormat = "昨天 HH:mm"

return sharedDateFormater.string(from: sinaDate)

} else {

//其他 MM-dd HH:mm

sharedDateFormater.dateFormat = "MM-dd HH:mm"

return sharedDateFormater.string(from: sinaDate)

}

} else {

//非当年

sharedDateFormater.dateFormat = "yyyy-MM-dd HH:mm"

return sharedDateFormater.string(from: sinaDate)

}

}

另外时间差如果不超过24小时,可以用下面这个,例如

// 时间戳的差转换成时间显示去掉时区8小时 

NSTimeInterval response = 3684;

NSDate *date = [[NSDate alloc]initWithTimeIntervalSince1970:response-28800];

NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"HH:mm:ss"];

NSString * responseTime = [dateFormatter stringFromDate:date];

NSLog(@"=%@",responseTime);

结果为=01:01:24

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容