| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120 |
- // CalendricalCalculations.cs
- //
- // (C) Ulrich Kunitz 2002
- //
- namespace System.Globalization {
- using System.Collections;
- /// <summary>A class that provides mathematical functions.</summary>
- /// <remarks>
- /// <para>
- /// We are breaking the .Net
- /// naming conventions to be compatible to the "Calendrical Calculations"
- /// bool.
- /// </para>
- /// </remarks>
- internal class CCMath {
- /// <summary>
- /// A static method which rounds a double value.
- /// </summary>
- /// <param name="x">The double value to round.</param>
- /// <returns>The rounded double.</returns>
- public static double round(double x) {
- return System.Math.Floor(x+0.5);
- }
- /// <summary>
- /// A static method that computes the remainder of the division
- /// of two doubles.
- /// </summary>
- /// <param name="x">The double value which is divided.</param>
- /// <param name="y">The divisor.</param>
- /// <returns>The remainder as double value.</returns>
- public static double mod(double x, double y) {
- return x - y * System.Math.Floor(x/y);
- }
- /// <summary>
- /// The static method divides two integers.
- /// </summary>
- /// <param name="x">The integer x value.</param>
- /// <param name="y">The integer y value.</param>
- /// <returns>The qotient of x and y defined by floor(x/y).
- /// </returns>
- /// <remarks>
- /// Please notify that the function is not compatible to the standard
- /// integer divide operation /.
- /// </remarks>
- public static int div(int x, int y) {
- return (int)System.Math.Floor((double)x/(double)y);
- }
- /// <summary>
- /// The static method computes the remainder of two integers.
- /// </summary>
- /// <param name="x">The integer value which will be divided.</param>
- /// <param name="y">The divisor integer value.</param>
- /// <returns> The remainder as integer value.</returns>
- /// <remarks>
- /// Please notify that the method is not compatible to the C#
- /// remainder operation %.
- /// </remarks>
- public static int mod(int x, int y) {
- return x - y * div(x, y);
- }
- /// <summary>
- /// A static method that combines integer division and remainder
- /// computation.
- /// </summary>
- /// <param name="remainder">Remainder integer output value.
- /// </param>
- /// <param name="x">Integer to be divided.</param>
- /// <param name="y">Divisor integer value.</param>
- /// <returns>The quotient as integer.</returns>
- /// <seealso cref="M:div"/>
- /// <seealso cref="M:mod"/>
- public static int div_mod(out int remainder, int x, int y) {
- int d = div(x, y);
- remainder = x - y * d;
- return d;
- }
- /// <summary>
- /// A static method returning the sign of the argument.
- /// </summary>
- /// <param name="x">The double argument.</param>
- /// <returns>An integer value: -1 for a negative argument;
- /// 0 for a zero argument, and 1 for a positive argument.
- /// </returns>
- public static int signum(double x) {
- if (x < 0.0)
- return -1;
- if (x == 0.0)
- return 0;
- return 1;
- }
- /// <summary>
- /// A static method returning the sign of the integer
- /// argument.
- /// </summary>
- /// <param name="x">The integer argument.</param>
- /// <returns>An integer value: -1 for a negative argument;
- /// 0 for a zero argument, and 1 for a positive argument.
- /// </returns>
- public static int signum(int x) {
- if (x < 0)
- return -1;
- if (x == 0)
- return 0;
- return 1;
- }
- /// <summary>
- /// An adjusted remainder function as defined in "Calendrical
- /// Calculations".
- /// </summary>
- /// <param name="x">The double x argument.</param>
- /// <param name="y">The double y argument, the divisor.</param>
- /// <returns>A double value representing remainder; but instead 0.0
- /// the divisor y is returned.
- /// </returns>
- public static double amod(double x, double y) {
- double d = mod(x, y);
- return (d == 0.0) ? y : d;
- }
- /// <summary>
- /// The adjusted remainder functions for integers as defined in
- /// "Calendrical Calculations".
- /// </summary>
- /// <param name="x">The integer argument to be divided.</param>
- /// <param name="y">The integer divisor argument.</param>
- /// <returns>The remainder as an integer; however instead 0
- /// is the divisor y returned.
- /// </returns>
- public static int amod(int x, int y) {
- int i = mod(x, y);
- return (i == 0) ? y : i;
- }
- }
- /// <summary>The class implements methods to handle the fixed date value from
- /// the "Calendrical Calculations" books.
- /// </summary>
- /// <remarks>
- /// <para>
- /// For implementing the Calendar classes I used the algorithms from the
- /// book "Calendrical Calculations" by Nachum Dershowitz and Edward M.
- /// Rheingold, second reprint 1998. Trying to prevent the introduction of new
- /// bugs, I implemented their algorithms in the
- /// <see cref="N:CalendricalCalculations"/>
- /// namespace and wrapped it in the calendar classes.
- /// </para>
- /// <para>
- /// The fixed day number is also known as R.D. - rata die.
- /// Midnight at the onset of Monday,
- /// January 1, year 1 (Gregorian) is R.D. 1.
- /// </para>
- /// <para>Here are all my references:</para>
- /// <list type="table">
- /// <item><description>
- /// [1] Nachum Dershowitz and Edward M. Rheingold: "Calendrical Calculations";
- /// Cambridge University Press; second reprint 1998.
- /// </description></item>
- /// <item><description>
- /// [2] P. Kenneth Seidelmann (ed.): "Explanatory Supplement to the Astronomical
- /// Almanac"; University Science Books, Sausalito; 1992
- /// </description></item>
- /// <item><description>
- /// [3] F. Richard Stephenson: "Historical Eclipses and Earth Rotation";
- /// Cambridge University Press; 1997
- /// </description></item>
- /// </list>
- /// </remarks>
- internal class CCFixed {
- /// <summary>The method computes the
- /// <see cref="T:System.DateTime"/>
- /// from a fixed day number.
- /// </summary>
- /// <param name="date">A integer representing the fixed day number.
- /// </param>
- /// <returns>The <see cref="T:System.DateTime"/> representing
- /// the date.
- /// </returns>
- public static System.DateTime ToDateTime(int date) {
- long ticks = (date - 1) * System.TimeSpan.TicksPerDay;
- return new System.DateTime(ticks);
- }
- /// <summary>The method computes the
- /// <see cref="T:System.DateTime"/>
- /// from a fixed day number and time arguments.
- /// </summary>
- /// <param name="date">An integer representing the fixed day number.
- /// </param>
- /// <param name="hour">An integer argument specifying the hour.
- /// </param>
- /// <param name="minute">An integer argument specifying the minute.
- /// </param>
- /// <param name="second">An integer argument giving the second.
- /// </param>
- /// <param name="milliseconds">An double argument specifying
- /// the milliseconds. Notice that
- /// <see cref="T:System.DateTime"/> has 100 nanosecond resolution.
- /// </param>
- /// <returns>The <see cref="T:System.DateTime"/> representing
- /// the date.
- /// </returns>
- public static System.DateTime ToDateTime(int date,
- int hour, int minute, int second, double milliseconds)
- {
- System.DateTime time = ToDateTime(date);
- time = time.AddHours(hour);
- time = time.AddMinutes(minute);
- time = time.AddSeconds(second);
- return time.AddMilliseconds(milliseconds);
- }
- /// <summary>
- /// A static method computing the fixed day number from a
- /// <see cref="T:System.DateTime"/> value.
- /// </summary>
- /// <param name="time">A
- /// <see cref="T:System.DateTime"/> value representing the date.
- /// </param>
- /// <returns>The fixed day number as integer representing the date.
- /// </returns>
- public static int FromDateTime(System.DateTime time) {
- return 1 + (int)(time.Ticks / System.TimeSpan.TicksPerDay);
- }
- /// <summary>
- /// The static method computes the <see cref="T:DayOfWeek"/>.
- /// </summary>
- /// <param name="date">An integer representing the fixed day number.
- /// </param>
- /// <returns>The day of week.</returns>
- public static DayOfWeek day_of_week(int date) {
- return (DayOfWeek)CCMath.mod(date, 7);
- }
- /// <summary>
- /// The static method computes the date of a day of week on or before
- /// a particular date.
- /// </summary>
- /// <param name="date">An integer representing the date as
- /// fixed day number.
- /// </param>
- /// <param name="k">An integer representing the day of the week,
- /// starting with 0 for sunday.
- /// </param>
- /// <returns>The fixed day number of the day of week specified by k
- /// on or before the given date.
- /// </returns>
- public static int kday_on_or_before(int date, int k) {
- return date - (int)day_of_week(date-k);
- }
- /// <summary>
- /// The static method computes the date of a day of week on or after
- /// a particular date.
- /// </summary>
- /// <param name="date">An integer representing the date as
- /// fixed day number.
- /// </param>
- /// <param name="k">An integer representing the day of the week,
- /// starting with 0 for sunday.
- /// </param>
- /// <returns>The fixed day number of the day of week specified by k
- /// on or after the given date.
- /// </returns>
- public static int kday_on_or_after(int date, int k) {
- return kday_on_or_before(date+6, k);
- }
- /// <summary>
- /// The static method computes the date of a day of week that is
- /// nearest to a particular date.
- /// </summary>
- /// <param name="date">An integer representing the date as
- /// fixed day number.
- /// </param>
- /// <param name="k">An integer representing the day of the week,
- /// starting with 0 for sunday.
- /// </param>
- /// <returns>The fixed day number of the day of week neares to the
- /// given date.
- /// </returns>
- public static int kd_nearest(int date, int k) {
- return kday_on_or_before(date+3, k);
- }
- /// <summary>
- /// The static method computes the date of a day of week after
- /// a particular date.
- /// </summary>
- /// <param name="date">An integer representing the date as
- /// fixed day number.
- /// </param>
- /// <param name="k">An integer representing the day of the week,
- /// starting with 0 for sunday.
- /// </param>
- /// <returns>The fixed day number of the day of week specified by k
- /// after the given date.
- /// </returns>
- public static int kday_after(int date, int k) {
- return kday_on_or_before(date+7, k);
- }
- /// <summary>
- /// The static method computes the date of a day of week before
- /// a particular date.
- /// </summary>
- /// <param name="date">An integer representing the date as
- /// fixed day number.
- /// </param>
- /// <param name="k">An integer representing the day of the week,
- /// starting with 0 for sunday.
- /// </param>
- /// <returns>The fixed day number of the day of week specified by k
- /// before the given date.
- /// </returns>
- public static int kday_before(int date, int k) {
- return kday_on_or_before(date-1, k);
- }
- } // class CCFixed
- /// <summary>
- /// A class encapsulating the functions of the Gregorian calendar as static
- /// methods.
- /// </summary>
- /// <remarks>
- /// <para>
- /// This class is not compatible to
- /// <see cref="T:System.Globalization.GregorianCalendar"/>.
- /// </para>
- /// <para>
- /// The fixed day number is also known as R.D. - rata die.
- /// Midnight at the onset of Monday,
- /// January 1, year 1 (Gregorian) is R.D. 1.
- /// </para>
- /// <seealso cref="T:CCFixed"/>
- /// </remarks>
- internal class CCGregorianCalendar {
- /// <summary>An integer defining the epoch of the Gregorian calendar
- /// as fixed day number.</summary>
- /// <remarks>The epoch is January 3, 1 C.E. (Julian).</remarks>
- const int epoch = 1;
- /// <summary>The enumeration defines the months of the Gregorian
- /// calendar.
- /// </summary>
- public enum Month {
- /// <summary>
- /// January.
- /// </summary>
- january = 1,
- /// <summary>
- /// February.
- /// </summary>
- february,
- /// <summary>
- /// March.
- /// </summary>
- march,
- /// <summary>
- /// April.
- /// </summary>
- april,
- /// <summary>
- /// May.
- /// </summary>
- may,
- /// <summary>
- /// June.
- /// </summary>
- june,
- /// <summary>
- /// July.
- /// </summary>
- july,
- /// <summary>
- /// August.
- /// </summary>
- august,
- /// <summary>
- /// September.
- /// </summary>
- september,
- /// <summary>
- /// October.
- /// </summary>
- october,
- /// <summary>
- /// November.
- /// </summary>
- november,
- /// <summary>
- /// December.
- /// </summary>
- december
- };
- /// <summary>
- /// The method tells whether the year is a leap year.
- /// </summary>
- /// <param name="year">An integer representing the Gregorian year.
- /// </param>
- /// <returns>A boolean which is true if <paramref name="year"/> is
- /// a leap year.
- /// </returns>
- public static bool is_leap_year(int year) {
- if (CCMath.mod(year, 4) != 0)
- return false;
- switch (CCMath.mod(year, 400)) {
- case 100:
- return false;
- case 200:
- return false;
- case 300:
- return false;
- }
- return true;
- }
- /// <summary>
- /// The method returns the fixed day number of the given Gregorian
- /// date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Gregorian year.
- /// </param>
- /// <param name="year">An integer representing the Gregorian year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value representing the fixed day number.
- /// </returns>
- public static int fixed_from_dmy(int day, int month, int year) {
- int k = epoch - 1;
- k += 365 * (year-1);
- k += CCMath.div(year-1, 4);
- k -= CCMath.div(year-1, 100);
- k += CCMath.div(year-1, 400);
- k += CCMath.div(367*month-362, 12);
- if (month > 2) {
- k += is_leap_year(year) ? -1 : -2;
- }
- k += day;
- return k;
- }
- /// <summary>
- /// The method computes the Gregorian year from a fixed day number.
- /// </summary>
- /// <param name="date">The fixed day number.
- /// </param>
- /// <returns>An integer value giving the Gregorian year of the date.
- /// </returns>
- public static int year_from_fixed(int date) {
- int d = date - epoch;
- int n_400 = CCMath.div_mod(out d, d, 146097);
- int n_100 = CCMath.div_mod(out d, d, 36524);
- int n_4 = CCMath.div_mod(out d, d, 1461);
- int n_1 = CCMath.div(d, 365);
- int year = 400*n_400 + 100*n_100 + 4*n_4 + n_1;
- return (n_100 == 4 || n_1 == 4) ? year : year + 1;
- }
- /// <summary>
- /// The method computes the Gregorian year and month from a fixed day
- /// number.
- /// </summary>
- /// <param name="month">The output value giving the Gregorian month.
- /// </param>
- /// <param name="year">The output value giving the Gregorian year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void my_from_fixed(out int month, out int year,
- int date)
- {
- year = year_from_fixed(date);
- int prior_days = date - fixed_from_dmy(1, (int)Month.january,
- year);
-
- int correction;
- if (date < fixed_from_dmy(1, (int)Month.march, year)) {
- correction = 0;
- } else if (is_leap_year(year)) {
- correction = 1;
- } else {
- correction = 2;
- }
- month = CCMath.div(12 * (prior_days + correction) + 373, 367);
- }
- /// <summary>
- /// The method computes the Gregorian year, month, and day from a
- /// fixed day number.
- /// </summary>
- /// <param name="day">The output value returning the day of the
- /// month.
- /// </param>
- /// <param name="month">The output value giving the Gregorian month.
- /// </param>
- /// <param name="year">The output value giving the Gregorian year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void dmy_from_fixed(out int day, out int month,
- out int year,
- int date)
- {
- my_from_fixed(out month, out year, date);
- day = date - fixed_from_dmy(1, month, year) + 1;
- }
- /// <summary>A method computing the Gregorian month from a fixed
- /// day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the Gregorian month.
- /// </returns>
- public static int month_from_fixed(int date) {
- int month, year;
- my_from_fixed(out month, out year, date);
- return month;
- }
- /// <summary>
- /// A method computing the day of the month from a fixed day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the day of the month.
- /// </returns>
- public static int day_from_fixed(int date) {
- int day, month, year;
- dmy_from_fixed(out day, out month, out year, date);
- return day;
- }
- /// <summary>
- /// The method computes the difference between two Gregorian dates.
- /// </summary>
- /// <param name="dayA">The integer parameter gives the day of month
- /// of the first date.
- /// </param>
- /// <param name="monthA">The integer parameter gives the Gregorian
- /// month of the first date.
- /// </param>
- /// <param name="yearA">The integer parameter gives the Gregorian
- /// year of the first date.
- /// </param>
- /// <param name="dayB">The integer parameter gives the day of month
- /// of the second date.
- /// </param>
- /// <param name="monthB">The integer parameter gives the Gregorian
- /// month of the second date.
- /// </param>
- /// <param name="yearB">The integer parameter gives the Gregorian
- /// year of the second date.
- /// </param>
- /// <returns>An integer giving the difference of days from the first
- /// the second date.
- /// </returns>
- public static int date_difference(int dayA, int monthA, int yearA,
- int dayB, int monthB, int yearB)
- {
- return fixed_from_dmy(dayB, monthB, yearB) -
- fixed_from_dmy(dayA, monthA, yearA);
- }
- /// <summary>
- /// The method computes the number of the day in the year from
- /// a Gregorian date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Gregorian year.
- /// </param>
- /// <param name="year">An integer representing the Gregorian year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value giving the number of the day in the
- /// Gregorian year, counting from 1.
- /// </returns>
- public static int day_number(int day, int month, int year) {
- return date_difference(31, (int)Month.december, year-1,
- day, month, year);
- }
- /// <summary>
- /// The method computes the days remaining in the given Gregorian
- /// year from a Gregorian date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Gregorian year.
- /// </param>
- /// <param name="year">An integer representing the Gregorian year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value giving the number of days remaining in
- /// the Gregorian year.
- /// </returns>
- public static int days_remaining(int day, int month, int year) {
- return date_difference(day, month, year,
- 31, (int)Month.december, year);
- }
- // Helper functions for the Gregorian calendars.
- /// <summary>
- /// Adds months to the given date.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> to which to add
- /// months.
- /// </param>
- /// <param name="months">The number of months to add.</param>
- /// <returns>A new <see cref="T:System.DateTime"/> value, that
- /// results from adding <paramref name="months"/> to the specified
- /// DateTime.</returns>
- public static System.DateTime AddMonths(System.DateTime time,
- int months)
- {
- int rd = CCFixed.FromDateTime(time);
- int day, month, year;
- dmy_from_fixed(out day, out month, out year, rd);
- month += months;
- rd = fixed_from_dmy(day, month, year);
- System.DateTime t = CCFixed.ToDateTime(rd);
- return t.Add(time.TimeOfDay);
- }
- /// <summary>
- /// Adds years to the given date.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> to which to add
- /// months.
- /// </param>
- /// <param name="years">The number of years to add.</param>
- /// <returns>A new <see cref="T:System.DateTime"/> value, that
- /// results from adding <paramref name="years"/> to the specified
- /// DateTime.</returns>
- public static System.DateTime AddYears(System.DateTime time,
- int years)
- {
- int rd = CCFixed.FromDateTime(time);
- int day, month, year;
- dmy_from_fixed(out day, out month, out year, rd);
- year += years;
- rd = fixed_from_dmy(day, month, year);
- System.DateTime t = CCFixed.ToDateTime(rd);
- return t.Add(time.TimeOfDay);
- }
- /// <summary>
- /// Gets the of the month from <paramref name="time"/>.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> that specifies a
- /// date.
- /// </param>
- /// <returns>An integer giving the day of months, starting with 1.
- /// </returns>
- public static int GetDayOfMonth(System.DateTime time) {
- return day_from_fixed(CCFixed.FromDateTime(time));
- }
- /// <summary>
- /// The method gives the number of the day in the year.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> that specifies a
- /// date.
- /// </param>
- /// <returns>An integer representing the day of the year,
- /// starting with 1.</returns>
- public static int GetDayOfYear(System.DateTime time) {
- int rd = CCFixed.FromDateTime(time);
- int year = year_from_fixed(rd);
- int rd1_1 = fixed_from_dmy(1, 1, year);
- return rd - rd1_1 + 1;
- }
- /// <summary>
- /// A method that gives the number of days of the specified
- /// month of the <paramref name="year"/>.
- /// </summary>
- /// <param name="year">An integer that gives the year in the current
- /// era.</param>
- /// <param name="month">An integer that gives the month, starting
- /// with 1.</param>
- /// <returns>An integer that gives the number of days of the
- /// specified month.</returns>
- public static int GetDaysInMonth(int year, int month) {
- int rd1 = fixed_from_dmy(1, month, year);
- int rd2 = fixed_from_dmy(1, month+1, year);
- return rd2 - rd1;
- }
- /// <summary>
- /// The method gives the number of days in the specified year.
- /// </summary>
- /// <param name="year">An integer that gives the year.
- /// </param>
- /// <returns>An integer that gives the number of days of the
- /// specified year.</returns>
- public static int GetDaysInYear(int year) {
- int rd1 = fixed_from_dmy(1, 1, year);
- int rd2 = fixed_from_dmy(1, 1, year+1);
- return rd2 - rd1;
- }
- /// <summary>
- /// The method gives the number of the month of the specified
- /// date.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> that specifies a
- /// date.
- /// </param>
- /// <returns>An integer representing the month,
- /// starting with 1.</returns>
- public static int GetMonth(System.DateTime time) {
- return month_from_fixed(CCFixed.FromDateTime(time));
- }
- /// <summary>
- /// The method gives the number of the year of the specified
- /// date.
- /// </summary>
- /// <param name="time">The
- /// <see cref="T:System.DateTime"/> that specifies a
- /// date.
- /// </param>
- /// <returns>An integer representing the year.
- /// </returns>
- public static int GetYear(System.DateTime time) {
- return year_from_fixed(CCFixed.FromDateTime(time));
- }
- /// <summary>
- /// A virtual method that tells whether the given day
- /// is a leap day.
- /// </summary>
- /// <param name="year">An integer that specifies the year.
- /// </param>
- /// <param name="month">An integer that specifies the month.
- /// </param>
- /// <param name="day">An integer that specifies the day.
- /// </param>
- /// <returns>A boolean that tells whether the given day is a leap
- /// day.
- /// </returns>
- public static bool IsLeapDay(int year, int month, int day) {
- return is_leap_year(year) && month == 2 && day == 29;
- }
- /// <summary>
- /// A method that creates the
- /// <see cref="T:System.DateTime"/> from the parameters.
- /// </summary>
- /// <param name="year">An integer that gives the year
- /// </param>
- /// <param name="month">An integer that specifies the month.
- /// </param>
- /// <param name="day">An integer that specifies the day.
- /// </param>
- /// <param name="hour">An integer that specifies the hour.
- /// </param>
- /// <param name="minute">An integer that specifies the minute.
- /// </param>
- /// <param name="second">An integer that gives the second.
- /// </param>
- /// <param name="milliseconds">An integer that gives the
- /// milliseconds.
- /// </param>
- /// <returns>A
- /// <see cref="T:system.DateTime"/> representig the date and time.
- /// </returns>
- public static System.DateTime ToDateTime(int year, int month, int day,
- int hour, int minute, int second, int milliseconds)
- {
- return CCFixed.ToDateTime(fixed_from_dmy(day, month, year),
- hour, minute, second, milliseconds);
- }
- } // class CCGregorianCalendar
- /// <summary>
- /// A class encapsulating the functions of the Julian calendar as static
- /// methods.
- /// </summary>
- /// <remarks>
- /// <para>The algorithms don't support a year 0. Years before Common Era
- /// (B.C.E. or B.C.) are negative and years of Common Era (C.E. or A.D.)
- /// are positive.
- /// </para>
- /// <para>
- /// This class is not compatible to
- /// <see cref="T:System.Globalization.JulianCalendar"/>.
- /// </para>
- /// <seealso cref="T:CCFixed"/>
- /// </remarks>
- internal class CCJulianCalendar {
- /// <summary>An integer defining the epoch of the Julian calendar
- /// as fixed day number.</summary>
- /// <remarks>The epoch is December 30, 0 (Gregorian).</remarks>
- const int epoch = -1; // 30. 12. 0 Gregorian
- /// <summary>The enumeration defines the months of the Julian
- /// calendar.
- /// </summary>
- public enum Month {
- /// <summary>
- /// January.
- /// </summary>
- january = 1,
- /// <summary>
- /// February.
- /// </summary>
- february,
- /// <summary>
- /// March.
- /// </summary>
- march,
- /// <summary>
- /// April.
- /// </summary>
- april,
- /// <summary>
- /// May.
- /// </summary>
- may,
- /// <summary>
- /// June.
- /// </summary>
- june,
- /// <summary>
- /// July.
- /// </summary>
- july,
- /// <summary>
- /// August.
- /// </summary>
- august,
- /// <summary>
- /// September.
- /// </summary>
- september,
- /// <summary>
- /// October.
- /// </summary>
- october,
- /// <summary>
- /// November.
- /// </summary>
- november,
- /// <summary>
- /// December.
- /// </summary>
- december
- };
- /// <summary>
- /// The method tells whether the year is a leap year.
- /// </summary>
- /// <param name="year">An integer representing the Julian year.
- /// </param>
- /// <returns>A boolean which is true if <paramref name="year"/> is
- /// a leap year.
- /// </returns>
- public static bool is_leap_year(int year) {
- return CCMath.mod(year, 4) == (year > 0 ? 0 : 3);
- }
- /// <summary>
- /// The method returns the fixed day number of the given Julian
- /// date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Julian year.
- /// </param>
- /// <param name="year">An integer representing the Julian year.
- /// Positive and Negative values are allowed.
- /// </param>
- /// <returns>An integer value representing the fixed day number.
- /// </returns>
- public static int fixed_from_dmy(int day, int month, int year) {
- int y = year < 0 ? year+1 : year;
- int k = epoch - 1;
- k += 365 * (y-1);
- k += CCMath.div(y-1, 4);
- k += CCMath.div(367*month-362, 12);
- if (month > 2) {
- k += is_leap_year(year) ? -1 : -2;
- }
- k += day;
- return k;
- }
- /// <summary>
- /// The method computes the Julian year from a fixed day number.
- /// </summary>
- /// <param name="date">The fixed day number.
- /// </param>
- /// <returns>An integer value giving the Julian year of the date.
- /// </returns>
- public static int year_from_fixed(int date) {
- int approx = CCMath.div(4*(date-epoch)+1464, 1461);
- return approx <= 0 ? approx - 1 : approx;
- }
- /// <summary>
- /// The method computes the Julian year and month from a fixed day
- /// number.
- /// </summary>
- /// <param name="month">The output value giving the Julian month.
- /// </param>
- /// <param name="year">The output value giving the Julian year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void my_from_fixed(out int month, out int year, int date)
- {
- year = year_from_fixed(date);
- int prior_days = date - fixed_from_dmy(1, (int)Month.january,
- year);
-
- int correction;
- if (date < fixed_from_dmy(1, (int)Month.march, year)) {
- correction = 0;
- } else if (is_leap_year(year)) {
- correction = 1;
- } else {
- correction = 2;
- }
- month = CCMath.div(12 * (prior_days + correction) + 373, 367);
- }
-
- /// <summary>
- /// The method computes the Julian year, month, and day from a
- /// fixed day number.
- /// </summary>
- /// <param name="day">The output value returning the day of the
- /// month.
- /// </param>
- /// <param name="month">The output value giving the Julian month.
- /// </param>
- /// <param name="year">The output value giving the Julian year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void dmy_from_fixed(out int day, out int month,
- out int year, int date)
- {
- my_from_fixed(out month, out year, date);
- day = date - fixed_from_dmy(1, month, year) + 1;
- }
- /// <summary>A method computing the Julian month from a fixed
- /// day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the Julian month.
- /// </returns>
- public static int month_from_fixed(int date) {
- int month, year;
- my_from_fixed(out month, out year, date);
- return month;
- }
- /// <summary>
- /// A method computing the day of the month from a fixed day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the day of the month.
- /// </returns>
- public static int day_from_fixed(int date) {
- int day;
- int month;
- int year;
- dmy_from_fixed(out day, out month, out year, date);
- return day;
- }
- /// <summary>
- /// The method computes the difference between two Julian dates.
- /// </summary>
- /// <param name="dayA">The integer parameter gives the day of month
- /// of the first date.
- /// </param>
- /// <param name="monthA">The integer parameter gives the Julian
- /// month of the first date.
- /// </param>
- /// <param name="yearA">The integer parameter gives the Julian
- /// year of the first date.
- /// </param>
- /// <param name="dayB">The integer parameter gives the day of month
- /// of the second date.
- /// </param>
- /// <param name="monthB">The integer parameter gives the Julian
- /// month of the second date.
- /// </param>
- /// <param name="yearB">The integer parameter gives the Julian
- /// year of the second date.
- /// </param>
- /// <returns>An integer giving the difference of days from the first
- /// the second date.
- /// </returns>
- public static int date_difference(int dayA, int monthA, int yearA,
- int dayB, int monthB, int yearB)
- {
- return fixed_from_dmy(dayB, monthB, yearB) -
- fixed_from_dmy(dayA, monthA, yearA);
- }
- /// <summary>
- /// The method computes the number of the day in the year from
- /// a Julian date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Julian year.
- /// </param>
- /// <param name="year">An integer representing the Julian year.
- /// Negative values are allowed also.
- /// </param>
- /// <returns>An integer value giving the number of the day in the
- /// Julian year, counting from 1.
- /// </returns>
- public static int day_number(int day, int month, int year) {
- return date_difference(31, (int)Month.december, year-1,
- day, month, year);
- }
- /// <summary>
- /// The method computes the days remaining in the given Julian
- /// year from a Julian date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Julian year.
- /// </param>
- /// <param name="year">An integer representing the Julian year.
- /// Negative values are allowed also.
- /// </param>
- /// <returns>An integer value giving the number of days remaining in
- /// the Julian year.
- /// </returns>
- public static int days_remaining(int day, int month, int year) {
- return date_difference(day, month, year,
- 31, (int)Month.december, year);
- }
- } // class CCJulianCalendar
- /// <summary>
- /// A class encapsulating the functions of the Hebrew calendar as static
- /// methods.
- /// </summary>
- /// <remarks>
- /// <para>
- /// This class is not compatible to
- /// <see cref="T:System.Globalization.HebrewCalendar"/>.
- /// </para>
- /// <seealso cref="T:CCFixed"/>
- /// </remarks>
- internal class CCHebrewCalendar {
- /// <summary>An integer defining the epoch of the Hebrew calendar
- /// as fixed day number.</summary>
- /// <remarks>The epoch is October 10, 3761 B.C.E. (Julian).</remarks>
- const int epoch = -1373427;
- /// <summary>The enumeration defines the months of the Gregorian
- /// calendar.
- /// </summary>
- /// <remarks>
- /// The enumaration differs from .NET which defines Tishri as month 1.
- /// </remarks>
- public enum Month {
- /// <summary>
- /// Nisan.
- /// </summary>
- nisan = 1,
- /// <summary>
- /// Iyyar.
- /// </summary>
- iyyar,
- /// <summary>
- /// Sivan.
- /// </summary>
- sivan,
- /// <summary>
- /// Tammuz.
- /// </summary>
- tammuz,
- /// <summary>
- /// Av.
- /// </summary>
- av,
- /// <summary>
- /// Elul.
- /// </summary>
- elul,
- /// <summary>
- /// Tishri.
- /// </summary>
- tishri,
- /// <summary>
- /// Heshvan.
- /// </summary>
- heshvan,
- /// <summary>
- /// Kislev.
- /// </summary>
- kislev,
- /// <summary>
- /// Teveth.
- /// </summary>
- teveth,
- /// <summary>
- /// Shevat.
- /// </summary>
- shevat,
- /// <summary>
- /// Adar.
- /// </summary>
- adar,
- /// <summary>
- /// Adar I. Only in years with Adar II.
- /// </summary>
- adar_I = 12,
- /// <summary>
- /// Adar II. Only in years wirh Adar I.
- /// </summary>
- adar_II = 13,
- };
- /// <summary>
- /// The method tells whether the year is a leap year.
- /// </summary>
- /// <param name="year">An integer representing the Hebrew year.
- /// </param>
- /// <returns>A boolean which is true if <paramref name="year"/> is
- /// a leap year.
- /// </returns>
- public static bool is_leap_year(int year) {
- return CCMath.mod(7*year+1, 19) < 7;
- }
- /// <summary>
- /// The Method gives the number of the last month in a year, which
- /// is equal with the number of month in a Hebrew year.
- /// </summary>
- /// <param name="year">An integer representing the Hebrew year.
- /// </param>
- /// <returns>An integer giving the number of the last month of the
- /// Hebrew year, which is the same as the numbers of month in the
- /// year.
- /// </returns>
- public static int last_month_of_year(int year) {
- return is_leap_year(year) ? 13 : 12;
- }
-
- /// <summary>The method is a helper function.</summary>
- /// <param name="year">An integer specifying the Hebrew year.
- /// </param>
- /// <returns>An integer representing the number of elapsed days
- /// until the Hebrew year.</returns>
- public static int elapsed_days(int year) {
- int months_elapsed = CCMath.div(235*year-234, 19);
- int r;
- int d = CCMath.div_mod(out r, months_elapsed, 1080);
- int parts_elapsed = 204 + 793 * r;
- int hours_elapsed = 11 + 12 * months_elapsed +
- 793 * d + CCMath.div(parts_elapsed, 1080);
- int day = 29*months_elapsed + CCMath.div(hours_elapsed, 24);
- if (CCMath.mod(3*(day+1), 7) < 3) {
- day += 1;
- }
- return day;
- }
- /// <summary>A method computing the delay of new year for the given
- /// Hebrew year.
- /// </summary>
- /// <param name="year">An integer that gives the Hebrew year.
- /// </param>
- /// <returns>The new year delay in days of the given Hebrew year.
- /// </returns>
- public static int new_year_delay(int year) {
- int ny1 = elapsed_days(year);
- int ny2 = elapsed_days(year+1);
- if (ny2 - ny1 == 356) {
- return 2;
- }
- int ny0 = elapsed_days(year-1);
- if (ny1 - ny0 == 382) {
- return 1;
- }
- return 0;
- }
- /// <summary>
- /// The method computes the last day of month (nummer of days in a
- /// month) of the given Hebrew year.
- /// </summary>
- /// <param name="month">The Hebrew month, allowed value between
- /// One and Thirteen.
- /// </param>
- /// <param name="year">An integer that gives the Hebrew year.
- /// </param>
- /// <returns>The number of the last day of the month of the given
- /// Hebrew year, which gives automatically the number of days in the
- /// month.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRange.Exception">
- /// The exception is thrown if month not between One and Thirteen.
- /// </exception>
- public static int last_day_of_month(int month, int year) {
- if (month < 1 || month > 13)
- throw new System.ArgumentOutOfRangeException("month",
- "Month should be between One and Thirteen.");
- switch (month) {
- case 2: return 29;
- case 4: return 29;
- case 6: return 29;
- case 8:
- if (!long_heshvan(year))
- return 29;
- break;
- case 9:
- if (short_kislev(year))
- return 29;
- break;
- case 10: return 29;
- case 12:
- if (!is_leap_year(year))
- return 29;
- break;
- case 13: return 29;
- }
- return 30;
- }
-
- /// <summary>
- /// The functions checks whether the month Heshvan is a long one
- /// in the given Hebrew year.
- /// </summary>
- /// <param name="year">An integer that gives the Hebrew year.
- /// </param>
- /// <returns>A boolean value: true if there is a long Heshvan
- /// in the given Hebrew year; false otherwise.
- /// </returns>
- public static bool long_heshvan(int year) {
- return CCMath.mod(days_in_year(year), 10) == 5;
- }
- /// <summary>
- /// The functions checks whether the month Kislev is a short one
- /// in the given Hebrew year.
- /// </summary>
- /// <param name="year">An integer that gives the Hebrew year.
- /// </param>
- /// <returns>A boolean value: true if there is a short Kislev
- /// in the given Hebrew year; false otherwise.
- /// </returns>
- public static bool short_kislev(int year) {
- return CCMath.mod(days_in_year(year), 10) == 3;
- }
- /// <summary>
- /// The functions gives the number of days in the specified Hebrew
- /// year.
- /// </summary>
- /// <param name="year">An integer that gives the Hebrew year.
- /// </param>
- /// <returns>The days of the Hebrew year as integer.
- /// </returns>
- public static int days_in_year(int year) {
- return fixed_from_dmy(1, 7, year+1) -
- fixed_from_dmy(1, 7, year);
- }
- /// <summary>
- /// The method returns the fixed day number of the given Hebrew
- /// date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Hebrew year.
- /// </param>
- /// <param name="year">An integer representing the Hebrew year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value representing the fixed day number.
- /// </returns>
- public static int fixed_from_dmy(int day, int month, int year) {
- int m;
- int k = epoch-1;
- k += elapsed_days(year);
- k += new_year_delay(year);
- if (month < 7) {
- int l = last_month_of_year(year);
- for (m = 7; m <= l; m++) {
- k += last_day_of_month(m, year);
- }
- for (m = 1; m < month; m++) {
- k += last_day_of_month(m, year);
- }
- }
- else {
- for (m = 7; m < month; m++) {
- k += last_day_of_month(m, year);
- }
- }
-
- k += day;
- return k;
- }
- /// <summary>
- /// The method computes the Hebrew year from a fixed day number.
- /// </summary>
- /// <param name="date">The fixed day number.
- /// </param>
- /// <returns>An integer value giving the Hebrew year of the date.
- /// </returns>
- public static int year_from_fixed(int date) {
- int approx = (int)System.Math.Floor(
- ((double)(date - epoch))/(35975351.0/98496.0));
- int y;
- for (y = approx; date >= fixed_from_dmy(1, 7, y); y++) {}
- return y-1;
- }
- /// <summary>
- /// The method computes the Hebrew year and month from a fixed day
- /// number.
- /// </summary>
- /// <param name="month">The output value giving the Hebrew month.
- /// </param>
- /// <param name="year">The output value giving the Hebrew year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void my_from_fixed(out int month, out int year,
- int date)
- {
- year = year_from_fixed(date);
- int start = date < fixed_from_dmy(1, 1, year) ? 7 : 1;
- for (month = start;
- date > fixed_from_dmy(last_day_of_month(month, year),
- month, year);
- month++)
- {}
- }
- /// <summary>
- /// The method computes the Hebrew year, month, and day from a
- /// fixed day number.
- /// </summary>
- /// <param name="day">The output value returning the day of the
- /// month.
- /// </param>
- /// <param name="month">The output value giving the Hebrew month.
- /// </param>
- /// <param name="year">The output value giving the Hebrew year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void dmy_from_fixed(out int day, out int month,
- out int year, int date)
- {
- my_from_fixed(out month, out year, date);
- day = date - fixed_from_dmy(1, month, year) + 1;
- }
- /// <summary>A method computing the Hebrew month from a fixed
- /// day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the Hebrew month.
- /// </returns>
- public static int month_from_fixed(int date) {
- int month, year;
- my_from_fixed(out month, out year, date);
- return month;
- }
- /// <summary>
- /// A method computing the day of the month from a fixed day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the day of the month.
- /// </returns>
- public static int day_from_fixed(int date) {
- int day, month, year;
-
- dmy_from_fixed(out day, out month, out year, date);
- return day;
- }
- /// <summary>
- /// The method computes the difference between two Hebrew dates.
- /// </summary>
- /// <param name="dayA">The integer parameter gives the day of month
- /// of the first date.
- /// </param>
- /// <param name="monthA">The integer parameter gives the Hebrew
- /// month of the first date.
- /// </param>
- /// <param name="yearA">The integer parameter gives the Hebrew
- /// year of the first date.
- /// </param>
- /// <param name="dayB">The integer parameter gives the day of month
- /// of the second date.
- /// </param>
- /// <param name="monthB">The integer parameter gives the Hebrew
- /// month of the second date.
- /// </param>
- /// <param name="yearB">The integer parameter gives the Hebrew
- /// year of the second date.
- /// </param>
- /// <returns>An integer giving the difference of days from the first
- /// the second date.
- /// </returns>
- public static int date_difference(int dayA, int monthA, int yearA,
- int dayB, int monthB, int yearB)
- {
- return fixed_from_dmy(dayB, monthB, yearB) -
- fixed_from_dmy(dayA, monthA, yearA);
- }
- /// <summary>
- /// The method computes the number of the day in the year from
- /// a Hebrew date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Hebrew year.
- /// </param>
- /// <param name="year">An integer representing the Hebrew year.
- /// </param>
- /// <returns>An integer value giving the number of the day in the
- /// Hebrew year, counting from 1.
- /// </returns>
- public static int day_number(int day, int month, int year) {
- return date_difference(1, 7, year,
- day, month, year) + 1;
- }
- /// <summary>
- /// The method computes the days remaining in the given Hebrew
- /// year from a Hebrew date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Hebrew year.
- /// </param>
- /// <param name="year">An integer representing the Hebrew year.
- /// </param>
- /// <returns>An integer value giving the number of days remaining in
- /// the Hebrew year.
- /// </returns>
- public static int days_remaining(int day, int month, int year) {
- return date_difference(day, month, year,
- 1, 7, year+1)-1;
- }
- } // class HebrewCalendar
- /// <summary>
- /// A class encapsulating the functions of the Islamic calendar as static
- /// methods.
- /// </summary>
- /// <remarks>
- /// <para>There is no difference here in using Hijri or Islamic calendar.
- /// </para>
- /// <para>The epoch of the Islamic calendar isn't fixed, because we cannot
- /// surely say today, when the crescent of the new moon has been observed
- /// around the July 16, 622 C.E. Julian. Even today the start and end of
- /// the month Ramadan is defined by religous authorities. So the calendar
- /// can be offset by two days.
- /// </para>
- /// <para>
- /// We don't support the offset here, however we changed the epoch from
- /// "Calendrical Calculations" to value, that .Net seems to be using.
- /// </para>
- /// <para>
- /// This class is not compatible to
- /// <see cref="T:System.Globalization.HijriCalendar"/>.
- /// </para>
- /// <seealso cref="T:CCFixed"/>
- /// </remarks>
- public class CCHijriCalendar {
- /// <summary>An integer defining the epoch of the Gregorian calendar
- /// as fixed day number.</summary>
- /// <remarks>
- /// <para>
- /// The epoch is given as 16 July 622 C.E. Julian (R.D. 227015)
- /// in Calendrical Calculations, the approximate date of
- /// the emigration of
- /// Muhammed to Medina. However there is no way to determine today
- /// the observation of the crescent of the new moon in July 622 C.E.
- /// (Julian). So there is some variability in the epoch.
- /// Religous authorities determine the epoch by observing the
- /// crescent of the new moon for the month Ramadan, so there might
- /// be an offsets by two days of the epoch.
- /// </para>
- /// <para>Windows
- /// supports an AddHijriDate parameter in the registry to adapt
- /// for it. It seems that the .NET implementation of
- /// HijriCalendar uses an epoch of 227014, so we use it here. The
- /// ArgumentOutOfRangeException gives July, 18 622 as epoch,
- /// which is 227014 supporting our theory.
- /// </para>
- /// </remarks>
- const int epoch = 227014;
- /// <summary>The enumeration defines the months of the Islamic
- /// calendar.
- /// </summary>
- public enum Month {
- /// <summary>
- /// Muharram.
- /// </summary>
- muharram = 1,
- /// <summary>
- /// Safar.
- /// </summary>
- safar,
- /// <summary>
- /// Rabi I.
- /// </summary>
- rabi_I,
- /// <summary>
- /// Rabi II.
- /// </summary>
- rabi_II,
- /// <summary>
- /// Jumada I.
- /// </summary>
- jumada_I,
- /// <summary>
- /// Jumada II.
- /// </summary>
- jumada_II,
- /// <summary>
- /// Rajab.
- /// </summary>
- rajab,
- /// <summary>
- /// Shaban.
- /// </summary>
- shaban,
- /// <summary>
- /// Ramadan.
- /// </summary>
- ramadan,
- /// <summary>
- /// Shawwal.
- /// </summary>
- shawwal,
- /// <summary>
- /// Dhu Al-Quada.
- /// </summary>
- dhu_al_quada,
- /// <summary>
- /// Dhu Al-Hijja.
- /// </summary>
- dhu_al_hijja,
- };
- /// <summary>
- /// The method tells whether the year is a leap year.
- /// </summary>
- /// <param name="year">An integer representing the Islamic year.
- /// </param>
- /// <returns>A boolean which is true if <paramref name="year"/> is
- /// a leap year.
- /// </returns>
- public static bool is_leap_year(int year) {
- return CCMath.mod(14+11*year, 30) < 11;
- }
- /// <summary>
- /// The method returns the fixed day number of the given Islamic
- /// date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Islamic year.
- /// </param>
- /// <param name="year">An integer representing the Islamic year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value representing the fixed day number.
- /// </returns>
- public static int fixed_from_dmy(int day, int month, int year) {
- int k = epoch - 1;
- k += 354 * (year-1);
- k += CCMath.div(3+11*year, 30);
- k += (int)System.Math.Ceiling(29.5 * (double)(month-1));
- k += day;
- return k;
- }
- /// <summary>
- /// The method computes the Islamic year from a fixed day number.
- /// </summary>
- /// <param name="date">The fixed day number.
- /// </param>
- /// <returns>An integer value giving the Islamic year of the date.
- /// </returns>
- public static int year_from_fixed(int date) {
- return CCMath.div(30*(date-epoch)+10646, 10631);
- }
- /// <summary>
- /// The method computes the Islamic year and month from a fixed day
- /// number.
- /// </summary>
- /// <param name="month">The output value giving the Islamic month.
- /// </param>
- /// <param name="year">The output value giving the Islamic year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void my_from_fixed(out int month, out int year, int date)
- {
- year = year_from_fixed(date);
- int m = 1+(int)System.Math.Ceiling(
- ((double)(date-29-fixed_from_dmy(1,1,year)))/29.5);
- month = m < 12 ? m : 12;
- }
-
- /// <summary>
- /// The method computes the Islamic year, month, and day from a
- /// fixed day number.
- /// </summary>
- /// <param name="day">The output value returning the day of the
- /// month.
- /// </param>
- /// <param name="month">The output value giving the Islamic month.
- /// </param>
- /// <param name="year">The output value giving the Islamic year.
- /// </param>
- /// <param name="date">An integer value specifying the fixed day
- /// number.</param>
- public static void dmy_from_fixed(out int day, out int month,
- out int year, int date)
- {
- my_from_fixed(out month, out year, date);
- day = date - fixed_from_dmy(1, month, year) + 1;
- }
- /// <summary>A method computing the Islamic month from a fixed
- /// day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the Islamic month.
- /// </returns>
- public static int month_from_fixed(int date) {
- int month, year;
- my_from_fixed(out month, out year, date);
- return month;
- }
- /// <summary>
- /// A method computing the day of the month from a fixed day number.
- /// </summary>
- /// <param name="date">An integer specifying the fixed day number.
- /// </param>
- /// <returns>An integer value representing the day of the month.
- /// </returns>
- public static int day_from_fixed(int date) {
- int day;
- int month;
- int year;
- dmy_from_fixed(out day, out month, out year, date);
- return day;
- }
- /// <summary>
- /// The method computes the difference between two Islamic dates.
- /// </summary>
- /// <param name="dayA">The integer parameter gives the day of month
- /// of the first date.
- /// </param>
- /// <param name="monthA">The integer parameter gives the Islamic
- /// month of the first date.
- /// </param>
- /// <param name="yearA">The integer parameter gives the Islamic
- /// year of the first date.
- /// </param>
- /// <param name="dayB">The integer parameter gives the day of month
- /// of the second date.
- /// </param>
- /// <param name="monthB">The integer parameter gives the Islamic
- /// month of the second date.
- /// </param>
- /// <param name="yearB">The integer parameter gives the Islamic
- /// year of the second date.
- /// </param>
- /// <returns>An integer giving the difference of days from the first
- /// the second date.
- /// </returns>
- public static int date_difference(int dayA, int monthA, int yearA,
- int dayB, int monthB, int yearB)
- {
- return fixed_from_dmy(dayB, monthB, yearB) -
- fixed_from_dmy(dayA, monthA, yearA);
- }
- /// <summary>
- /// The method computes the number of the day in the year from
- /// a Islamic date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Islamic year.
- /// </param>
- /// <param name="year">An integer representing the Islamic year.
- /// </param>
- /// <returns>An integer value giving the number of the day in the
- /// Islamic year, counting from 1.
- /// </returns>
- public static int day_number(int day, int month, int year) {
- return date_difference(31, 12, year-1, day, month, year);
- }
- /// <summary>
- /// The method computes the days remaining in the given Islamic
- /// year from a Islamic date.
- /// </summary>
- /// <param name="day">An integer representing the day of the month,
- /// counting from 1.
- /// </param>
- /// <param name="month">An integer representing the month in the
- /// Islamic year.
- /// </param>
- /// <param name="year">An integer representing the Islamic year.
- /// Non-positive values are allowed also.
- /// </param>
- /// <returns>An integer value giving the number of days remaining in
- /// the Islamic year.
- /// </returns>
- public static int days_remaining(int day, int month, int year) {
- return date_difference(day, month, year,31, 12, year);
- }
- } // class CCHijriCalendar
- /// <summary>
- /// A class that supports the Gregorian based calendars with other eras
- /// (e.g. <see cref="T:System.Gloablization.JapaneseCalendar"/>).
- /// </summary>
- [System.Serializable]
- public class CCGregorianEraHandler {
- /// <summary>
- /// A struct that represents a single era.
- /// </summary>
- [System.Serializable]
- struct Era {
- /// <summary>
- /// The integer number identifying the era.
- /// </summary>
- private int _nr;
- /// <value>
- /// A get-only property that gives the era integer number.
- /// </value>
- public int Nr { get { return _nr; } }
- /// <summary>This integer gives the first day of the era as
- /// fixed day number.
- /// </summary>
- private int _start; // inclusive
- /// <summary>
- /// This integer gives the gregorian year of the
- /// <see cref="M:_start"/> value.
- /// </summary>
- private int _gregorianYearStart;
- /// <summary>
- /// This integer gives the last day of the era as fixed day
- /// number.
- /// </summary>
- private int _end; // inclusive
- /// <summary>
- /// This integer gives the largest year number of this era.
- /// </summary>
- private int _maxYear;
- /// <summary>
- /// This constructor creates the era structure.
- /// </summary>
- /// <param name="nr">The integer number of the era.
- /// </param>
- /// <param name="start">The fixed day number defining the
- /// first day of the era.
- /// </param>
- /// <param name="end">The fixed day number that defines the
- /// last day of the era.
- /// </param>
- public Era(int nr, int start, int end) {
- if (nr == 0)
- throw new System.ArgumentException(
- "Era number shouldn't be zero.");
- _nr = nr;
- if (start > end) {
- throw new System.ArgumentException(
- "Era should start before end.");
- }
- _start = start;
- _end = end;
- _gregorianYearStart =
- CCGregorianCalendar.year_from_fixed(_start);
- int gregorianYearEnd =
- CCGregorianCalendar.year_from_fixed(_end);
- _maxYear = gregorianYearEnd - _gregorianYearStart + 1;
- }
- /// <summary>
- /// This method computes the Gregorian year from the year
- /// of this era.
- /// </summary>
- /// <param name="year">An integer giving the year in the
- /// era.
- /// </param>
- /// <returns>
- /// The Gregorian year as integer.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The exception is thrown if the year isn't valid in this
- /// era.
- /// </exception>
- public int GregorianYear(int year) {
- if (year < 1 || year > _maxYear) {
- System.IO.StringWriter sw =
- new System.IO.StringWriter();
- sw.Write(
- "Valid Values are between " +
- "{0} and {1}, inclusive.",
- 1, _maxYear);
- throw new System.ArgumentOutOfRangeException(
- "year", sw.ToString());
- }
- return year + _gregorianYearStart - 1;
- }
- /// <summary>
- /// This function checks wether the given fixed day number is
- /// ion the time span of the era.
- /// </summary>
- /// <param name="date">An integer giving the fixed day
- /// number.
- /// </param>
- /// <returns>A boolean: true if the argument is in the time
- /// span of the era.
- /// </returns>
- public bool Covers(int date) {
- return _start <= date && date <= _end;
- }
- /// <summary>
- /// This function returns the year of the era and sets
- /// the era in an output parameter.
- /// </summary>
- /// <param name="era">An output parameter returning the
- /// era number.
- /// </param>
- /// <param name="date">An integer giving the fixed day
- /// number.
- /// </param>
- /// <returns>An integer giving the year of the era.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The exception is thrown if date is outside of the time
- /// span of the era.
- /// </exception>
- public int EraYear(out int era, int date) {
- if (!Covers(date))
- throw new System.ArgumentOutOfRangeException(
- "date",
- "Time was out of Era range.");
- int gregorianYear =
- CCGregorianCalendar.year_from_fixed(date);
- era = _nr;
- return gregorianYear - _gregorianYearStart + 1;
- }
- } // struct Era
- /// <summary>
- /// A private member storing the eras in a
- /// <see cref="T:System.Collections.SortedList"/>.
- /// </summary>
- private SortedList _Eras;
- /// <value>
- /// The property returns the era numbers as an array of integers.
- /// </value>
- public int[] Eras {
- get {
- int[] a = new int[_Eras.Count];
- for (int i = 0; i < _Eras.Count; i++) {
- Era e = (Era)_Eras.GetByIndex(i);
- a[i] = e.Nr;
- }
- return a;
- }
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- public CCGregorianEraHandler() {
- _Eras = new SortedList();
- }
- /// <summary>
- /// Method adds an era to the GregorianEraHandler instance.
- /// </summary>
- /// <param name="nr">The integer number of the era.
- /// </param>
- /// <param name="rd_start">The fixed day number defining the
- /// first day of the era.
- /// </param>
- /// <param name="rd_end">The fixed day number that defines the
- /// last day of the era.
- /// </param>
- public void appendEra(int nr, int rd_start, int rd_end) {
- Era era = new Era(nr, rd_start, rd_end);
- _Eras[(System.Object)nr] = era;
- }
- /// <summary>
- /// Method adds a yet not-ended era to the GregorianEraHandler
- /// instance.
- /// </summary>
- /// <param name="nr">The integer number of the era.
- /// </param>
- /// <param name="rd_start">The fixed day number defining the
- /// first day of the era.
- /// </param>
- public void appendEra(int nr, int rd_start) {
- appendEra(nr, rd_start,
- CCFixed.FromDateTime(DateTime.MaxValue));
- }
- /// <summary>
- /// This method computes the Gregorian year from the year
- /// of the given era.
- /// </summary>
- /// <param name="year">An integer giving the year in the
- /// era.
- /// </param>
- /// <param name="era">An integer giving the era number.
- /// </param>
- /// <returns>
- /// The Gregorian year as integer.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The exception is thrown if the year isn't valid in this
- /// era.
- /// </exception>
- public int GregorianYear(int year, int era) {
- Era e = (Era)_Eras[(System.Object)era];
- return e.GregorianYear(year);
- }
- /// <summary>
- /// This function returns the year of the era and sets
- /// the era in an output parameter.
- /// </summary>
- /// <param name="era">An output parameter returning the
- /// era number.
- /// </param>
- /// <param name="date">An integer giving the fixed day
- /// number.
- /// </param>
- /// <returns>An integer giving the year of the era.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The exception is thrown if the fixed day number is outside of the
- /// time spans of all eras.
- /// </exception>
- public int EraYear(out int era, int date)
- {
- IList list = _Eras.GetValueList();
- foreach (Era e in list) {
- if (e.Covers(date))
- return e.EraYear(out era, date);
- }
- throw new System.ArgumentOutOfRangeException("date",
- "Time value was out of era range.");
- }
- /// <summary>
- /// The method checks whether a given
- /// <see cref="T:System.DateTime"/> is covered by any era.
- /// </summary>
- /// <param name="time">A
- /// <see cref="T:System.DateTime"/> giving the date and time.
- /// </param>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The exception is thrown if the argument isn't inside the time
- /// span of any era.
- /// </exception>
- public void CheckDateTime(System.DateTime time) {
- int date = CCFixed.FromDateTime(time);
- if (!ValidDate(date))
- throw new System.ArgumentOutOfRangeException("time",
- "Time value was out of era range.");
- }
-
- /// <summary>
- /// The method tests whether a given
- /// fixed day number is covered by any era.
- /// </summary>
- /// <param name="date">An integer representing the fixed day number.
- /// </param>
- /// <returns> A boolean is returned: true if the argument is inside
- /// the time span of one era; false otherwise.
- /// </returns>
- public bool ValidDate(int date) {
- IList list = _Eras.GetValueList();
- foreach (Era e in list) {
- if (e.Covers(date))
- return true;
- }
- return false;
- }
- /// <summary>
- /// The method tests, whether the era number does exist.
- /// </summary>
- /// <param name="era">An integer giving the era number.
- /// </param>
- /// <returns>A boole value: True if the era number does exist;
- /// false otherwise.
- /// </returns>
- public bool ValidEra(int era) {
- return _Eras.Contains((System.Object)era);
- }
- } // class CCGregorianEraHandler
- } // namespace System.Globalization
|