2017-03-10 1 views
1

아래 예제 코드는 현재 날짜에서 DateComponents를 가져 와서 구성 요소를 수정하고 수정 된 구성 요소에서 새 Date를 만듭니다. 그것은 또한 새로운 DateComponents 객체를 생성하고, 그것을 채우고, 그로부터 새로운 Date를 생성하는 것을 보여줍니다. 다른 년, 월, 일, 등, 다음 날짜를 얻을 수있는 구성 요소를 사용 설정 내가 구성 요소를 수정하는 경우 Swift : DateComponents 연도를 설정할 때 예기치 않은 동작

import Foundation 

let utcHourOffset = -7.0 
let tz = TimeZone(secondsFromGMT: Int(utcHourOffset*60.0*60.0))! 
let calendar = Calendar(identifier: .gregorian) 
var now = calendar.dateComponents(in: tz, from: Date()) 

// Get and display current date 
print("\nCurrent Date:") 
print("\(now.month!)/\(now.day!)/\(now.year!) \(now.hour!):\(now.minute!):\(now.second!) \(now.timeZone!)") 
let curDate = calendar.date(from: now) 
print("\(curDate!)") 

// Modify and display current date 
now.year = 2010 
now.month = 2 
now.day = 24 
now.minute = 0 
print("\nModified Date:") 
print("\(now.month!)/\(now.day!)/\(now.year!) \(now.hour!):\(now.minute!):\(now.second!) \(now.timeZone!)") 
let modDate = calendar.date(from: now) 
print("\(modDate!)") 

// Create completely new date 
var dc = DateComponents() 
dc.year = 2014 
dc.month = 12 
dc.day = 25 
dc.hour = 10 
dc.minute = 12 
dc.second = 34 
print("\nNew Date:") 
print("\(dc.month!)/\(dc.day!)/\(dc.year!) \(dc.hour!):\(dc.minute!):\(dc.second!) \(now.timeZone!)") 
let newDate = calendar.date(from: dc) 
print("\(newDate!)") 

는, 나는 새로운 날짜가 수정 된 모든 구성 요소를 가지고있는 예상치 못한 결과를 얻을 수 변경되지 않은 연도는 예외입니다.

DateComponents 객체를 만들고 채우면 날짜를 작성하면 예상대로 작동합니다.

코드의 출력은 다음과 같습니다

Current Date: 
3/9/2017 19:5:30 GMT-0700 (fixed) 
2017-03-10 02:05:30 +0000 

Modified Date: 
2/24/2010 19:0:30 GMT-0700 (fixed) 
2017-02-25 02:00:30 +0000 

New Date: 
12/25/2014 10:12:34 GMT-0700 (fixed) 
2014-12-25 17:12:34 +0000 

나는 2010-02-25 02:00:30 +0000보다는 2017-02-25 02:00:30 +0000으로 수정 된 날짜를 예상했다. 왜 안 그래? 왜 두 번째 경우에 작동합니까?

DateComponents의 docs은 "NSDateComponents의 인스턴스가 초기화 된 정보를 초과하는 날짜에 대한 답변에 대한 책임이 없습니다 ..."라고 말합니다. DateComponents 객체가 1 년으로 초기화되었으므로, 적용되지 않는 것처럼 보였습니다. 그러나 관찰 한 동작을 설명 할 수있는 문서에서 본 것은 유일한 것입니다.

답변

1

nowdc을 기록하면 문제가 발생합니다. nowDate에서 생성됩니다. 그러면 yearForWeekOfYear 및 요일 관련 구성 요소 중 몇 개를 비롯한 모든 날짜 구성 요소가 채워집니다. 이러한 구성 요소로 인해 modDate이 잘못 나옵니다.

newDate은 특정 구성 요소 만 설정되기 때문에 예상대로 작동합니다.

일부 추가 구성 요소를 재설정하면 modDate이 올바르게 나올 수 있습니다. 특히, 추가 :

now.yearForWeekOfYear = nil 

그냥 modDate의 예상 날짜가 발생합니다 modDate를 작성하기 전에. 필요에 따라 물론 가장 좋은 방법은 DateComponents의 새로운 인스턴스를 생성하고 이전 DateComponents에서 특정 값을 사용하는 것입니다

let mod = DateComponents() 
mod.timeZone = now.timeZone 
mod.year = 2010 
mod.month = 2 
mod.day = 24 
mod.hour = now.hour 
mod.minute = 0 
mod.second = now.second 
print("\nModified Date:") 
print("\(mod.month!)/\(mod.day!)/\(mod.year!) \(mod.hour!):\(mod.minute!):\(mod.second!) \(mod.timeZone!)") 
let modDate = calendar.date(from: mod) 
print("\(modDate!)")