1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
[Sorry for my english, it's not very good. I hope, this will be
understandable enough, thought.]
INTRODUCTION
The 'libkal' library provides support for converting dates between various
calendary systems (currently only julianic, gregorianic, arabic and jewish
ones) and some more related stuff.
The basic idea of this library is, that any date in any calendar system can
be converted to a single number, which express the number of days since some
fixed date in the past. I use here so-called 'julianic date'(jd), that is used
in Astronomy (not exactly).
Therefore it's easy to compute for example 'how many days are there
between x and y' - just compute the jd's of x and y, and substract them:
difference=kal_conv_gre_jd(y_day,y_month,y_year)-
kal_conv_gre_jd(x_day,x_month,x_year);
Also evaluating the day of week of given date is quite easy - just divide
the jd by 7 and the reminder is what you seek. (not exactly)
LIBRARY OVERVIEW
1. Basic conversions
--------------------
Each calendary system has two basic functions, which convert the date to and
from the jd:
long kal_conv_*_jd(int d, int m, int y);
void kal_conv_jd_*(long jd, int *d, int *m, int *y);
,where * can be one of: jul,gre,ar,jew for julianic, gregorianic, arabic
and jewish calendary system respectively.
(e.g.: "kal_conv_gre_jd(day,month,year)" computes the jd of day/month/year
according to the gregorian calendar.)
(See the test.c example.)
2. Checking if date valid
-------------------------
When converting a date into the jd, we would like to know, whether the
date is valid. This is done in the folowing function:
int kal_*_check(long *jd, int d, int m, int y);
(simillar to the previous). It returns 0 on succes and 1 when the date is
invalid.
The check is done in two steps: first checking for 'big nonsenses' such as
the month number bigger than 13 (jewish calendar has sometimes 13 months) or
lower than 1; second, we convert the date into jd, and then back into d/m/y
and check, whether the d/m/y are equal.
Thus we have here as a parameter the pointer on the jd, as we need not to
do the same job (converting d/m/y to jd) later again.
(See also the test1.c example.)
3. Computing the day of easter sunday
-------------------------------------
This functions compute the jd of the easter sunday for given year:
long kal_jul_east(int y);
respectivelly:
long kal_gre_east(int y);
(Dates of many christian feasts are evaluated from this date).
4. Days of week
---------------
A day of week can be simply obtained from jd by calling:
int kal_day_of_week(long jd);
,where 0 stands for sunday, 1==monday, 2==tuesday, etc.
Another functions give you the closest (next or previous) 'day of week':
long kal_next_dw(long jd, int dw);
long kal_prev_dw(long jd, int dw);
For exapmle: "jd1=kal_next_dw(jd,0);" will make the jd1 to be the nearest
sunday(==0) _after_ the jd, or to be equal to jd, if jd is a sunday. There
exist also two simillar functions, that differs in that the result is never
equal to the inputed jd.
long kal_next_after_dw(long jd, int dw);
long kal_prev_before_dw(long jd, int dw);
(See also the 'test-dw.c' example.)
5. Names of months
------------------
I suppose that the names of the months are language dependand, so I don't
cover them in this library. The only exeptions are the "exotic" calendars.
You can get that names by calling:
char * kal_jew_months(int m);
char * kal_ar_months(int m);
6. Some notes on the Jewish calendar
------------------------------------
Jewish calendar is probably the most complicated calendary system ever existed.
It's so-called 'luni-solar' calendar, which means, that it's 'lunar'
calendar, i.e. that the 'calendar month' equals to the 'lunar month', but
this is adjusted so, that every month remains in it's season.
In order to do that, jews have 7 times in 19 years 13 months per year.
But for historical reasons, this 'leap-month' isn't added at the end of the year, but after the sixth month. (Which was in the past the end of the year.)
This makes it ugly for computing- either would the relation between month
number and month name be not stable (it would be dependand on whether the
year is leap or not), or would the number of the month be not trully it's
number. I choose the second possibility, so that the month no. 7 may be used
in leap years only.
Therefore it might be usefull to know, whether the year is leap, or not.
You may use 'int kal_jew_leap(int y)' function, which returns 1, if the year
is leap.
(See functions 'prv' and 'nxt' in gtk-example/example.c)
7. Year adjustments
-------------------
It could happen, that we will do something with the years 'before [Christ |
creation | Hegira ]'. In such a case it's not nice to output to user something
like "Year -2", because it can be very confusing ( year "-2" is the "year 3
before" !). For that case ther are in this library two functions, which
convert to and from "user friendly" form, having beside the year number
a boolean variable "a", which tells, whether the year is "before" or not:
int kal_year_code(int y, int a); /* from 'user friendly' form */
int kal_year_decode(int y, int *a); /* to 'user friendly' form */
(See also the 'gtk-example'.)
8. Getting current date
-----------------------
The funcion kal_getdate() gets the jd of today's date. (Needs to be rewriten!)
9. More general function interface.
-----------------------------------
It can happen, that you will need general functions, to be independant
on what calendar is beeing used. I Implemented here a simple table, where
basic routines for each calendar are stored and general functions, that can
call them. These functions are:
long kal_conv_xxx_jd(int d, int m, int y, int sys);
void kal_conv_jd_xxx(long &jd, int d, int y, int sys);
long kal_xxx_east(int y, int sys);
char * kal_xxx_months(int m, int sys);
,where sys can be one of the following: KAL_JUL, KAL_GRE, KAL_AR, KAL_JEW for
the julianic, gregorianic .... calendary system.
Note, that not all of the functions must be defined for all calendars.
(It is, for example, nonsense to compute the date od Easter Sunday for jewish,
or arabic calendar - but not for gregorian or julian ones - and for example
also not for the coptic one [which is not implemented yet;-)].)
In order to test if the function is available, call:
int kal_proc_valid(int proc, int sys);
,where 'proc' can be: KAL_PROCS_XXX_JD, KAL_PROCS_JD_XXX, KAL_PROCS_MONTHS or
KAL_PROCS_EAST. It results 0 on succes, 1 if the function doesn't exist.
You can also get the abbreviation for the calendar by calling:
char * kal_proc_get_name(int sys);
(For more see the 'gtk-example'.)
TESTING
The library is not very well tested, althought something was done:
- I checked all the calendars with the 'check' utility for things that
can be checked without having to have any chronological tables or calendars.
(For more see check.c)
- I have (randomly) checked the library against some known-to-work programs.
(for example the 'xjewcal').
- I have (randomly) checked the 'jul', 'gre' and 'jew' calendars agains
chronological tables and calendars I've found.
I've been using this routines for about 2 years (since 1996), so there
is a chance, that they might be correct. Expecially the dates between 1990-
2000 should be o.k.
Please, if You could test this library in any way, do so. Thanks.
ADDING NEW CALENDARS
If someone has any other calendar to be added to this library, should:
* Add the kal_conv_*_jd and kal_conv_jd_* functions to the
(possible) kal_main.c .
* Add other functions there.
* Update the kal_proc.h.
* Test the library with 'check'.
* Test it more using chronological tables etc.
AUTHOR
Petr Tomasek <tomasek@etf.cuni.cz> July 1998
|