简体   繁体   English

iOS-NSDateFormatter dateFromString仅在一种情况下返回nil

[英]iOS - NSDateFormatter dateFromString returns nil only in one case

I'm testing some values for a date format ( "dd-MM-yyyy" ) and there's a special case that I can't explain: 我正在测试日期格式的一些值( "dd-MM-yyyy" ),有一种特殊情况我无法解释:

var datef = NSDateFormatter()
datef.dateFormat = "dd-MM-yyyy";
var date_a = "02-01-1990"
var date_b = "01-01-1990"
var date_f_a = datef.dateFromString(date_a);
var date_f_b = datef.dateFromString(date_b);

data_f_a returns Jan 2, 1990, 12:00 AM, but date_f_b returns nil. data_f_a返回1990年1月2日上午12:00,但date_f_b返回nil。 Any other date will return the expected value, except for January 1st, 1990. 除1990年1月1日外,任何其他日期都将返回预期值。

If I add datef.lenient = true date_f_b is no longer nil, but I shouldn't need to do that. 如果我添加datef.lenient = true date_f_b不再为nil,但我不需要这样做。 Why is it an invalid date? 为什么它是无效的日期?

EDIT 1: It happens the same if I use DateFormatter() : 编辑1:如果我使用DateFormatter()也会发生相同的情况:

使用Swift版本3

EDIT 2: Xcode version: 8.1 编辑2: Xcode版本:8.1

After a few comments, it has been determined that the code in the question is being run with the locale of es_PE . 经过一番评论后,可以确定问题中的代码正在使用es_PE的语言环境运行。 This is the country of Peru. 这是秘鲁的国家。 The date in question is January 1, 1990. By default, NSDateFormatter uses the local timezone and when parsing date strings that have no time, midnight is assumed. 有问题的日期是1990年1月1日。默认情况下, NSDateFormatter使用本地时区,当解析没有时间的日期字符串时,将假定为午夜。

In Peru, in the year 1990, day light savings began at midnight, January 1st, 1990. This means that clocks went from December 31, 1989 at 11:59:59pm straight to January 1, 1990 at 1:00:00am. 在秘鲁,1990年的日光节约时间是从1990年1月1日午夜开始。这意味着时钟从1989年12月31日晚上11:59:59一直到1990年1月1日上午1:00:00。 There was no midnight on January 1, 1990. 1990年1月1日无午夜。

This is why the attempt to convert the string 01-01-1990 failed for this user. 这就是为什么该用户尝试转换字符串01-01-1990失败的原因。 There was no midnight for this date in Peru (and possibly a few other locales, if any, that had day light saving start at the same time). 在秘鲁,这个日期没有午夜(可能还有其他几个同时开始夏令时的语言环境,如果有的话)。 Most people testing this code would claim it works just fine since most people testing this code don't live in Peru. 大多数测试此代码的人会认为它工作正常,因为大多数测试此代码的人都不住在秘鲁。

I found a useful website with helpful information. 我找到了一个有用的网站,其中包含有用的信息。 See http://www.timeanddate.com/time/change/peru/lima?year=1990 for details about Peru and day light savings time. 有关秘鲁和夏令时的详细信息,请参见http://www.timeanddate.com/time/change/peru/lima?year=1990 Note that in 1989 and 1991, Peru did not use day light savings time. 请注意,在1989年和1991年,秘鲁没有使用夏时制。

For xCode 7.3 You need to use NSDateComponents 对于xCode 7.3,您需要使用NSDateComponents

var datef = NSDateFormatter()
datef.dateFormat = "dd-MM-yyyy";

var dtCompo = NSDateComponents()
dtCompo.day = 2
dtCompo.month = 1
dtCompo.year = 1990
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var date_f_a = cal.dateFromComponents(dtCompo)

dtCompo = NSDateComponents()
dtCompo.day = 1
dtCompo.month = 1
dtCompo.year = 1990
var date_f_b = cal.dateFromComponents(dtCompo)

var date_f_a_string = datef.stringFromDate(date_f_a!)
var date_f_b_string = datef.stringFromDate(date_f_b!)

print(date_f_a_string)
print(date_f_b_string)

Output will 输出将 在此处输入图片说明 xCode 8.1 xCode 8.1

var datef = DateFormatter()
datef.dateFormat = "dd-MM-yyyy";

var dtCompo = DateComponents()
dtCompo.day = 2
dtCompo.month = 1
dtCompo.year = 1990
let cal = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
var date_f_a = cal.date(from: dtCompo)

dtCompo = DateComponents()
dtCompo.day = 1
dtCompo.month = 1
dtCompo.year = 1990
var date_f_b = cal.date(from: dtCompo)

var date_f_a_string = datef.string(from: date_f_a!)
var date_f_b_string = datef.string(from: date_f_b!)

print(date_f_a_string)
print(date_f_b_string)

Output will 输出将 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM