为什么NSDateFormatter返回这4个时区的无date?

尝试在iOS6中运行(未在iOS6之前testing过):

NSDateFormatter *julianDayDateFormatter = nil; julianDayDateFormatter = [[NSDateFormatter alloc] init]; [julianDayDateFormatter setDateFormat:@"g"]; for (NSString *timeZone in [NSTimeZone knownTimeZoneNames]) { julianDayDateFormatter.timeZone = [NSTimeZone timeZoneWithName: timeZone]; NSDate *date = [julianDayDateFormatter dateFromString:[NSString stringWithFormat:@"%d", 2475213]]; if (date == nil) NSLog(@"timeZone = %@", timeZone); } 

并得到以下输出:

 America/Bahia America/Campo_Grande America/Cuiaba America/Sao_Paulo 

任何人都可以解释为什么这四个时区的行为像NSDateFormatter设置为朱连天数字? 所有其他时区使NSDateFormatter返回实际的NSDates。

我有一个怀疑 。 只有一个怀疑,但一个相当强大的。

该值代表2064年10月19日。巴西时区从本地午夜开始实行夏令时 – 即时钟前进,所以午夜本身不存在。 10月19日是这些转折之一。

下面是使用Noda Time,.NETdate/时间API的一些示例代码。 它检查它知道的每个时区的一天的开始是否实际上是午夜:

 using System; using NodaTime; class Test { static void Main() { var localDate = new LocalDate(2064, 10, 19); var provider = DateTimeZoneProviders.Tzdb; foreach (var id in provider.Ids) { var zone = provider[id]; var startOfDay = zone.AtStartOfDay(localDate).LocalDateTime.TimeOfDay; if (startOfDay != LocalTime.Midnight) { Console.WriteLine(id); } } } } 

这产生了一个非常相似的名单:

 America/Bahia America/Campo_Grande America/Cuiaba America/Sao_Paulo Brazil/East 

我怀疑巴西/东部可能是美国/ Sao_Paolo的别名,这就是为什么它不在你的名单上。

无论如何,回到你的Julian日问题 – 我怀疑格式化程序总是想要返回在当地午夜NSDate * 。 2064年10月19日这个时间段不存在 ,因此它返回零。 我个人build议它应该返回1am值,而是嘿…

感谢Jon Skeet让我走上正轨。 不过,我只是想在iOS上下文中澄清他的答案。

当您要求NSDateFormatter将Juliandate编号转换为NSDate时,您只能在要分析的string中指定整数(通常可以指定小时/分钟/秒的小数部分)。 因为苹果在午夜划分了朱利安天(而不是天文中午,请阅读更多信息: http : //www.unicode.org/reports/tr35/#Date_Field_Symbol_Table ),有些中午根本不存在(谢谢指出@JonSkeet)NSDateFormatter标识该特定时间点在该时区中不存在,并返回nil。

为了logging,iOS5的行为不像这样,我同意Jon Skeet,NSDateFormatter应该返回一个调整为DST而不是零的NSDate,因为那个特定的Julian实际上是存在的! 我向苹果提交了一个bug。