2016-12-14 2 views
0

이상한 일이 일어납니다. 이 특정 날짜 (1994-04-01) 문자열을 변환 할 수 없습니다. 누구든지이 내용을 확인하고 코드에서 재생산하면 알려 주실 수 있습니까?이 특정 날짜의 NSDate로 변환 할 수 없습니다 (1994-04-01). 문자열

단계 재현하기 :

스위프트 -

let dateString = "1994-04-01" 
let dateFormatter = DateFormatter() 
dateFormatter.dateFormat = "yyyy-MM-dd" 
let dateFromString = dateFormatter.date(from: dateString) 

를 Obj C : -

NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; 
[formatter setDateFormat:@"yyyy-MM-dd"]; 
NSString *birthdayStr = @"1994-04-01"; 
NSDate *birthday = [formatter dateFromString:birthdayStr]; 

예상 결과 :

birthday = 1994-03-31 21:00:00 +0000 

UTC

에서

실제 결과 :

birthday = nil 

버전 :

엑스 코드 VER : - 버전 8.1 (8B62)

OS X의 버전 : - 10.12.1 (16B2555)

당신이 시도 할 수 있습니다 어떤 다른 날짜 (1994-04-01) 그리고 그것은 잘 작동합니다.

+0

기울임 꼴로 코드를 게시하지 마십시오. 대신 코드 블록을 사용하십시오. –

+0

@CodeDifferent : 문제를 전혀 설명하지 않습니다. 제대로 파싱되지 않았습니다. 예기치 않은 시간대에 나타나는 것과 같지 않습니다. –

+0

'캘린더'가 부적절한 것일 수도 있습니다. 그레고리력으로 명시 적으로 설정해보십시오. –

답변

7

테스트 코드 :

import Foundation 

for timeZoneId in TimeZone.knownTimeZoneIdentifiers { 
    let dateString = "1994-04-01" 
    let dateFormatter = DateFormatter() 
    dateFormatter.timeZone = TimeZone(identifier: timeZoneId) 
    dateFormatter.dateFormat = "yyyy-MM-dd" 
    if dateFormatter.date(from: dateString) == nil { 
     print(timeZoneId) 
    } 
} 

출력 :

Asia/Amman 
Asia/Damascus 
Asia/Gaza 
Asia/Hebron 
Asia/Jerusalem 

내가 시스템 시간대가 인쇄 된 것들 중 하나로 설정됩니다 결론 지었다. Google에 "jerusalem time zone 1994"을 입력하면 the first result에서 1994 년 4 월 1 일 자정에 일광 절약 시간제가 시작되었다고 알려줍니다. 이는 자정이 없음을 의미합니다. 1994 년 4 월 1 일의 첫 번째 순간은 실제로 해당 시간대의 오전 1시였습니다.

DateFormatter은 문자열에서 시간을 파싱하지 않을 때 기본적으로 자정 시각을 사용합니다. 이렇게하면 자정이 문자열의 날짜에 없을 때 실패합니다.

해결책은 기본 시간으로 자정을 사용하지 않는 것입니다. 정오가 훨씬 안전한 기본 시간입니다.

// Reference date was 00:00:00 UTC on 1 January 2001. This is noon of the same day in UTC. 
    dateFormatter.defaultDate = Date(timeIntervalSinceReferenceDate: 12*60*60) 
:

let dateString = "1994-04-01 12:00:00" 
    let dateFormatter = DateFormatter() 
    dateFormatter.timeZone = TimeZone(identifier: timeZoneId) 
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 

또 다른 해결책은 날짜 포맷 언젠가의 정오 기본 날짜를 제공하는 것입니다 : 그래서, 하나 개의 솔루션은 입력에 하루의 시간을 포함하고 형식으로 구문 분석하는 것입니다

iOS 또는 macOS에서 파싱 또는 조작을 수행하려는 경우 매우 일 것입니다. WWDC 2013 Session 227: Solutions to Common Date and Time Challenges을 보는 것이 좋습니다.

+0

탐정 작업의 뛰어난 비트. 특정 일 전용 날짜 문자열이 일광 절약 시간에 대한 "교차 일"을 변환하지 못하는 것은 매우 이상합니다. 잘못된 것 같아. –

+0

정오로 문제의 시간을 강요하는 대신, UTC에 서머 타임이 없기 때문에 날짜 포맷터의 시간대를 UTC로 설정하는 것이 더 좋지 않습니까? –

+0

정말 그 문자열을 파싱하는 이유에 따라 달라집니다. WWDC 세션을보십시오. –