最近Swift项目开发中,涉及到了日期时间的处理,需求是这样的,需要把一个日期格式类型的字符串,转换为Date类型,但是转换完发现和OC中处理的结果不太一样,具体如下所示:
先来看下OC版本的代码:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *currentTime = [self dateTransformToTimeString];
NSLog(@"currentTime = %@", currentTime);
NSDate *currentDate = [self timeStrToDate:currentTime];
NSLog(@"date = %@",currentDate);
}
#pragma mark 将NSDate --> NSString
- (NSString *)dateTransformToTimeString {
NSDate *currentDate = [NSDate date];//获得当前时间为UTC时间 2014-07-16 07:54:36 UTC (UTC时间比标准时间差8小时)
NSDateFormatter*dateFormatter = [[NSDateFormatter alloc]init];//实例化时间格式类
[dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];//格式化
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/BeiJing"]];
NSString *timeString = [dateFormatter stringFromDate:currentDate];
return timeString;
}
#pragma mark 将时间NSString --> NSDate
- (NSDate *)timeStrToDate:(NSString *)timeStr {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
[formatter setTimeZone:timeZone];
NSDate *date = [formatter dateFromString:timeStr];
return date;
}
@end
输出结果如下所示:
2021-11-26 17:31:03.535092+0800 OCDemo[36383:1191861] currentTime = 2021-11-26 17:31:03
2021-11-26 17:31:15.342025+0800 OCDemo[36383:1191861] date = Fri Nov 26 17:31:03 2021
注意看,这里OC中把NSString -> NSDate完全没有问题,但是相同的代码,请看Swift如下的输出结果:
override func viewDidLoad() {
super.viewDidLoad()
let currentTime = dateTransformToTimeString()
print("currentTime = \(String(describing: currentTime))")
let currentDate = timeStringTransformToDate(toDate: currentTime)
print("date = \(currentDate)")
}
// MARK: 获取当前时间
func dateTransformToTimeString() -> String? {
let currentDate = Date() //获得当前时间为UTC时间 2014-07-16 07:54:36 UTC (UTC时间比标准时间差8小时)
let dateFormatter = DateFormatter() //实例化时间格式类
dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" //格式化
dateFormatter.timeZone = NSTimeZone(name: "Asia/BeiJing") as TimeZone?
let timeString = dateFormatter.string(from: currentDate)
return timeString
}
//将时间字符串转换为时间Date
func timeStringTransformToDate(toDate timeStr: String?) -> Date {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
formatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
formatter.timeZone = NSTimeZone(name: "Asia/BeiJing") as TimeZone?
let date = formatter.date(from: timeStr ?? "") ?? Date()
return date
}
Swift中输出结果如下:
currentTime = Optional("2021-11-26 17:38:42")
date = 2021-11-26 09:38:42 +0000
注意看,这里Swift中把String -> Date时区就差了8小时,这里查阅资料说的是Swift中Date是0时区造成的,具体可以参考Swift4中对于日期时间的处理(Date、DateComponents、Calendar、DateFormatter、Locale 文章,里面解释的比较详细。
那么如何让Swift中打印和OC中的时间一样准确,也是当前北京时间呢,只需要将 formatter.timeZone = NSTimeZone(name: "Asia/BeiJing") as TimeZone?
写法替换为formatter.timeZone = TimeZone.init(secondsFromGMT: 8)
即可解决问题,效果如下所示:
具体原因没有深究,可能这也是OC和Swift中的一点点不同之处吧。这里也记录下Swift学习之路的小坑~