internal LuniSolarYear(int year)
        {
            Year = year;
            //TimeZone = timeZone;
            var timeZone = ILocalInfoProvider.GetLocalInfoProvider <T>().TimeZone;

            // at 00:00:00 local
            _month11LastYear = Moon.GetNewMoon11(Year - 1, timeZone).Date;
            _month11ThisYear = Moon.GetNewMoon11(Year, timeZone).Date;

            // Convert the local date to UTC date time by adding AddHours(-TimeZone).
            double jdMonth11LastYear = _month11LastYear.AddHours(-timeZone).UniversalDateTimeToJulianDate();
            double jdMonth11ThisYear = _month11ThisYear.AddHours(-timeZone).UniversalDateTimeToJulianDate();

            int k = (int)(0.5 + (jdMonth11LastYear - 2415021.076998695) / 29.530588853);

            IsLeapYear = (jdMonth11ThisYear - jdMonth11LastYear) > 365.0;

            if (!IsLeapYear)
            {
                InitNonLeapYear(k, timeZone);
                Console.WriteLine("None Leap {0}", year);
            }
            else
            {
                InitLeapYear(k, timeZone);
                Console.WriteLine("Leap {0}", year);
            }
        }
Example #2
0
 /// <summary>
 /// Returns "Giêng, Hai, Ba..." or "Giêng nhuận, Hai nhuận, Ba nhuận..." (if applicable)
 /// </summary>
 /// <returns></returns>
 public static string GetMonthShortName(int month, bool isLeapMonth)
 {
     if (month < 1 || month > ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames.Length)
     {
         return("undefined");
     }
     return(ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames[month - 1] + (isLeapMonth ? " nhuận" : ""));
 }
Example #3
0
 /// <summary>
 /// Returns "Name (Can Chi)" or "Name (Can Chi) nhuận".
 /// E.g. "Bảy (Bính Ngọ)", "Năm (Nhâm Ngọ) nhuận".
 /// </summary>
 /// <returns></returns>
 public static string GetMonthFullName(int year, int month, bool isLeapMonth = false)
 {
     if (month < 1 || month > ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames.Length)
     {
         return("undefined");
     }
     return(String.Format("{0} ({1} {2}){3}", GetMonthName(month), GetMonthCelestialStemName(year, month), GetMonthTerrestrialBranchName(month), (isLeapMonth ? " nhuận" : "").ToString()));
 }
Example #4
0
 /// <summary>
 /// Returns "Giêng, Hai, Ba..."
 /// </summary>
 /// <returns></returns>
 public static string GetMonthName(int month)
 {
     if (month < 1 || month > ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames.Length)
     {
         return("undefined");
     }
     return(ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames[month - 1]);
 }
Example #5
0
 public static string GetMonthTerrestrialBranchName(int month)
 {
     if (month < 1 || month > ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames.Length)
     {
         return("undefined");
     }
     return(ILocalInfoProvider.GetLocalInfoProvider <T>().BranchNames[GetMonthTerrestrialIndex(month)]);
 }
