必要に迫られて作成してみました。NSDateのカテゴリです。和暦でも問題なく動いていることを確認しました。

月初と月末の日付を返すメソッドです。


    NSDate *baseDate = [self dateWithString:@"2014-03-03 00:00:00"];
    NSDate *bomDate = [NSDate gnz_BOMWithDate:baseDate];

    ---> 2014-03-31 00:00:00

こんな感じになります。

なんでこんなメソッドを作ったかというと、RSSリーダーのフィードのようなものを月別にまとめたい時に、フィードの更新日から月初の日付を算出して保持したいなあと思ったのです。あと、FMDBを使ってSQLでDBを操作するときに、1日から末日までのデータを取得するときに、BETWEEN句で1日から末日までを指定したかったから、というのもあります。

なので、元のNSDateインスタンスの時間部分はすべて無視されて00:00:00になります。今思えば、末日は23:59:59のほうがよかったような気がしますが、まあいいんじゃないでしょうか。

EOMの[retComponents setMonth:month + 1]が若干怪しいですが、年またぎでも問題なく動作しました。

月末はEOM(End Of Month)らしいけど、月初ってBOM(Begin Of Month)でいいのかな。。。

都合上 BOM、 EOM というメソッド名にしていますが、カテゴリに追加するときはプレフィックスを付けてくださいね。(xxx_BOM, xxx_EOM など)

- (NSDate *)BOM
{
    if (!self) {
        return nil;
    }

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:self];
    NSInteger year = [components year];
    NSInteger month = [components month];

    NSDateComponents *retComponents = [[NSDateComponents alloc] init];

    [retComponents setYear:year];
    [retComponents setMonth:month];

    return [calendar dateFromComponents:retComponents];
}

- (NSDate *)EOM
{
    if (!self) {
        return nil;
    }

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:self];
    NSInteger year = [components year];
    NSInteger month = [components month];

    NSDateComponents *retComponents = [[NSDateComponents alloc] init];

    [retComponents setYear:year];
    [retComponents setMonth:month + 1];

    return [calendar dateFromComponents:retComponents];
}