2012年9月1日土曜日

NSDate, NSDateComponents でiOSの時間を制する(その2)

前回(iOSの時間を制する) という題で, NSDate, NSDateComponentsを使って, GMT時間とローカル時間を行ったり来たりする方法を書きました。

今回はその続きです。

最近, アプリ内でカレンダーが欲しかったので,  さくっと実装してみました。
その時に出た副産物です。





ラインナップ

1. 月初めって何曜日?
2. 今月は何日まであるのか?
3. 先月末の日付をとってこよう
4. 1か月後の日付をとってこよう

他にも結構ありますが今回はこれくらいで。※NSDate で取得した時間はGMT時間です

1. 月初めって何曜日?

・実装手順
-  まず, 月はじめが欲しい日付(たとえば今日とか)の日付を NSDate * でとってくる
-  NSDateComponents で,現地時間を取得
-  その現地時間に 日付の1をセット
- それをもとにもう一度 NSDate * をつくる
-  NSDateComponents を再度つくり, 要素に NSWeekdayCalendarUnit を入れる
-  NSDateComponents の weekday で, 今日が何番目の曜日かを取得
(1:日曜日 ~ 7:土曜日)

例)  今日の日付から, 月初めを取ってくる
NSDate *date = [NSDate date];                    // 現在の GMT時間


NSDateComponents *comps;
NSCalendar *calendar = [NSCalendar currentCalendar];
comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit fromDate:date];
[comps setDay:1];

NSDate *d = [calendar dateFromComponents:comps];
comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit fromDate:d];
int week_day = [comps weekday];



2. 今月は何日まであるのか?

- NSCalendar で, 日付などのlimitationがどこまであるかを表す  rangeOfUnit 
を利用する
- NSRange の length で最終日を取得できる

NSDate *date = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSRange range = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
int last =  range.length;



※どこからかサンプルをいただきました。出典忘れてしまいましたすみません。


3. 先月末の日付を取ってこよう

※ある種のテクニックですね
-  NSDateComponents で, 年, 月を取得しておきます
-  新しいNSDateComponentsをつくって, setDay で -1 を入れます
-  これをもとに, NSDate *をつくります

NSDate *date = [NSDate date];

NSDateComponents *comps;
NSCalendar *calendar = [NSCalendar currentCalendar];
comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:date];
NSInteger year = [comps year];
NSInteger month = [comps month];
   
NSDateComponents *ret_comps = [[NSDateComponents alloc] init];
   
[ret_comps setYear:year];
[ret_comps setMonth:month];
[ret_comps setDay:-1];
//[ret_comps setHour:0];
//[ret_comps setMinute:0];
//[ret_comps setSecond:0];
NSDate *prevMonth =  [calendar dateFromComponents:ret_comps];


4. 1か月後の日付をとってこよう

※うまい方法が見つからなかったので, 地道に場合分けでmonthが 12 ならしゃーなしで。



NSDateComponents *comps;
NSCalendar *calendar = [NSCalendar currentCalendar];
comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:date];
NSInteger year = [comps year];
NSInteger month = [comps month];
NSInteger day = [comps day];
   
NSDateComponents *ret_comps = [[NSDateComponents alloc] init];
   
if ( month == 12 )
{
    month = 1;
    year++;
}
else
{
    month++;
}
   
[ret_comps setYear:year];
[ret_comps setMonth:month];
[ret_comps setDay:day];
[ret_comps setHour:0];
[ret_comps setMinute:0];
[ret_comps setSecond:0];
NSDate *next =  [calendar dateFromComponents:ret_comps];









0 件のコメント:

コメントを投稿