Example #6
0
 public static string GetMonthCelestialStemName(int year, int month)
 {
     if (month < 1 || month > ILocalInfoProvider.GetLocalInfoProvider <T>().MonthNames.Length)
     {
         return("undefined");
     }
     return(ILocalInfoProvider.GetLocalInfoProvider <T>().StemNames[GetMonthCelestialStemIndex(year, month)]);
 }
        public static LuniSolarDate <T> LuniSolarDateFromSolarDate(int year, int month, int day)
        {
            float timeZone = ILocalInfoProvider.GetLocalInfoProvider <T>().TimeZone;

            if (DateCacheSize > 0)
            {
                // init dictionary for the first time
                if (_dateCache == null)
                {
                    _dateCache = new Dictionary <string, LuniSolarDate <T> >(DateCacheSize);
                }

                // hash the year and time zone
                string key = GetSolarDateHash(year, month, day, timeZone);

                // if year is already cached, just take it out
                if (_dateCache.ContainsKey(key))
                {
                    return(_dateCache[key]);
                }
                // else, calculate the date and add cache to dictionay
                else
                {
                    // if dictionary is already full, remove the oldest pair.
                    if (_dateCache.Count == DateCacheSize)
                    {
                        _dateCache.Remove(_dateCache.Keys.First());
                    }
                    // calculate the date
                    var luniSolarDate = LuniSolarDate <T> .CalculateLuniSolarDateFromSolarDate(year, month, day);

                    // do not forget to add new date to dictionay :))
                    _dateCache.Add(key, luniSolarDate);
                    return(luniSolarDate);
                }
            }
            // no caching, just calculate the date directly
            else
            {
                return(LuniSolarDate <T> .CalculateLuniSolarDateFromSolarDate(year, month, day));
            }
        }
        public static LuniSolarYear <T> GetLunarYear(int year)
        {
            float timeZone = ILocalInfoProvider.GetLocalInfoProvider <T>().TimeZone;

            if (YearCacheSize > 0)
            {
                // init dictionary for the first time
                if (_yearCache == null)
                {
                    _yearCache = new Dictionary <string, LuniSolarYear <T> >();
                }

                // hash the year and time zone
                string key = GetYearHash(year, timeZone);

                // if year is already cached, just take it out
                if (_yearCache.ContainsKey(key))
                {
                    return(_yearCache[key]);
                }
                // else, calculate the year and add cache to dictionay
                else
                {
                    // if dictionary is already full, remove the oldest pair.
                    if (_yearCache.Count == YearCacheSize)
                    {
                        _yearCache.Remove(_yearCache.Keys.First());
                    }
                    // calculate the year
                    var lunarYear = new LuniSolarYear <T>(year);
                    // do not forget to add new year to dictionay :))
                    _yearCache.Add(key, lunarYear);
                    return(lunarYear);
                }
            }
            // no caching, just calculate the year directly
            else
            {
                return(new LuniSolarYear <T>(year));
            }
        }
 public static string GetYearTerrestrialBranchName(int year)
 => ILocalInfoProvider.GetLocalInfoProvider <T>().BranchNames[GetYearTerrestrialBranchIndex(year)];
Example #10
0
 public static string GetYearCelestialStemName(int year)
 => ILocalInfoProvider.GetLocalInfoProvider <T>().StemNames[GetYearCelestialStemIndex(year)];
Example #11
0
 public static int GetSolarTermIndex(DateTime date)
 => Sun.GetSolarTermIndex(date.AddHours(-ILocalInfoProvider.GetLocalInfoProvider <T>().TimeZone).AddHours(24));
Example #12
0
 public static string GetDayTerrestrialBranchName(int solarYear, int solarMonth, int solarDay)
 => ILocalInfoProvider.GetLocalInfoProvider <T>().BranchNames[GetDayTerrestrialIndex(solarYear, solarMonth, solarDay)];
Example #13
0
 public static string GetDayCelestialStemName(int solarYear, int solarMonth, int solarDay)
 => ILocalInfoProvider.GetLocalInfoProvider <T>().StemNames[GetDayCelestialStemIndex(solarYear, solarMonth, solarDay)];
Example #14
0
        ///// <summary>
        ///// 0 -> 12, 1 -> 1, 2 -> 2, 3 -> 3... 11 -> 11
        ///// </summary>
        ///// <param name="monthIndex"></param>
        ///// <returns></returns>
        //public static int GetMonth(int monthIndex) { return monthIndex == 0 ? 12 : monthIndex; }

        #endregion

        #region Day

        public static string GetSolarTermName(DateTime date)
        {
            return(ILocalInfoProvider.GetLocalInfoProvider <T>().SolarTerms[GetSolarTermIndex(date)]);
        }
Example #15
0
        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));
        }