使用 NSDateFormatter 将 UTC 转换为本地时间 [英] Convert UTC to local time with NSDateFormatter

查看:42
本文介绍了使用 NSDateFormatter 将 UTC 转换为本地时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 iOS 应用程序中的服务器获取以下字符串:

I am getting the following string from a server in my iOS app:

20140621-061250

20140621-061250

如何将其转换为当地时间?

How can I convert it to the local time?

如何定义我的日期格式化程序?这是正确的吗?

How can I define my date formatter? Is this correct?

dateFormatter.dateFormat = @"YYYYMMd-HHmmss"; 

推荐答案

这个问题没有具体说明转换的含义,确切地说,但是无论最终目标如何,你应该做的第一件事是使用正确配置的 NSDateFormatter 正确解析服务器响应.这需要指定正确的格式字符串,并且必须在格式化程序上明确设置时区,否则它会从本地时间推断出来,这在大多数情况下是不正确的.

The question doesn't specify the nature of what you mean by converting, exactly, but the first thing you should do, regardless of the final goal, is to correctly parse the server response using a properly configured NSDateFormatter. This requires specification of the correct format string, and the time zone must be explicitly set on the formatter or it will infer it from the local time, which would be incorrect in most cases.

让我们看看提供的输入字符串:

Let's look at the input string provided:

20140621-061250

20140621-061250

这使用四位数字表示年份,两位数字(带零填充)表示月份,两位数字(推测这些也会用零填充)表示日期.后面跟着一个-,然后是两位数字代表小时,两位数字代表分钟,两位数字代表秒.

This uses four digits for the year, two digits (with a zero-padding) for the month, and two digits (presumably, these will be zero-padded as well) for the day. This is followed by a -, then two digits to represent the hour, 2 digits for the minute, and 2 digits for the second.

参考 Unicode 日期格式标准,我们可以通过以下方式导出格式字符串.表示日历年的四位数字将替换为格式字符串中的 yyyy.使用 MM 表示月份,使用 dd 表示日.接下来是文字 -.对于小时,我假设它将采用 24 小时格式,否则这个响应是不明确的,所以我们使用 HH.分钟是 mm 和秒 ss.连接格式说明符会产生以下格式字符串,我们将在下一步中使用它:

Referring to the Unicode date format standards, we can derive the format string in the following way. The four digits representing the calendar year will be replaced with yyyy in the format string. Use MM for the month, and dd for the day. Next would come the literal -. For the hours, I assume that it will be in 24 hour format as otherwise this response is ambiguous, so we use HH. Minutes are then mm and seconds ss. Concatenating the format specifiers yields the following format string, which we will use in the next step:

yyyyMMdd-HHmmss

在我们的程序中,这看起来像:

In our program, this would look like:

NSString *dateFormat = @"yyyyMMdd-HHmmss";

配置输入日期格式器

上面的时间格式没有指定时区,但是因为您已经提供了代表 UTC 时间的服务器响应规范,我们可以将其编码到我们的应用程序中.因此,我们实例化一个 NSDateFormatter,设置正确的时区,并设置日期格式:

Configure the input date formatter

The time format above does not specify a time zone, but because you have been provided the specification for the server response that it represents the UTC time, we can code this into our application. So, we instantiate an NSDateFormatter, set the correct time zone, and set the date format:

NSTimeZone *inputTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
NSDateFormatter *inputDateFormatter = [[NSDateFormatter alloc] init];
[inputDateFormatter setTimeZone:inputTimeZone];
[inputDateFormatter setDateFormat:dateFormat];

将输入字符串转换为 NSDate

出于演示目的,我们对您从服务器响应中收到的字符串进行了硬编码;您可以将 inputString 的定义替换为您从服务器获得的定义:

Convert the input string to an NSDate

For demonstration purposes, we hard-code the string you received from the server response; you would replace this definition of inputString with the one you get from the server:

NSString *inputString = @"20140621-061250";
NSDate *date = [inputDateFormatter dateFromString:inputString];

