実装
DateUtility というクラスを作り、そこへクラスメソッドを実装する。
@interface DateUtility : NSObject { } + (NSInteger)daysBetween:(NSDate*)startDate and:(NSDate*)endDate;
+ (NSDate*)adjustZeroClock:(NSDate*)date withCalendar:(NSCalendar*)calendar { NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date]; return [calendar dateFromComponents:components]; } + (NSInteger)daysBetween:(NSDate*)startDate and:(NSDate*)endDate { NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; startDate = [DateUtility adjustZeroClock:startDate withCalendar:calendar]; endDate = [DateUtility adjustZeroClock:endDate withCalendar:calendar]; NSDateComponents *components = [calendar components:NSDayCalendarUnit fromDate:startDate toDate:endDate options:0]; NSInteger days = [components day]; [calendar release]; return days; }
NSCalendar を使うと2つの日付間の日数を簡単に取得できる。ポイントとしては +adjustZeroClock:withCalendar: を使い、時刻を 0:00 に合わせていること。これをやらないと日時まで含めた比較となってしまう。
(例)7/25 11:00〜7/27 9:00 のケース [A] 時刻補正なし:1日となる。 [B] 時刻補正あり:2日となる。補正が不要であれば +ajdustZeroClock:withCalendar: の呼出をやめる。
なお -[NSCalendar components:fromDate:toDate:options:] の最初に引数に NSMonthCalendarUnit を含めると、結果は日数ではなく月数+日数の組み合わせになるので注意が必要。
(例)7/10〜8/19の日のケース [A] NSDayCalendarUnit|NSMonthCalendarUnit [components month] == 1 [components day] == 10 [B] NSDayCalendarUnit [components day] == 40
参考情報
- NSDate Class Reference
- NSDateのリファレンス
- NSCalendar Class Reference
- NSCalendarのリファレンス
- NSDateComponents Class Reference
- NSDateComponentsのリファレンス
- Date and Time Programming Guide
- 日付関連クラスの解説
匿名
2012年11月11日 1:24
とても参考になりました。ありがとうございます!
ビルドしてみたらエラーになりましたが
メソッド名の
and:
を
別のラベルにしたらOKでした。
andって予約後でしたっけね。
匿名
2012年11月11日 1:24
とても参考になりました。ありがとうございます!
ビルドしてみたらエラーになりましたが
メソッド名の
and:
を
別のラベルにしたらOKでした。
andって予約後でしたっけね。
匿名
2012年11月11日 1:32
同投稿者です。
andがだめだったのは、自分の環境では
Objective-C++にしてたからでした。いやいやすいません。。
C++だとandは予約語なんですね。
匿名
2012年11月11日 1:32
同投稿者です。
andがだめだったのは、自分の環境では
Objective-C++にしてたからでした。いやいやすいません。。
C++だとandは予約語なんですね。