cat*_*eof 9 time cocoa cocoa-touch nsdateformatter date-parsing
我从iOS应用中的服务器获取以下字符串:
20140621-061250
如何将其转换为当地时间?
如何定义日期格式化程序?它是否正确?
dateFormatter.dateFormat = @"YYYYMMd-HHmmss";
Run Code Online (Sandbox Code Playgroud)
Car*_*zey 36
问题并没有明确指出转换的含义,但是无论最终目标如何,您应该做的第一件事就是使用正确配置来正确解析服务器响应NSDateFormatter
.这需要指定正确的格式字符串,并且必须在格式化程序上明确设置时区,否则它将从本地时间推断出来,这在大多数情况下是不正确的.
让我们看看提供的输入字符串:
20140621-061250
这使用了年份的四位数字,月份的两位数字(零填充)和当天的两位数(可能也是零填充).接下来是a -
,然后两位数表示小时,2位数表示分钟,2位数表示秒.
参考Unicode日期格式标准,我们可以通过以下方式派生格式字符串.表示日历年的四位数将替换yyyy
为格式字符串.使用MM
了一个月,dd
这一天.接下来就是字面意思-
.几个小时,我认为它将是24小时格式,否则这个响应是模糊的,所以我们使用HH
.分钟是mm
秒和秒ss
.连接格式说明符会产生以下格式字符串,我们将在下一步中使用它:
yyyyMMdd-HHmmss
Run Code Online (Sandbox Code Playgroud)
在我们的程序中,这看起来像:
NSString *dateFormat = @"yyyyMMdd-HHmmss";
Run Code Online (Sandbox Code Playgroud)
上面的时间格式没有指定时区,但是因为您已经为服务器响应提供了表示UTC时间的规范,我们可以将其编码到我们的应用程序中.因此,我们实例化一个NSDateFormatter
,设置正确的时区,并设置日期格式:
NSTimeZone *inputTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
NSDateFormatter *inputDateFormatter = [[NSDateFormatter alloc] init];
[inputDateFormatter setTimeZone:inputTimeZone];
[inputDateFormatter setDateFormat:dateFormat];
Run Code Online (Sandbox Code Playgroud)
NSDate
出于演示目的,我们对从服务器响应中收到的字符串进行硬编码; 你将这个定义替换为inputString
从服务器获得的定义:
NSString *inputString = @"20140621-061250";
NSDate *date = [inputDateFormatter dateFromString:inputString];
Run Code Online (Sandbox Code Playgroud)
此时,我们有必要的对象来进行任何进一步的转换或计算 - NSDate
表示服务器传达的时间.请记住,a NSDate
只是一个时间戳 - 它与时区无关,它只在转换日期的字符串表示或从日历的表示形式转换时起作用NSDateComponents
.
问题没有明确指出需要什么类型的转换,因此我们将看到一个格式化日期的示例,以与服务器响应相同的格式显示(尽管我不能想到这个可能的用例)特别是代码,老实说).步骤非常相似 - 我们指定格式字符串,时区,配置日期格式化程序,然后从日期生成一个字符串(以指定的格式):
NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateFormat:dateFormat];
NSString *outputString = [outputDateFormatter stringFromDate:date];
Run Code Online (Sandbox Code Playgroud)
由于我在UTC-06:00,打印outputString
提供以下内容:
20140621-001250
如果您向用户显示此日期,或者使用an 来获取实例在日期进行算术运算或计算,那么您可能会想要使用setDateStyle:
而setTimeStyle:
不是格式字符串.向用户显示详细日期字符串的示例:NSCalendar
NSDateComponents
NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateStyle:NSDateFormatterFullStyle];
[outputDateFormatter setTimeStyle:NSDateFormatterFullStyle];
NSString *outputString = [outputDateFormatter stringFromDate:date];
Run Code Online (Sandbox Code Playgroud)
outputString
在这里打印给我们以下内容:
2014年6月21日星期六上午12:12:50山区夏令时
请注意,适当设置时区将处理夏令时的转换.使用上面的格式化器样式代码将输入字符串更改为"20141121-061250"会给我们显示以下日期(请注意,Mountain Standard Time是UTC-7):
2014年11月20日星期四晚上11:12:50山区标准时间
每当您以表示日历日期和时间的字符串形式获取日期输入时,您的第一步是使用已NSDateFormatter
配置的输入格式,时区以及可能的区域设置和日历来转换它,具体取决于输入的来源和您的要求.这将产生一个NSDate
毫不含糊的时刻表示.创建之后NSDate
,可以根据应用程序的需要对其进行格式化,设置样式或将其转换为日期组件.
要将字符串放入NSDate,您可以像这样使用NSDateFormatter:
NSString *myDateAsAStringValue = @"20140621-061250"
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyyMMdd-HHmmss"];
NSDate *myDate = [df dateFromString: myDateAsAStringValue];
Run Code Online (Sandbox Code Playgroud)
您可能想阅读有关使用日期和时间的这篇文章
编辑:
要将其解析为UTC,您必须添加以下行:
[df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
Run Code Online (Sandbox Code Playgroud)
此外,当您使用NSLog打印它时,如果您使用相同的NSDateFormatter,您将获得输入字符串作为输出(因为您应用解析函数的反转).
以下是完整的代码,用于解析和获取标准格式的输出:
//The input
NSString *myDateAsAStringValue = @"20140621-061250";
//create the formatter for parsing
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[df setDateFormat:@"yyyyMMdd-HHmmss"];
//parsing the string and converting it to NSDate
NSDate *myDate = [df dateFromString: myDateAsAStringValue];
//create the formatter for the output
NSDateFormatter *out_df = [[NSDateFormatter alloc] init];
[out_df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssz"];
//output the date
NSLog(@"the date is %@",[out_df stringFromDate:myDate]);
Run Code Online (Sandbox Code Playgroud)
使用NSDate扩展的Swift中的一个可能的解决方案(也许它可以帮助未来的这个问题的观众):
import UIKit
// For your personal information: NSDate() initializer
// always returns a date in UTC, no matter the time zone specified.
extension NSDate {
// Convert UTC (or GMT) to local time
func toLocalTime() -> NSDate {
let timezone: NSTimeZone = NSTimeZone.localTimeZone()
let seconds: NSTimeInterval = NSTimeInterval(timezone.secondsFromGMTForDate(self))
return NSDate(timeInterval: seconds, sinceDate: self)
}
// Convert local time to UTC (or GMT)
func toGlobalTime() -> NSDate {
let timezone: NSTimeZone = NSTimeZone.localTimeZone()
let seconds: NSTimeInterval = -NSTimeInterval(timezone.secondsFromGMTForDate(self))
return NSDate(timeInterval: seconds, sinceDate: self)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20526 次 |
最近记录: |