此时,我们有必要的对象来进行任何进一步的转换或计算 - 一个 NSDate 代表服务器通信的时间.请记住,NSDate 只是一个时间戳 - 它与任何时区都没有关系,它仅在与日期的字符串表示或日历日期的表示之间进行转换时起作用NSDateComponents.

At this point, we have the necessary object to do any further conversions or calculations - an NSDate which represents the time communicated by the server. Remember, an NSDate is just a time stamp - it has no relation to a time zone whatsoever, which only plays a role when converting to and from string representations of the date, or representations of a calendrical date via NSDateComponents.

这个问题没有明确说明需要什么类型的转换,所以我们将看到一个示例,将日期格式化为以与服务器响应相同的格式显示(虽然,我想不出可能的用途老实说,对于这个特定的代码位的情况).步骤非常相似——我们指定一个格式字符串,一个时区,配置一个日期格式化程序,然后从日期生成一个字符串(以指定格式):

The question doesn't clearly specify what type of conversion is needed, so we'll see an example of formatting the date to display in the same format as the server response (although, I can't think of a likely use case for this particular bit of code, to be honest). The steps are quite similar - we specify a format string, a time zone, configure a date formatter, and then generate a string (in the specified format) from the date:

NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateFormat:dateFormat];
NSString *outputString = [outputDateFormatter stringFromDate:date];

由于我在 UTC-06:00,打印 outputString 给出以下内容:

Since I'm in UTC-06:00, printing outputString gives the following:

20140621-001250

20140621-001250

如果您要向用户显示此日期,则您可能希望使用 setDateStyle:setTimeStyle:NSCalendar 获取一个 NSDateComponents 实例来对日期进行算术或计算.向用户显示详细日期字符串的示例:

It's likely you'll instead want to use setDateStyle: and setTimeStyle: instead of a format string if you're displaying this date to the user, or use an NSCalendar to get an NSDateComponents instance to do arithmetic or calculations on the date. An example for displaying a verbose date string to the user:

NSTimeZone *outputTimeZone = [NSTimeZone localTimeZone];
NSDateFormatter *outputDateFormatter = [[NSDateFormatter alloc] init];
[outputDateFormatter setTimeZone:outputTimeZone];
[outputDateFormatter setDateStyle:NSDateFormatterFullStyle];
[outputDateFormatter setTimeStyle:NSDateFormatterFullStyle];
NSString *outputString = [outputDateFormatter stringFromDate:date];

在此处打印 outputString 为我们提供以下内容:

Printing outputString here gives us the following:

2014 年 6 月 21 日星期六上午 12:12:50 山区夏令时

Saturday, June 21, 2014 at 12:12:50 AM Mountain Daylight Time

请注意,适当设置时区将处理夏令时的转换.使用上面的格式化程序样式代码将输入字符串更改为20141121-061250"将为我们提供以下显示日期(请注意,山地标准时间为 UTC-7):

Note that setting the time zone appropriately will handle transitions over daylight savings time. Changing the input string to "20141121-061250" with the formatter style code above gives us the following date to display (Note that Mountain Standard Time is UTC-7):

山区标准时间 2014 年 11 月 20 日星期四晚上 11:12:50

Thursday, November 20, 2014 at 11:12:50 PM Mountain Standard Time

总结

每当您以字符串形式获得表示日历日期和时间的日期输入时,您的第一步是使用为输入的格式、时区和可能的区域设置配置的 NSDateFormatter 进行转换日历,取决于输入的来源和您的要求.这将产生一个 NSDate,它是一个时刻的明确表示.在创建该 NSDate 之后,您可以根据应用程序要求对其进行格式化、设置样式或将其转换为日期组件.

Summary

Any time you get date input in a string form representing a calendar date and time, your first step is to convert it using an NSDateFormatter configured for the input's format, time zone, and possibly locale and calendar, depending on the source of the input and your requirements. This will yield an NSDate which is an unambiguous representation of a moment in time. Following the creation of that NSDate, one can format it, style it, or convert it to date components as needed for your application requirements.

这篇关于使用 NSDateFormatter 将 UTC 转换为本地时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