Exemple #1
0
        /// <summary>
        /// Returns the PeriodField for the given index, in the range 0-8 inclusive.
        /// </summary>
        private static IPeriodField GetFieldForIndex(PeriodFieldSet fields, int index)
        {
            switch (index)
            {
            case YearIndex: return(fields.Years);

            case MonthIndex: return(fields.Months);

            case WeekIndex: return(fields.Weeks);

            case DayIndex: return(fields.Days);

            case HourIndex: return(fields.Hours);

            case MinuteIndex: return(fields.Minutes);

            case SecondIndex: return(fields.Seconds);

            case MillisecondIndex: return(fields.Milliseconds);

            case TickIndex: return(fields.Ticks);

            default: throw new ArgumentOutOfRangeException("index");
            }
        }
Exemple #2
0
        /// <summary>
        /// Returns the PeriodField for the given unit value, or null if the values does
        /// not represent a single unit.
        /// </summary>
        private static IPeriodField GetSingleField(PeriodFieldSet fields, PeriodUnits units)
        {
            switch (units)
            {
            case PeriodUnits.Years: return(fields.Years);

            case PeriodUnits.Months: return(fields.Months);

            case PeriodUnits.Weeks: return(fields.Weeks);

            case PeriodUnits.Days: return(fields.Days);

            case PeriodUnits.Hours: return(fields.Hours);

            case PeriodUnits.Minutes: return(fields.Minutes);

            case PeriodUnits.Seconds: return(fields.Seconds);

            case PeriodUnits.Milliseconds: return(fields.Milliseconds);

            case PeriodUnits.Ticks: return(fields.Ticks);

            default: return(null);
            }
        }
Exemple #3
0
        /// <summary>
        /// Adds the contents of this period to the given local instant in the given calendar system.
        /// </summary>
        internal LocalInstant AddTo(LocalInstant localInstant, CalendarSystem calendar, int scalar)
        {
            Preconditions.CheckNotNull(calendar, "calendar");

            PeriodFieldSet fields = calendar.PeriodFields;
            LocalInstant   result = localInstant;

            if (years != 0)
            {
                result = fields.Years.Add(result, years * scalar);
            }
            if (months != 0)
            {
                result = fields.Months.Add(result, months * scalar);
            }
            if (weeks != 0)
            {
                result = fields.Weeks.Add(result, weeks * scalar);
            }
            if (days != 0)
            {
                result = fields.Days.Add(result, days * scalar);
            }
            if (hours != 0)
            {
                result = fields.Hours.Add(result, hours * scalar);
            }
            if (minutes != 0)
            {
                result = fields.Minutes.Add(result, minutes * scalar);
            }
            if (seconds != 0)
            {
                result = fields.Seconds.Add(result, seconds * scalar);
            }
            if (milliseconds != 0)
            {
                result = fields.Milliseconds.Add(result, milliseconds * scalar);
            }
            if (ticks != 0)
            {
                result = fields.Ticks.Add(result, ticks * scalar);
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Returns the period between a start and an end date/time, using only the given units.
        /// </summary>
        /// <remarks>
        /// If <paramref name="end"/> is before <paramref name="start" />, each property in the returned period
        /// will be negative. If the given set of units cannot exactly reach the end point (e.g. finding
        /// the difference between 1am and 3:15am in hours) the result will be such that adding it to <paramref name="start"/>
        /// will give a value between <paramref name="start"/> and <paramref name="end"/>. In other words,
        /// any rounding is "towards start"; this is true whether the resulting period is negative or positive.
        /// </remarks>
        /// <param name="start">Start date/time</param>
        /// <param name="end">End date/time</param>
        /// <param name="units">Units to use for calculations</param>
        /// <exception cref="ArgumentException"><paramref name="units"/> is empty or contained unknown values.</exception>
        /// <exception cref="ArgumentException"><paramref name="start"/> and <paramref name="end"/> use different calendars.</exception>
        /// <returns>The period between the given date/times, using the given units.</returns>
        public static Period Between(LocalDateTime start, LocalDateTime end, PeriodUnits units)
        {
            Preconditions.CheckArgument(units != 0, "units", "Units must not be empty");
            Preconditions.CheckArgument((units & ~PeriodUnits.AllUnits) == 0, "units", "Units contains an unknown value: {0}", units);
            CalendarSystem calendar = start.Calendar;

            Preconditions.CheckArgument(calendar.Equals(end.Calendar), "end", "start and end must use the same calendar system");

            LocalInstant startLocalInstant = start.LocalInstant;
            LocalInstant endLocalInstant   = end.LocalInstant;

            if (startLocalInstant == endLocalInstant)
            {
                return(Zero);
            }

            PeriodFieldSet fields = calendar.PeriodFields;

            // Optimization for single field
            var singleField = GetSingleField(fields, units);

            if (singleField != null)
            {
                long value = singleField.Subtract(end.LocalInstant, start.LocalInstant);
                return(new Period(units, value));
            }

            // Multiple fields
            long[] values = new long[ValuesArraySize];

            LocalInstant remaining     = startLocalInstant;
            int          numericFields = (int)units;

            for (int i = 0; i < ValuesArraySize; i++)
            {
                if ((numericFields & (1 << i)) != 0)
                {
                    var field = GetFieldForIndex(fields, i);
                    values[i] = field.Subtract(endLocalInstant, remaining);
                    remaining = field.Add(remaining, values[i]);
                }
            }
            return(new Period(values));
        }
 private CalendarSystem(string id, string name, YearMonthDayCalculator yearMonthDayCalculator, int minDaysInFirstWeek)
 {
     this.id   = id;
     this.name = name;
     this.yearMonthDayCalculator = yearMonthDayCalculator;
     this.weekYearCalculator     = new WeekYearCalculator(yearMonthDayCalculator, minDaysInFirstWeek);
     this.minYear      = yearMonthDayCalculator.MinYear;
     this.maxYear      = yearMonthDayCalculator.MaxYear;
     this.minTicks     = yearMonthDayCalculator.GetYearTicks(minYear);
     this.maxTicks     = yearMonthDayCalculator.GetYearTicksSafe(maxYear + 1) - 1;
     this.eras         = new ReadOnlyCollection <Era>(new List <Era>(yearMonthDayCalculator.Eras));
     this.periodFields = new PeriodFieldSet.Builder(TimeOfDayCalculator.TimeFields)
     {
         Days   = FixedDurationPeriodField.Days,
         Weeks  = FixedDurationPeriodField.Weeks,
         Months = new MonthsPeriodField(yearMonthDayCalculator),
         Years  = new YearsPeriodField(yearMonthDayCalculator)
     }.Build();
 }