Пример #1
0
        /// <summary>
        /// Calculates the current date
        /// This will work also when a year cannot be divided in days without a remainder
        /// Every year will end at the last full day of the year.
        /// The time difference carries over from year to year, untill it's enough to get another full day.
        /// Example: if a year is 365.25 days, the first three years will have 365 days and 0.25 will carry over.
        /// On the fourth year there will be enough time carried over, so it will have 366 days.
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public virtual Date GetLeapDate(double time)
        {
            // Time in a short (non-leap) year
            double shortYear = loader.Clock.year.value - (loader.Clock.year.value % loader.Clock.day.value);

            // Chance of getting a leap day in a year
            double chanceOfLeapDay = (loader.Clock.year.value % loader.Clock.day.value) / loader.Clock.day.value;

            // Number of days in a short (non-leap) year
            int daysInOneShortYear = (int)(shortYear / loader.Clock.day.value);

            // Current Year (calculated as if there were no leap years)
            int year = (int)(time / shortYear);

            // Time left this year (calculated as if there were no leap years)
            double timeFromPreviousYears = year * shortYear;
            double timeLeftThisYear      = time - timeFromPreviousYears;

            // Current Day of the Year (calculated as if there were no leap years)
            int day = (int)Math.Floor(timeLeftThisYear / loader.Clock.day.value);

            // Remove the days lost to leap years
            day -= (int)Math.Floor(chanceOfLeapDay * year);

            // If days go negative, borrow days from the previous year
            while (day < 0)
            {
                year--;
                day += daysInOneShortYear + 1;
            }

            // Now 'day' and 'year' correctly account for leap years

            // Time left to count
            double left = MOD(time, loader.Clock.day.value);

            // Number of hours in this day
            int hours = (int)(left / loader.Clock.hour.value);

            // Time left to count
            left = left - hours * loader.Clock.hour.value;

            // Number of minutes in this hour
            int minutes = (int)(left / loader.Clock.minute.value);

            // Time left to count
            left = left - minutes * loader.Clock.minute.value;

            // Number of seconds in this minute
            int seconds = (int)(left / loader.Clock.second.value);

            // DATE CALCULATION COMPLETE

            // Temporary Month (needed later)
            Month month = null;

            // If there are months, change 'day' to indicate the current 'day of the month'
            if (loader.calendar.Count > 0)
            {
                // Calculate the time passed from the last month reset
                // Note: months reset every N years (Kronometer.resetMonths)

                // Total days passed untill now
                int daysPassedTOT = (int)Math.Floor(time / loader.Clock.day.value);

                // Days between month resets = normal days between month resets + leap days between month resets
                int daysBetweenResets = (daysInOneShortYear * loader.resetMonths) + (int)(chanceOfLeapDay * loader.resetMonths);

                // Days passed since last month reset
                int daysFromReset = (int)MOD(daysPassedTOT, daysBetweenResets);



                // Go through each month in the calendar
                for (int i = 0; i < loader?.calendar?.Count; i++)
                {
                    Month Mo = loader.calendar[i];

                    month = Mo;

                    // If there are more days left than there are in this month
                    // AND
                    // this is not the last month of the calendar
                    if (daysFromReset >= Mo.days && Mo != loader.calendar[loader.calendar.Count - 1])
                    {
                        // Remove this month worth of days and move on to check next month
                        daysFromReset -= Mo.days;
                    }
                    else
                    {
                        break;
                    }
                    // If we run out of months, the last month will last until the next reset
                }

                // Set 'day' as 'day of the month'
                day = daysFromReset;
            }

            // The final date
            return(new Date(year, month, day, hours, minutes, seconds));
        }
Пример #2
0
        /// <summary>
        /// Calculates the current date
        /// This will work also when a year cannot be divided in days without a remainder
        /// Every year will end at the last full day of the year.
        /// The time difference carries over from year to year, untill it's enough to get another full day.
        /// Example: if a year is 365.25 days, the first three years will have 365 days and 0.25 will carry over.
        /// On the fourth year there will be enough time carried over, so it will have 366 days.
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public virtual Date GetLeapDate(double time)
        {
            // Number of days in a short (non-leap) year
            int daysInOneShortYear = SmartFloor(loader.Clock.year.value / loader.Clock.day.value);
            int daysInOneLongYear  = (int)Math.Ceiling(loader.Clock.year.value / loader.Clock.day.value);

            // Time in a short (non-leap) year
            double shortYear = loader.Clock.day.value * daysInOneShortYear;

            // Chance of getting a leap day in a year
            double chanceOfLeapDay = (loader.Clock.year.value / loader.Clock.day.value) % 1;

            if (daysInOneShortYear == daysInOneLongYear)
            {
                chanceOfLeapDay = 0;
            }

            // Time left to count
            double left = time;

            double leap    = 0;
            int    year    = 0;
            int    day     = 0;
            int    hours   = 0;
            int    minutes = 0;
            int    seconds = 0;

            while (left >= shortYear)
            {
                left -= shortYear;
                leap += chanceOfLeapDay;
                year += 1;

                while (SmartFloor(leap) >= 1)
                {
                    leap = Math.Max(leap - 1, 0);

                    if (!(left < loader.Clock.day.value))
                    {
                        left -= loader.Clock.day.value;
                    }
                    else
                    {
                        year -= 1;
                        day  += daysInOneShortYear;
                    }
                }
            }

            day  += (int)(left / loader.Clock.day.value);
            left -= (int)(left / loader.Clock.day.value) * loader.Clock.day.value;

            if (left >= loader.Clock.day.value)
            {
                day  += 1;
                left -= loader.Clock.day.value;
            }

            hours = (int)(left / 3600);
            left -= hours * 3600;

            minutes = (int)(left / 60);
            left   -= minutes * 60;

            seconds = (int)left;

            // DATE CALCULATION COMPLETE

            // Temporary Month (needed later)
            Month month      = null;
            int   dayOfMonth = 0;

            // If there are months, change 'dayOfMonth' to indicate the current 'day of the month'
            if (loader.calendar.Count > 0)
            {
                // Calculate the time passed from the last month reset
                // Note: months reset every N years (Kronometer.resetMonths)

                // Total days passed untill now
                int daysPassedTOT = (int)Math.Floor(time / loader.Clock.day.value);

                // Days between month resets = normal days between month resets + leap days between month resets
                int daysBetweenResets = (daysInOneShortYear * loader.resetMonths) + (int)(chanceOfLeapDay * loader.resetMonths);

                // Days passed since last month reset
                int daysFromReset = (int)MOD(daysPassedTOT, daysBetweenResets);



                // Go through each month in the calendar
                for (int i = 0; i < loader?.calendar?.Count; i++)
                {
                    Month Mo = loader.calendar[i];

                    month = Mo;

                    // If there are more days left than there are in this month
                    // AND
                    // this is not the last month of the calendar
                    if (daysFromReset >= Mo.days && Mo != loader.calendar[loader.calendar.Count - 1])
                    {
                        // Remove this month worth of days and move on to check next month
                        daysFromReset -= Mo.days;
                    }
                    else
                    {
                        break;
                    }
                    // If we run out of months, the last month will last until the next reset
                }

                // Set 'dayOfMonth' as 'day of the month'
                dayOfMonth = daysFromReset;
            }

            // The final date
            return(new Date(year, month, dayOfMonth, day, hours, minutes, seconds));
        }