📄 hijrah.cpp
字号:
/*
Copyright (C) 2002 Fayez Alhargan.
King Abdulaziz City for Science and Technology
Computer and Electronics Research Institute
Riyadh, Saudi Arabia
alhargan@kacst.edu.sa
Tel:4813770 Fax:4813764
This is a program that computes the Hijary dates for Umm-AlQura calendar
the official calendar of the Kingdom of Saudi Arabia.
version: opn1.2
last modified 22-1-2003
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser Library General Public License for more details.
*/
#include <stdlib.h>
#include <math.h>
#define HStartYear 1420
#define HEndYear 1450
int MonthMap[]={19410
,19396,19337,19093,13613,13741,15210,18132,19913,19858,19110
,18774,12974,13677,13162,15189,19114,14669,13469,14685,12986
,13749,17834,15701,19098,14638,12910,13661,15066,18132,18085
};
short gmonth[14]={31,31,28,31,30,31,30,31,31,30,31,30,31,31};/* makes it circular m[0]=m[12] & m[13]=m[1] */
short smonth[14]={31,30,30,30,30,30,29,31,31,31,31,31,31,30}; /* makes it circular m[0]=m[12] & m[13]=m[1] */
int BH2GA(int yh,int mh,int *yg,int *mg, int *dg,int *dayweek);
int G2HA(int yg,int mg, int dg,int *yh,int *mh,int *dh,int *dayweek);
int H2GA(int *yh,int *mh,int *dh,int *yg,int *mg, int *dg,int *dayweek);
void S2G(int ys,int ms,int ds,int *yg,int *mg,int *dg);
void G2S(int yg,int mg,int dg,int *ys,int *ms,int *ds);
double GCalendarToJD(int yg,int mg, double dg );
double JDToGCalendar(double JD, int *yy,int *mm, int *dd);
int GLeapYear(int year);
void GDateAjust(int *yg,int *mg,int *dg);
int DayWeek(long JulianD);
void JDToHCalendar(double JD,int *yh,int *mh,int *dh);
void JDToHACalendar(double JD,int *yh,int *mh,int *dh);
double HCalendarToJD(int yh,int mh,int dh);
double HCalendarToJDA(int yh,int mh,int dh);
int HMonthLength(int yh,int mh);
double ip(double x);
int mod(double x, double y);
/****************************************************************************/
/* Name: BH2GA */
/* Type: Procedure */
/* Purpose: Finds Gdate(year,month,day) for Hdate(year,month,day=1) */
/* Arguments: */
/* Input: Hijrah date: year:yh, month:mh */
/* Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek */
/* and returns flag found:1 not found:0 */
/****************************************************************************/
int BH2GA(int yh,int mh,int *yg,int *mg, int *dg,int *dayweek)
{
int flag,Dy,m,b;
long JD;
double GJD;
/* Make sure that the date is within the range of the tables */
if(mh<1) {mh=12;}
if(mh>12) {mh=1;}
if(yh<HStartYear) {yh=HStartYear;}
if(yh>HEndYear) {yh=HEndYear;}
GJD=HCalendarToJDA(yh,mh,1);
JDToGCalendar(GJD,yg,mg,dg);
JD=GJD;
*dayweek=(JD+1)%7;
flag=1; /* date has been found */
return flag;
}
/****************************************************************************/
/* Name: HCalendarToJDA */
/* Type: Function */
/* Purpose: convert Hdate(year,month,day) to Exact Julian Day */
/* Arguments: */
/* Input : Hijrah date: year:yh, month:mh, day:dh */
/* Output: The Exact Julian Day: JD */
/****************************************************************************/
double HCalendarToJDA(int yh,int mh,int dh)
{
int flag,Dy,m,b;
long JD;
double GJD;
JD=HCalendarToJD(yh,1,1); /* estimate JD of the begining of the year */
Dy=MonthMap[yh-HStartYear]/4096; /* Mask 1111000000000000 */
GJD=JD-3+Dy; /* correct the JD value from stored tables */
b=MonthMap[yh-HStartYear];
b=b-Dy*4096;
for(m=1;m<mh;m++)
{
flag=b%2; /* Mask for the current month */
if(flag) Dy=30; else Dy=29;
GJD=GJD+Dy; /* Add the months lengths before mh */
b=(b-flag)/2;
}
GJD=GJD+dh-1;
return GJD;
}
/****************************************************************************/
/* Name: HMonthLength */
/* Type: Function */
/* Purpose: Obtains the month length */
/* Arguments: */
/* Input : Hijrah date: year:yh, month:mh */
/* Output: Month Length */
/****************************************************************************/
int HMonthLength(int yh,int mh)
{
int flag,Dy,N,m,b;
if(yh<HStartYear || yh>HEndYear)
{
flag=0;
Dy=0;
}
else
{
Dy=MonthMap[yh-HStartYear]/4096; /* Mask 1111000000000000 */
b=MonthMap[yh-HStartYear];
b=b-Dy*4096;
for(m=1;m<=mh;m++)
{
flag=b%2; /* Mask for the current month */
if(flag) Dy=30; else Dy=29;
b=(b-flag)/2;
}
}
return Dy;
}
/****************************************************************************/
/* Name: DayInYear */
/* Type: Function */
/* Purpose: Obtains the day number in the yea */
/* Arguments: */
/* Input : Hijrah date: year:yh, month:mh day:dh */
/* Output: Day number in the Year */
/****************************************************************************/
int DayinYear(int yh,int mh,int dh)
{
int flag,Dy,N,m,b,DL;
if(yh<HStartYear || yh>HEndYear)
{
flag=0;
DL=0;
}
else
{
Dy=MonthMap[yh-HStartYear]/4096; /* Mask 1111000000000000 */
b=MonthMap[yh-HStartYear];
b=b-Dy*4096;
DL=0;
for(m=1;m<=mh;m++)
{
flag=b%2; /* Mask for the current month */
if(flag) Dy=30; else Dy=29;
b=(b-flag)/2;
DL=DL+Dy;
}
DL=DL+dh;
}
return DL;
}
/****************************************************************************/
/* Name: HYearLength */
/* Type: Function */
/* Purpose: Obtains the year length */
/* Arguments: */
/* Input : Hijrah date: year:yh */
/* Output: Year Length */
/****************************************************************************/
int HYearLength(int yh)
{
int flag,Dy,N,m,b,YL;
if(yh<HStartYear || yh>HEndYear)
{
flag=0;
YL=0;
}
else
{
Dy=MonthMap[yh-HStartYear]/4096; /* Mask 1111000000000000 */
b=MonthMap[yh-HStartYear];
b=b-Dy*4096;
flag=b%2; /* Mask for the current month */
if(flag) YL=30; else YL=29;
for(m=2;m<=12;m++)
{
flag=b%2; /* Mask for the current month */
if(flag) Dy=30; else Dy=29;
b=(b-flag)/2;
YL=YL+Dy;
}
}
return YL;
}
/****************************************************************************/
/* Name: G2HA */
/* Type: Procedure */
/* Purpose: convert Gdate(year,month,day) to Hdate(year,month,day) */
/* Arguments: */
/* Input: Gregorian date: year:yg, month:mg, day:dg */
/* Output: Hijrah date: year:yh, month:mh, day:dh, day of week:dayweek */
/* and returns flag found:1 not found:0 */
/****************************************************************************/
int G2HA(int yg,int mg, int dg,int *yh,int *mh,int *dh,int *dayweek)
{
int yh1,mh1,dh1;
int yh2,mh2,dh2;
int yg1,mg1,dg1;
int yg2,mg2,dg2;
int df,dw2;
int flag;
long J;
double GJD,HJD;
GJD=GCalendarToJD(yg,mg,dg+0.5); /* find JD of Gdate */
JDToHCalendar(GJD,&yh1,&mh1,&dh1); /* estimate the Hdate that correspond to the Gdate */
HJD=HCalendarToJDA(yh1,mh1,dh1); // get the exact Julian Day
df=GJD-HJD;
dh1=dh1+df;
while(dh1>30)
{
dh1=dh1-HMonthLength(yh1,mh1);
mh1++;
if(mh1>12) {yh1++;mh1=1;}
}
if(dh1==30)
{
mh2=mh1+1;
yh2=yh1;
if(mh2>12) {mh2=1;yh2++;}
BH2GA(yh2,mh2,&yg1,&mg1,&dg1,&dw2);
if(dg==dg1) {yh1=yh2;mh1=mh2;dh1=1;} /* Make sure that the month is 30days if not make adjustment */
}
J=(GCalendarToJD(yg,mg,dg)+2);
*dayweek=J%7;
*yh=yh1;
*mh=mh1;
*dh=dh1;
return flag;
}
/****************************************************************************/
/* Name: H2GA */
/* Type: Procedure */
/* Purpose: convert Hdate(year,month,day) to Gdate(year,month,day) */
/* Arguments: */
/* Input/Ouput: Hijrah date: year:yh, month:mh, day:dh */
/* Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek */
/* and returns flag found:1 not found:0 */
/* Note: The function will correct Hdate if day=30 and the month is 29 only */
/****************************************************************************/
int H2GA(int *yh,int *mh,int *dh, int *yg,int *mg, int *dg,int *dayweek)
{
int found,yh1,mh1,yg1,mg1,dg1,dw1;
/* make sure values are within the allowed values */
if(*dh>30) {*dh=1;(*mh)++;}
if(*dh<1) {*dh=1;(*mh)--;}
if(*mh>12) {*mh=1;(*yh)++;}
if(*mh<1) {*mh=12;(*yh)--;}
/*find the date of the begining of the month*/
found=BH2GA(*yh,*mh,yg,mg,dg,dayweek);
*dg=*dg+*dh-1;
GDateAjust(yg,mg,dg); /* Make sure that dates are within the correct values */
*dayweek=*dayweek+*dh-1;
*dayweek=*dayweek%7;
/*find the date of the begining of the next month*/
if(*dh==30)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -