1 : 	// c_date
     2 : 	
     3 : 	#include <windows.h>
     4 : 	#include "c_date.h"
     5 : 	
     6 : 	
     7 : 	static const char k_szDayOfWeekStrJpn[9][5] =
     8 : 		{"−","日","月","火","水","木","金","土","−"};
     9 : 	static const char k_szDayOfWeekStrEng[9][5] =
    10 : 		{"-","Sun","Mon","The","Wed","Thu","Fri","Sta","-"};
    11 : 	
    12 : 	C_DATE::C_DATE()
    13 : 	{
    14 : 		::ZeroMemory(&m_Systime,sizeof(m_Systime));
    15 : 	}
    16 : 	C_DATE::C_DATE(int y,int m,int d)
    17 : 	{
    18 : 		::ZeroMemory(&m_Systime,sizeof(m_Systime));
    19 : 		m_Systime.wYear = y;
    20 : 		m_Systime.wMonth = m;
    21 : 		m_Systime.wDay = d;
    22 : 	}
    23 : 	
    24 : 	//現在時刻取得
    25 : 	void
    26 : 	C_DATE::GetLocalTime()
    27 : 	{
    28 : 		::GetLocalTime(&m_Systime);
    29 : 	}
    30 : 	
    31 : 	//曜日を算出
    32 : 	int
    33 : 	C_DATE::GetDayOfWeek(BOOL fFirstDay)
    34 : 	{
    35 : 		int y=m_Systime.wYear;
    36 : 		int m=m_Systime.wMonth;
    37 : 		int d;
    38 : 		if(fFirstDay){
    39 : 			d = 1;
    40 : 		}else{
    41 : 			d=m_Systime.wDay;
    42 : 		}
    43 : 		int iDayOfWeek;
    44 : 		if(m==1 || m==2) {
    45 : 			y--;
    46 : 			m+=12;
    47 : 		}
    48 : 	
    49 : 		//ツェラーの公式
    50 : 		if (y*366+m*31+d < 1582*366+10*31+15)
    51 : 			return -1;
    52 : 		iDayOfWeek = (y + y/4 - y/100 + y/400 + (13*m+8)/5 + d) % 7;
    53 : 		//
    54 : 	
    55 : 		m_Systime.wDayOfWeek = iDayOfWeek;
    56 : 		return iDayOfWeek;
    57 : 	}
    58 : 	
    59 : 	//文字列取得(値は変更しない)
    60 : 	const char*
    61 : 	C_DATE::GetDayOfWeekStrJpn()
    62 : 	{
    63 : 		return &k_szDayOfWeekStrJpn[m_Systime.wDayOfWeek+1][0];
    64 : 	}
    65 : 	
    66 : 	//月の最後の日
    67 : 	int
    68 : 	C_DATE::GetLastDayOfMonth()
    69 : 	{
    70 : 		int y = m_Systime.wYear;
    71 : 		int m = m_Systime.wMonth;
    72 : 		int last;
    73 : 		switch(m){
    74 : 			case 1:last = 31;break;
    75 : 			case 2:
    76 : 				//うるう年の算出
    77 : 				if(y % 4 ==0){
    78 : 					if(y % 100 == 0) {
    79 : 						if(y % 400 == 0){
    80 : 							last=29;		
    81 : 						}else{
    82 : 							last=28;
    83 : 						}
    84 : 					}else{
    85 : 						last=29;
    86 : 					}
    87 : 				}else{
    88 : 					last=28;
    89 : 				}
    90 : 				break;
    91 : 			case 3:last = 31;break;
    92 : 			case 4:last = 30;break;
    93 : 			case 5:last = 31;break;
    94 : 			case 6:last = 30;break;
    95 : 			case 7:last = 31;break;
    96 : 			case 8:last = 31;break;
    97 : 			case 9:last = 30;break;
    98 : 			case 10:last = 31;break;
    99 : 			case 11:last = 30;break;
   100 : 			case 12:last = 31;break;
   101 : 			default: return 0;
   102 : 		}
   103 : 		return last;
   104 : 	}
   105 : 	
   106 : 	//春分
   107 : 	int 
   108 : 	C_DATE::GetVernalEquinoxDay()
   109 : 	{
   110 : 	
   111 : 		int y = m_Systime.wYear;
   112 : 		int  d;
   113 : 		if(y<1851) return -1;
   114 : 		else if(y < 1900){
   115 : 			d = (int)(19.8277 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
   116 : 		}else if(y < 1980){
   117 : 			d = (int)(20.8357 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
   118 : 		}else if(y < 2100){
   119 : 			d = (int)(20.8431 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
   120 : 		}else if(y < 2151){
   121 : 			d = (int)(21.8510 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
   122 : 		}else return -1;
   123 : 	//	m_Systime.wMonth = 3;
   124 : 		m_VernalEquinoxDay = d;
   125 : 		return d;
   126 : 	}
   127 : 	
   128 : 	//秋分
   129 : 	int 
   130 : 	C_DATE::GetAutumnalEquinoxDay()
   131 : 	{
   132 : 	
   133 : 		int y = m_Systime.wYear;
   134 : 		int  d;
   135 : 		if(y<1851) return -1;
   136 : 		else if(y < 1900){
   137 : 			d = (int)(22.2588 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
   138 : 		}else if(y < 1980){
   139 : 			d = (int)(23.2588 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
   140 : 		}else if(y < 2100){
   141 : 			d = (int)(23.2488 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
   142 : 		}else if(y < 2151){
   143 : 			d = (int)(24.2488 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
   144 : 		}else return -1;
   145 : 	//	m_Systime.wMonth = 9;
   146 : 		m_AutumnalEquinoxDay = d;
   147 : 		return d;
   148 : 	}
   149 : 	
   150 : 	//第何曜日かを求める
   151 : 	int C_DATE::GetNumOfWeek(int d)
   152 : 	{
   153 : 		if(d==0) d = m_Systime.wDay;
   154 : 		return (d-1) / 7 + 1;
   155 : 	}
   156 : 	
   157 : 	
   158 : 	
   159 : 	//休日かどうかの判定
   160 : 	int C_DATE::IsHoliday(BOOL fPrevDay)
   161 : 	{
   162 : 		int y = m_Systime.wYear;
   163 : 		int m = m_Systime.wMonth;
   164 : 		int d = m_Systime.wDay;
   165 : 		if(this->GetDayOfWeek() == -1) return 0;
   166 : 	
   167 : 		int w = m_Systime.wDayOfWeek;
   168 : 	
   169 : 		if(fPrevDay){
   170 : 			//月末の祝日は存在しないのでd==0を容認
   171 : 			d--;
   172 : 			if(w==0) w = 6;
   173 : 			else w--;
   174 : 		}
   175 : 	
   176 : 	
   177 : 		int c = this->GetNumOfWeek();
   178 : 	
   179 : 		if(m==9)
   180 : 			this->GetAutumnalEquinoxDay();
   181 : 		if(m==3)
   182 : 			this->GetVernalEquinoxDay();
   183 : 	
   184 : 	
   185 : 		if(m==1 && d==1){
   186 : 			return DAY_NEWYEARSDAY;
   187 : 		}else if((y >= 1949 && y < 2000) &&  m==1 && d==15){
   188 : 			//1949-1999 1月、15日
   189 : 			return DAY_SEIJINNOHI;
   190 : 		}else if((y >= 2000) &&  m==1 && w==1 && c == 2){
   191 : 			//2000〜、1月、月曜日、第2
   192 : 			return DAY_SEIJINNOHI;
   193 : 		}else if(y>= 1967 && m==2 && d==11){
   194 : 			//1967〜、2月、11日
   195 : 			return DAY_KENKOKUKINENBI;
   196 : 		}else if(y>= 1949 && y<1989 && m==4 && d==29){
   197 : 			//1949〜1988、4月、29日
   198 : 			return DAY_TENNOUTANJOBI;
   199 : 		}else if(y>=1989 && m==4 && d==29){
   200 : 			//1989〜、4月、29日
   201 : 			return DAY_MIDORINOHI;
   202 : 		}else if(y>=1949 && m==5 && d==3){
   203 : 			//1949〜、5月、3日
   204 : 			return DAY_KENPOUKINENBI;
   205 : 		}else if(y>=1986 && m==5 && d==4){
   206 : 			//1986〜、5月、4日
   207 : 			return DAY_KOKUMINNOKYUJITU5;
   208 : 		}else if(y>=1949 && m==5 && d==5){
   209 : 			//1949〜、5月、5日
   210 : 			return DAY_KODOMONOHI;
   211 : 		}else if(y>=1996  && y<2003  && m==7 && d==20){
   212 : 			//1949〜2002、7月、20日
   213 : 			return DAY_UMINOHI;
   214 : 		}else if(y>=2003 && m==7 && w==1 &&c==3){
   215 : 			//2003〜、7月、月曜、第3
   216 : 			return DAY_UMINOHI;
   217 : 		}else if(y>=1966  && y<2003  && m==9 && d==15){
   218 : 			//1966〜2002、9月、15日
   219 : 			return DAY_KEIROUNOHI;
   220 : 		}else if(y>=2003 && m==9 && w==1 &&c==3){
   221 : 			//2003〜、9月、月曜、第3
   222 : 			return DAY_KEIROUNOHI;
   223 : 		}else if(y>=1966  && y<2003  && m==10 && d==10){
   224 : 			//1966〜2002、10月、10日
   225 : 			return DAY_TAIKUNOHI;
   226 : 		}else if(y>=2003 && m==10 && w==1 &&c==2){
   227 : 			//2003〜、10月、月曜、第2
   228 : 			return DAY_TAIKUNOHI;
   229 : 		}else if(y>=1948 && m==11 && d==3){
   230 : 			//1948〜、11月、3日
   231 : 			return DAY_BUNKANOHI;
   232 : 		}else if(y>=1948 && m==11 && d==23){
   233 : 			//1948〜、11月、23日
   234 : 			return DAY_KINROUKANSYANOHI;
   235 : 		}else if(y>=1989 && m==12 && d==23){
   236 : 			//1989〜、11月、23日
   237 : 			return DAY_TENNOUTANJOBI2;
   238 : 		}else if(y>=2003 && m==9 && GetNumOfWeek(d-1)==3 && w-1 == 1 
   239 : 			&& (d+1)==m_AutumnalEquinoxDay){
   240 : 			//2003〜、9月、前日が第3月曜日、翌日が秋分の日
   241 : 			return DAY_KOKUMINNOKYUJITU9;
   242 : 		}else if(m==3 && d==m_VernalEquinoxDay){
   243 : 			//春分
   244 : 			return DAY_SYUNBUNNOHI;
   245 : 		}else if(m==9 && d==m_AutumnalEquinoxDay){
   246 : 			//秋分
   247 : 			return DAY_SYUUBUNNOHI;
   248 : 		}
   249 : 	
   250 : 		//前日の調査
   251 : 		if(fPrevDay == FALSE && w == 1){
   252 : 			d--;
   253 : 			if(d!=0){
   254 : 				if(IsHoliday(TRUE)!=DAY_WEEKDAY){
   255 : 					return DAY_HURIKAEKYUJITU;
   256 : 				}
   257 : 			}
   258 : 		}
   259 : 	
   260 : 		return DAY_WEEKDAY;
   261 : 	}
   262 : 	
   263 : 	char*
   264 : 	C_DATE::GetHolidayStr()
   265 : 	{
   266 : 		switch(this->IsHoliday()){
   267 : 		case DAY_WEEKDAY:
   268 : 			return TEXT("");
   269 : 		case DAY_NEWYEARSDAY:
   270 : 			return TEXT("元旦");
   271 : 		case DAY_SEIJINNOHI:
   272 : 			return TEXT("成人の日");
   273 : 		case DAY_KENKOKUKINENBI:
   274 : 			return TEXT("建国記念の日");
   275 : 		case DAY_TENNOUTANJOBI:
   276 : 			return TEXT("天皇誕生日");
   277 : 		case DAY_MIDORINOHI:
   278 : 			return TEXT("みどりの日");
   279 : 	
   280 : 		case DAY_KENPOUKINENBI:
   281 : 			return TEXT("憲法記念日");
   282 : 		case DAY_KOKUMINNOKYUJITU5:
   283 : 			return TEXT("国民の休日");
   284 : 		case DAY_KODOMONOHI:
   285 : 			return TEXT("子供の日");
   286 : 		case DAY_UMINOHI:
   287 : 			return TEXT("海の日");
   288 : 		case DAY_KEIROUNOHI:
   289 : 			return TEXT("敬老の日");
   290 : 		case DAY_TAIKUNOHI:
   291 : 			return TEXT("体育の日");
   292 : 		case DAY_BUNKANOHI:
   293 : 			return TEXT("文化の日");
   294 : 	
   295 : 		case DAY_KINROUKANSYANOHI:
   296 : 			return TEXT("勤労感謝の日");
   297 : 	
   298 : 		case DAY_TENNOUTANJOBI2:
   299 : 			return TEXT("天皇誕生日");
   300 : 	
   301 : 		case DAY_KOKUMINNOKYUJITU9:
   302 : 			return TEXT("国民の休日");
   303 : 		case DAY_SYUNBUNNOHI:
   304 : 			return TEXT("春分の日");
   305 : 	
   306 : 		case DAY_SYUUBUNNOHI:
   307 : 			return TEXT("秋分の日");
   308 : 	
   309 : 		case DAY_HURIKAEKYUJITU:
   310 : 			return TEXT("振替休日");
   311 : 	
   312 : 		}
   313 : 	
   314 : 		return TEXT("");
   315 : 	}
   316 : 	
   317 : 	//1日戻す
   318 : 	void C_DATE::BackDay(BOOL fCalcDayOfWeek)
   319 : 	{
   320 : 		if(m_Systime.wDay > 1){ 
   321 : 			//1日以外
   322 : 			m_Systime.wDay --;
   323 : 		}else{
   324 : 			//1日の場合
   325 : 			if(m_Systime.wMonth == 1){
   326 : 				//1月の場合
   327 : 				m_Systime.wMonth = 12;
   328 : 				m_Systime.wYear --;
   329 : 			}else{
   330 : 				m_Systime.wMonth --;
   331 : 			}
   332 : 			m_Systime.wDay = this->GetLastDayOfMonth();
   333 : 		}
   334 : 	
   335 : 		if(fCalcDayOfWeek) GetDayOfWeek();
   336 : 	}
   337 : 	
   338 : 	
   339 : 	void C_DATE::operator=(C_DATE &src){
   340 : 		CopyMemory(&m_Systime,src.GetDatePointer(),sizeof(m_Systime));
   341 : 	}