private void InitLeapYear(int k, float timeZone) { int numberOfMonths = 14; Months = new Tuple <int, DateTime, bool> [numberOfMonths]; DateTime[] newMoons = new DateTime[numberOfMonths]; int[] majorTermAtMonthBeginnings = new int[numberOfMonths]; // get all the new moons, local date newMoons[0] = _month11LastYear; newMoons[numberOfMonths - 1] = _month11ThisYear; for (int i = 1; i < numberOfMonths - 1; i++) { newMoons[i] = JulianDateConverter.JulianDateToUniversalDateTime(Moon.GetNewMoon(k + i)).AddHours(timeZone).Date; } // determine leap month bool found = false; majorTermAtMonthBeginnings[0] = (int)(Sun.GetSunLongitudeAtJulianDate( newMoons[0].AddHours(-timeZone).UniversalDateTimeToJulianDate()) * 6 / Math.PI); for (int i = 0; i < numberOfMonths - 1; i++) { // If major term at the beginning of this month is same as // major term at the beginning of next month, i.e. this month // does not have major term, this month is leap month. // // Note that only the first month which does not have major term // is leap month (as a Lunar year has maximum one leap month). if (found) { Months[i] = new Tuple <int, DateTime, bool>(MonthIdxToMonthNumber((i - 1 + 11) % 12), newMoons[i], false); continue; } double julianDateAtNextMonthBeginning = newMoons[i + 1].AddHours(-timeZone).UniversalDateTimeToJulianDate(); majorTermAtMonthBeginnings[i + 1] = (int)(Sun. GetSunLongitudeAtJulianDate(julianDateAtNextMonthBeginning) * 6 / Math.PI); // In this algorithm, comparisons will happen with updated element only. // Yet be careful: initial value of elements of an int array are zeros. // This may confuse the debugging process! if (majorTermAtMonthBeginnings[i] == majorTermAtMonthBeginnings[i + 1]) { found = true; LeapMonthIndex = i; Months[i] = new Tuple <int, DateTime, bool>(MonthIdxToMonthNumber((i - 1 + 11) % 12), newMoons[i], true); } else { Months[i] = new Tuple <int, DateTime, bool>(MonthIdxToMonthNumber((i + 11) % 12), newMoons[i], false); } } Months[numberOfMonths - 1] = new Tuple <int, DateTime, bool>(11, newMoons[13], false); }
public void JulianDayNumberToUniversalDateTimeTest() { DateTime dateTime1 = new DateTime(2000, 1, 1, 6, 15, 11); DateTime dateTime2 = new DateTime(2000, 1, 1, 16, 15, 11); Assert.AreEqual(dateTime1, JulianDateConverter.JulianDateToUniversalDateTime(dateTime1.UniversalDateTimeToJulianDate())); Assert.AreEqual(dateTime2, JulianDateConverter.JulianDateToUniversalDateTime(dateTime2.UniversalDateTimeToJulianDate())); //dateTime1 = new DateTime(1582, 10, 15, 6, 15, 11); //dateTime2 = new DateTime(1582, 10, 4, 16, 15, 11); //Assert.AreEqual(dateTime1, Astronomy.JulianDateToUniversalDateTime(dateTime1.UniversalDateTimeToJulianDate())); //Assert.AreEqual(dateTime2, Astronomy.JulianDateToUniversalDateTime(dateTime2.UniversalDateTimeToJulianDate())); }
public void GetNewMoonInJulianDateTest() { //int k = 1236; double jd = Moon.GetNewMoon(1236); TimeSpan diff = (new DateTime(1999, 12, 7, 22, 32, 42)) - JulianDateConverter.JulianDateToUniversalDateTime(jd); Assert.AreEqual(2451520.4393767994, jd, 1E-10); int tollerance = 500;// milliseconds bool isPassed = (diff < TimeSpan.FromMilliseconds(tollerance)) && (diff > -TimeSpan.FromMilliseconds(tollerance)); Assert.IsTrue(isPassed, String.Format("There wwas a difference of {0} between expected and retured value.", diff)); }
private void InitNonLeapYear(int k, float timeZone) { int numberOfMonths = 13; Months = new Tuple <int, DateTime, bool> [numberOfMonths]; Months[0] = new Tuple <int, DateTime, bool>(11, _month11LastYear, false); Months[numberOfMonths - 1] = new Tuple <int, DateTime, bool>(11, _month11ThisYear, false); for (int i = 1; i < numberOfMonths - 1; i++) { var newMoon = JulianDateConverter.JulianDateToUniversalDateTime(Moon.GetNewMoon(k + i)).AddHours(timeZone).Date; Months[i] = new Tuple <int, DateTime, bool>(MonthIdxToMonthNumber((i + 11) % 12), newMoon, false); } LeapMonthIndex = -1; }
internal static LuniSolarDate <T> CalculateLuniSolarDateFromSolarDate(int year, int month, int day) { // Sample case 1: Solar date 24/05/2000 --- Lunar date 21/04/2000 // previousNewMoon = 04/05/2000 // lunarYear = previousNewMoon.Year = 2000 // newMoon11Before = 08/12/1999 // newMoon11After = 26/11/2000 // (04/05/2000 - 08/12/1999) / 29 = 148 days / 29 // = 5.10x // -------------------------------------------------------------- // Sample case 2: Solar date 01/01/2014 --- Lunar date 01/12/2013 // previousNewMoon = 01/01/2014 // previousNewMoon.Year = 2014 // lunarYear = 2013 // newMoon11Before = 03/12/2013 // newMoon11After = 26/11/2000 // (01/01/2014 - 03/12/2013) / 29 = 29 days / 29 // = 1 // -------------------------------------------------------------- // Sample case 3: Solar date 22/12/2033 --- Lunar date 01/11i/2033 // previousNewMoon = 22/12/2033 // lunarYear = previousNewMoon.Year = 2033 // newMoon11Before = 03/12/2032 // newMoon11After = 22/11/2033 var timeZone = ILocalInfoProvider.GetLocalInfoProvider <T>().TimeZone; int lunarYear; int lunarMonth; int lunarDay; bool isLeapMonth = false; var thisDay = new DateTime(year, month, day); var k = (int)((thisDay.AddHours(-timeZone).UniversalDateTimeToJulianDate() - 2415021.076998695) / Constants.SynodicMonth + 0.5); var previousNewMoon = JulianDateConverter.JulianDateToUniversalDateTime(Moon.GetNewMoon(k)).AddHours(timeZone).Date; while (previousNewMoon > thisDay) { previousNewMoon = JulianDateConverter.JulianDateToUniversalDateTime(Moon.GetNewMoon(--k)).AddHours(timeZone).Date; } // "previous, this/current" and "next" are not used to avoid ambiguity. var newMoon11Before = Moon.GetNewMoon11(previousNewMoon.Year - 1, timeZone).Date; var newMoon11After = Moon.GetNewMoon11(previousNewMoon.Year, timeZone).Date; // correcting for such cases as case 3 if (newMoon11After < previousNewMoon) { newMoon11Before = newMoon11After; newMoon11After = Moon.GetNewMoon11(previousNewMoon.Year + 1, timeZone).Date; } var isLeapYear = (newMoon11After - newMoon11Before).TotalDays > 365.0; var monthsFromNewMoon11Before = (int)((previousNewMoon - newMoon11Before).TotalDays / 29); /* Note: * monthsFromNewMoon11Before = 0: lunar month = 11, lunar year = previous year * monthsFromNewMoon11Before = 1: lunar month = 12, lunar year = previous year * monthsFromNewMoon11Before = 2: lunar month = 1, lunar year = this year * monthsFromNewMoon11Before = 3: lunar month = 2, lunar year = this year * and so on */ // month 11 and 12 belong to lunar year of the previous year. if (monthsFromNewMoon11Before < 2) { lunarYear = newMoon11After.Year - 1; lunarMonth = 11 + monthsFromNewMoon11Before; } else { lunarYear = newMoon11After.Year; lunarMonth = monthsFromNewMoon11Before - 1; } // correcting month number if this lunar year is leap year if (isLeapYear) { var leapMonthIndex = LuniSolarCalendar <VietnameseLocalInfoProvider> .GetLunarYear(newMoon11After.Year).LeapMonthIndex; if (monthsFromNewMoon11Before >= leapMonthIndex) { lunarMonth--; if (monthsFromNewMoon11Before == leapMonthIndex) { isLeapMonth = true; } } } lunarDay = (int)(thisDay - previousNewMoon).TotalDays + 1; return(new LuniSolarDate <T>(lunarYear, lunarMonth, isLeapMonth, lunarDay, thisDay)); }