FSCalendar/Example/SSLunarDate/SSHolidayWest.m

299 lines
8.2 KiB
Objective-C
Executable File

//
// SSHolidayWest.m
// SSLunarDate
//
// Created by Jiejing Zhang on 13-2-21.
// Copyright (c) 2013 Jiejing Zhang. All rights reserved.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// The Easter algorithm is from
// HTTP://www.codeproject.com/Articles/1595/Calculating-Easter-Sunday
#import "SSHolidayWest.h"
@implementation SSHolidayWest
// TODO: need implement a cache with current year.
- (id) initWithCalendar:(NSCalendar *)calendar
{
self = [super init];
if (self) {
currentCalendar = calendar;
}
return self;
}
- (NSDate *) getDateFromYear:(int) year month: (int) month day: (int) day
{
unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *cal = currentCalendar;
NSDateComponents *parts = [cal components:flags
fromDate:[NSDate date]];
[parts setYear:year];
[parts setMonth:month];
[parts setDay:day];
return [cal dateFromComponents:parts];
}
- (NSDate *) getEasterMonday: (int) year
{
// good Friday is two day before easter day
NSDate *easterDay = [self getEaster:year];
NSDateComponents *c = [[NSDateComponents alloc] init];
c.day = 1;
return [currentCalendar
dateByAddingComponents:c toDate:easterDay options:0];
}
// calculate easter sunday
- (NSDate *) getEaster: (int) year
{
int correction = 0;
int day, month;
if (year < 1700) correction = 4;
else if (year < 1800) correction = 5;
else if (year < 1900) correction = 6;
else if (year < 2100) correction = 0;
else if (year < 2200) correction = 1;
else if (year < 2300) correction = 2;
else if (year < 2500) correction = 3;
day = (19 * (year % 19) + 24) % 30;
day = 22 + day + ((2 * (year % 4) + 4 * (year % 7) + 6 * day + 5 + correction) % 7);
// jump to next month
if (day > 31) {
month = 4;
day -= 31;
} else {
month = 3;
}
// compose to a NSDate...
return [self getDateFromYear:year month:month day:day];
}
- (NSDate *) getGoodFriday: (int) year
{
// good Friday is two day before easter day
NSDate *easterDay = [self getEaster:year];
NSDateComponents *c = [[NSDateComponents alloc] init];
c.day = -2;
return [currentCalendar
dateByAddingComponents:c toDate:easterDay options:0];
}
- (NSDate *) getGoodFridayNextDay: (int) year
{
// one day after good Friday
NSDate *easterDay = [self getEaster:year];
NSDateComponents *c = [[NSDateComponents alloc] init];
c.day = -1;
return [currentCalendar
dateByAddingComponents:c toDate:easterDay options:0];
}
// Third Monday in January, Birthday of Dr. Martin Luther King, Jr.
- (NSDate *) getMartinLutherKingBirthday: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 1;
c.weekdayOrdinal = 3; // third week
c.weekday = 2; // Monday
c.year = year;
return [calendar dateFromComponents:c];
}
// Third Monday in Feb
- (NSDate *) getPresidentsDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 2;
c.weekdayOrdinal = 3; // third week
c.weekday = 2; // Monday
c.year = year;
return [calendar dateFromComponents:c];
}
// Last Monday in May Memorial Day
- (NSDate *) getMemorialDay: (int) year
{
NSCalendar* calendar = currentCalendar;
NSDateComponents* firstMondayInJuneComponents = [NSDateComponents new] ;
firstMondayInJuneComponents.month = 6 ;
firstMondayInJuneComponents.weekdayOrdinal = 1 ;
firstMondayInJuneComponents.weekday = 2 ; //Monday
firstMondayInJuneComponents.year = year;
NSDate* firstMondayInJune = [calendar
dateFromComponents:firstMondayInJuneComponents] ;
// --> 2012-06-04
NSDateComponents* subtractAWeekComponents = [NSDateComponents new] ;
subtractAWeekComponents.weekOfYear = -1 ;
NSDate* memorialDay = [calendar dateByAddingComponents:subtractAWeekComponents
toDate:firstMondayInJune options:0] ;
// --> 2012-05-28
return memorialDay;
}
// First Monday in Septembe Labor Day
- (NSDate *) getLaborDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 9;
c.weekdayOrdinal = 1;
c.weekday = 2; // Monday
c.year = year;
return [calendar dateFromComponents:c];
}
// Second Monday in October Columbus Day
- (NSDate *) getColumbusDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 10;
c.weekdayOrdinal = 2;
c.weekday = 2; // Monday
c.year = year;
return [calendar dateFromComponents:c];
}
// Fourth Thursday in November
- (NSDate *) getThanksGivingDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 11;
c.weekdayOrdinal = 4;
c.weekday = 5;
c.year = year;
return [calendar dateFromComponents:c];
}
// 1st Monday in May
- (NSDate *) getMayBankDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 5;
c.weekdayOrdinal = 1; // 1st
c.weekday = 2; // Monday
c.year = year;
return [calendar dateFromComponents:c];
}
// last Monday in may
- (NSDate *) getSpringBankDay: (int) year
{
return [self getMemorialDay:year];
}
// last Monday in August
- (NSDate *) getLateSummaryBankHoliday: (int) year
{
NSCalendar* calendar = currentCalendar;
NSDateComponents* firstMondayNextMonthComponents = [NSDateComponents new] ;
firstMondayNextMonthComponents.month = 9 ;
firstMondayNextMonthComponents.weekdayOrdinal = 1 ;
firstMondayNextMonthComponents.weekday = 2 ; //Monday
firstMondayNextMonthComponents.year = year;
NSDate* firstMondayNextMonth = [calendar
dateFromComponents:firstMondayNextMonthComponents] ;
//
NSDateComponents* subtractAWeekComponents = [NSDateComponents new] ;
subtractAWeekComponents.weekOfYear = -1 ;
NSDate* day = [calendar dateByAddingComponents:subtractAWeekComponents
toDate:firstMondayNextMonth options:0] ;
return day;
}
- (NSDate *) getBoxingDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 12;
c.day = 26;
c.year = year;
NSDate *d = [calendar dateFromComponents:c];
NSDateComponents *cc = [calendar components:NSCalendarUnitWeekday fromDate:d];
if (cc.weekday == 1) {// if sunday, move to next monday
c.day = 27;
return [calendar dateFromComponents:c];
} else
return d;
}
// Last Monday before 5/25
- (NSDate *) getVictoriaDay: (int) year
{
NSCalendar *calendar = currentCalendar;
NSDateComponents *c = [[NSDateComponents alloc] init];
c.month = 5;
c.day = 24;
c.year = year;
NSDate *may24 = [calendar dateFromComponents:c];
NSDateComponents *cc = [calendar components:NSCalendarUnitWeekday fromDate:may24];
// if that day was monday, it equal to zero.
// if that day was tue, it equal to 1, minor 1 =
NSDateComponents *ccc = [NSDateComponents new];
int reminder = cc.weekday - 2;
if (reminder >= 0)
ccc.day = - (cc.weekday - 2);
else
ccc.day = -6; // only happen when 24 is sunday.
return [calendar dateByAddingComponents:ccc toDate:may24 options:0];
}
@end