无法正确格式化时间
Can't format time right
我有以下方法将给定时间(UTC 格式)作为参数并将其转换为当前时间,比方说 'friendlier format'。
A valid/normal 输入可能是:'11:30' 或 '1:30' 我的问题是虽然我设备中设置的时区是纽约(-4 GMT) 甚至在此示例中进行硬编码!此函数不断将时间转换为格林威治标准时间 -5 (分别为上午 6:30 和下午 8:30)
-(NSString*) convertServerTimeToAppTimeFormat:(NSString*) input {
NSDateFormatter *dateFormatInput = [[NSDateFormatter alloc] init];
[dateFormatInput setDateFormat:@"HH:mm"];
[dateFormatInput setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateFormatInput dateFromString:input];
NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
[dateFormatInputOutput setDateFormat:@"h:mm a"];
[dateFormatInputOutput setTimeZone: [NSTimeZone localTimeZone]];
[dateFormatInputOutput setTimeZone:[NSTimeZone timeZoneWithName:@"America/New_York"]];
return [dateFormatInputOutput stringFromDate:date];
}
肯定有一些我没有看到的非常明显的东西。我通常会使用:
[NSTimeZone localTimeZone]
获取我的用户所在的当前时区,而不是像我在这里那样对其进行硬编码,但我认为硬编码版本应该有助于使错误更加明显。
当您仅解析没有日期的时间时,返回的日期将为 Jan 1, 2000
。由于夏令时,今天您与 GMT 之间的时差可能与 1 月 1 日不同。您需要在代码中间添加一些额外的步骤以使其执行正确的操作。
我对 Objective-C 真的很生疏,所以我将总结一下您需要执行的步骤。我还可以 post swift 中的解决方案,您认为这会有所帮助,因为它基本上相同,只是语法不同。
- 保留从字符串
创建 date
的代码
- 创建一个
Calendar
并将其时区设置为 GMT
- 创建一个
DateComponents
包含当前日期的年、月、日
- 创建一个
DateComponents
,其中包含从 date
起的小时、分钟
- 将两个
DateComponents
合并在一起,编辑其中一个或制作一个新的
- 使用日历从组件中获取日期
- 使用您的
dateFormatInputOutput
格式化程序从这个日期创建一个字符串
问题是纽约是晚 4 小时还是 5 小时 GMT/UTC 取决于您当前是否处于夏令时。我们目前处于“夏令时”时间,但在没有相反信息的情况下,日期格式化程序将假定日期为 2000 年 1 月 1 日,这不是夏令时。因此断开连接。
但是你可以将格式化程序的 defaultDate
设置为今天:
NSDate *today = [[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]];
[dateFormatInput setDefaultDate:today];
以上将格式化程序默认为今天的日期。显然,如果您的输入有一个单独的字段来标识当前时间与哪一天相关,则使用它。
但是通过设置 defaultDate
,这将使 time-only 字符串知道它是否应该应用夏令时,从而产生所需的时区转换。
顺便说一句,我建议不要使用 dateFormat
作为输出字符串。指定 timeStyle
,它将根据用户设备的设置对其进行适当的格式化:
NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
[dateFormatInputOutput setTimeStyle:NSDateFormatterShortStyle];
return [dateFormatInputOutput stringFromDate:date];
具体来说,如果用户将他们的设备配置为 24 小时时钟,则以上内容将遵循用户指示的任何内容,而不是强制采用他们可能不喜欢的格式。
另请注意,您不必强制设置时区或区域设置(除非您真的打算将其强制设置为纽约,即使用户在加利福尼亚州也是如此),因为它也将默认为用户设备的设置.这仅取决于您是否真的想将其强制为东部时区。
如果您从网络服务中读取 date/time 字符串,您可能还需要根据 Technical Note 1480 指定一致的语言环境。从技术上讲,它是一个 time-only 字符串,可能不需要,但这是一个很好的做法:
[dateFormatInput setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
我有以下方法将给定时间(UTC 格式)作为参数并将其转换为当前时间,比方说 'friendlier format'。
A valid/normal 输入可能是:'11:30' 或 '1:30' 我的问题是虽然我设备中设置的时区是纽约(-4 GMT) 甚至在此示例中进行硬编码!此函数不断将时间转换为格林威治标准时间 -5 (分别为上午 6:30 和下午 8:30)
-(NSString*) convertServerTimeToAppTimeFormat:(NSString*) input {
NSDateFormatter *dateFormatInput = [[NSDateFormatter alloc] init];
[dateFormatInput setDateFormat:@"HH:mm"];
[dateFormatInput setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateFormatInput dateFromString:input];
NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
[dateFormatInputOutput setDateFormat:@"h:mm a"];
[dateFormatInputOutput setTimeZone: [NSTimeZone localTimeZone]];
[dateFormatInputOutput setTimeZone:[NSTimeZone timeZoneWithName:@"America/New_York"]];
return [dateFormatInputOutput stringFromDate:date];
}
肯定有一些我没有看到的非常明显的东西。我通常会使用:
[NSTimeZone localTimeZone]
获取我的用户所在的当前时区,而不是像我在这里那样对其进行硬编码,但我认为硬编码版本应该有助于使错误更加明显。
当您仅解析没有日期的时间时,返回的日期将为 Jan 1, 2000
。由于夏令时,今天您与 GMT 之间的时差可能与 1 月 1 日不同。您需要在代码中间添加一些额外的步骤以使其执行正确的操作。
我对 Objective-C 真的很生疏,所以我将总结一下您需要执行的步骤。我还可以 post swift 中的解决方案,您认为这会有所帮助,因为它基本上相同,只是语法不同。
- 保留从字符串 创建
- 创建一个
Calendar
并将其时区设置为GMT
- 创建一个
DateComponents
包含当前日期的年、月、日 - 创建一个
DateComponents
,其中包含从date
起的小时、分钟
- 将两个
DateComponents
合并在一起,编辑其中一个或制作一个新的 - 使用日历从组件中获取日期
- 使用您的
dateFormatInputOutput
格式化程序从这个日期创建一个字符串
date
的代码
问题是纽约是晚 4 小时还是 5 小时 GMT/UTC 取决于您当前是否处于夏令时。我们目前处于“夏令时”时间,但在没有相反信息的情况下,日期格式化程序将假定日期为 2000 年 1 月 1 日,这不是夏令时。因此断开连接。
但是你可以将格式化程序的 defaultDate
设置为今天:
NSDate *today = [[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]];
[dateFormatInput setDefaultDate:today];
以上将格式化程序默认为今天的日期。显然,如果您的输入有一个单独的字段来标识当前时间与哪一天相关,则使用它。
但是通过设置 defaultDate
,这将使 time-only 字符串知道它是否应该应用夏令时,从而产生所需的时区转换。
顺便说一句,我建议不要使用 dateFormat
作为输出字符串。指定 timeStyle
,它将根据用户设备的设置对其进行适当的格式化:
NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
[dateFormatInputOutput setTimeStyle:NSDateFormatterShortStyle];
return [dateFormatInputOutput stringFromDate:date];
具体来说,如果用户将他们的设备配置为 24 小时时钟,则以上内容将遵循用户指示的任何内容,而不是强制采用他们可能不喜欢的格式。
另请注意,您不必强制设置时区或区域设置(除非您真的打算将其强制设置为纽约,即使用户在加利福尼亚州也是如此),因为它也将默认为用户设备的设置.这仅取决于您是否真的想将其强制为东部时区。
如果您从网络服务中读取 date/time 字符串,您可能还需要根据 Technical Note 1480 指定一致的语言环境。从技术上讲,它是一个 time-only 字符串,可能不需要,但这是一个很好的做法:
[dateFormatInput setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];