既存のNSDate
の時間を設定するにはどうすればよいですか?
つまり、日付(たとえば、現在の日付/時刻)がありますが、これを特定の時刻(たとえば11.23am)に設定したいとします。目的Cでこれを行う最も速い方法は何ですか?
私はNSCalendar
を調べており、dateByAddingComponents:toDate:options:
、dateFromComponents:
、しかし、これらは私がここで必要とするものの基準を完全には満たしていないようです。例えば:
dateFromComponents:
-これが機能するには、やりすぎのように見えるすべてのコンポーネントを計算する必要があります。dateByAddingComponents:toDate:options:
-私の場合は追加したくないが、時間を「設定」したい。NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];
[components setHour: 7];
[components setMinute: 59];
[components setSecond: 17];
NSDate *newDate = [gregorian dateFromComponents: components];
特定のOR結合ビットマスクの代わりにNSUIntegerMax
を使用しています。これは簡単なためですが、受信するデータコンポーネントを指定する場合は、ゲストにしてください。
iOS 7注: NSUIntegerMaxの使用がiOS7では機能しなくなったため、これをいくつかの質問に入れました。これを使用すると、尾を約3時間追跡しました。 NSUIntegerMax
を使用すると、NSDateComponents
ignoresが年を設定することがわかりました。たとえば、これは年を変更しません:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:NSUIntegerMax fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];
これが行うのに対して:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger timeComps = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit);
NSDateComponents *comps = [gregorian components:timeComps fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];
これはiOS7のバグであるか、NSUIntegerMaxを使用しても動作しなかったために機能しなくなった可能性があります。バグレポートを提出し、最終的な回答を得ます。
とにかく、予期しない結果を回避したい場合は、すべてのコンポーネントを指定してください。
特定の日付を午前8時に設定する方法のSwift 2.0バージョン
extension NSDate {
func setTo8AM() -> NSDate {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
components.hour = 8
return calendar.dateFromComponents(components)!
}
}
これを適用して、別の日付から既存の日付に時間を設定します
NSDate *today = [NSDate date]; // from which i need only "Year" "Month" "Date"
NSCalendar *calendar = [NSCalendar currentCalendar]
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit ) fromDate:today];
NSDate *timeDate = datePicker.date; // from which i need only "Hours" "Minutes" and "Seconds"
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:timeDate];
[dateComponents setHour:[timeComponents hour]];
[dateComponents setMinute:[timeComponents minute]];
[dateComponents setSecond:[timeComponents second]];
NSDate *newDate = [calendar dateFromComponents:dateComponents]; // New Date with My "Year" "Month" "Date" "Hours" "Minutes" and "Seconds"
NSLog(@"New Date: %@",newDate);
Andrew Schreiberの役立つ回答に基づいて構築された、より一般的なSwift(v2.1.1)拡張機能を次に示します。
extension NSDate {
func dateWithTime(hour: Int, minute: Int, second: Int) -> NSDate? {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
components.hour = hour
components.minute = minute
components.second = second
let newDate = calendar.dateFromComponents(components)
return newDate
}
}
A Swiftの例。私の目的のために、私は明日の正午頃の日付を取得したいと思っていました。
var tomorrow:NSDate = NSDate().dateByAddingTimeInterval(60*60*24); //60seconds*60minutes*12hours
var gregorian:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!;
var unit : NSCalendarUnit = (NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.DayCalendarUnit|NSCalendarUnit.HourCalendarUnit|NSCalendarUnit.MinuteCalendarUnit);
var comps:NSDateComponents = gregorian.components(unit, fromDate: tomorrow);
comps.setValue(12, forComponent: NSCalendarUnit.HourCalendarUnit);
comps.setValue(0, forComponent: NSCalendarUnit.MinuteCalendarUnit);
var noon_tomorrow : NSDate = gregorian.dateFromComponents(comps)!;