// ----------------------------------------------------------------------
        public void TimePeriodCombinerSample()
        {
            TimePeriodCollection periods = new TimePeriodCollection();

            periods.Add(new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 10)));
            periods.Add(new TimeRange(new DateTime(2011, 3, 04), new DateTime(2011, 3, 08)));

            periods.Add(new TimeRange(new DateTime(2011, 3, 15), new DateTime(2011, 3, 18)));
            periods.Add(new TimeRange(new DateTime(2011, 3, 18), new DateTime(2011, 3, 22)));
            periods.Add(new TimeRange(new DateTime(2011, 3, 20), new DateTime(2011, 3, 24)));

            periods.Add(new TimeRange(new DateTime(2011, 3, 26), new DateTime(2011, 3, 30)));

            TimePeriodCombiner <TimeRange> periodCombiner  = new TimePeriodCombiner <TimeRange>();
            ITimePeriodCollection          combinedPeriods = periodCombiner.CombinePeriods(periods);

            foreach (ITimePeriod combinedPeriod in combinedPeriods)
            {
                Console.WriteLine("Combined Period: " + combinedPeriod);
            }
            // > Combined Period: 01.03.2011 - 10.03.2011 | 9.00:00
            // > Combined Period: 15.03.2011 - 24.03.2011 | 9.00:00
            // > Combined Period: 26.03.2011 - 30.03.2011 | 4.00:00
        }         // TimePeriodCombinerSample
Пример #2
0
        public void FiscalYearsNearestDayGetQuartersTest()
        {
            const int             yearCount = 13;
            Years                 years     = new Years(2006, yearCount, GetFiscalYearCalendar(FiscalYearAlignment.NearestDay));
            ITimePeriodCollection quarters  = years.GetQuarters();

            Assert.AreNotEqual(quarters, null);
            Assert.AreEqual(quarters.Count, yearCount * TimeSpec.QuartersPerYear);

            Assert.AreEqual(quarters[0].Start, new DateTime(2006, 9, 3));
            foreach (Quarter quarter in quarters)
            {
                // last quarter of a leap year
                // http://en.wikipedia.org/wiki/4-4-5_Calendar
                if ((quarter.YearQuarter == YearQuarter.Fourth) && (quarter.Year == 2011 || quarter.Year == 2016))
                {
                    Assert.AreEqual(quarter.Duration.Subtract(TimeCalendar.DefaultEndOffset).Days, TimeSpec.FiscalDaysPerLeapQuarter);
                }
                else
                {
                    Assert.AreEqual(quarter.Duration.Subtract(TimeCalendar.DefaultEndOffset).Days, TimeSpec.FiscalDaysPerQuarter);
                }
            }
        }         // FiscalYearsNearestDayGetQuartersTest
Пример #3
0
        public void GetQuartersTest()
        {
            const int         startYear    = 2004;
            const int         yearCount    = 10;
            const YearMonth   startMonth   = YearMonth.October;
            const YearQuarter startQuarter = YearQuarter.Third;
            Years             years        = new Years(startYear, yearCount, TimeCalendar.New(startMonth));

            ITimePeriodCollection quarters = years.GetQuarters();

            Assert.AreNotEqual(quarters, null);

            int index = 0;

            foreach (Quarter quarter in quarters)
            {
                int quarterYear = startYear + ((index + (int)startQuarter) / TimeSpec.QuartersPerYear);
                Assert.AreEqual(quarter.Year, quarterYear);
                Assert.AreEqual(quarter.Start, years.Start.AddMonths(index * TimeSpec.MonthsPerQuarter));
                Assert.AreEqual(quarter.End, quarter.Calendar.MapEnd(quarter.Start.AddMonths(TimeSpec.MonthsPerQuarter)));
                index++;
            }
            Assert.AreEqual(index, yearCount * TimeSpec.QuartersPerYear);
        }         // GetQuartersTest
Пример #4
0
        } // StartPeriodVisit

        // ----------------------------------------------------------------------
        protected void StartPeriodVisit(ITimePeriod period, TContext context = null)
        {
            if (period == null)
            {
                throw new ArgumentNullException("period");
            }
            if (period.IsMoment)
            {
                return;
            }

            OnVisitStart();

            Years years = calendar != null ?
                          new Years(period.Start.Year, period.End.Year - period.Start.Year + 1, calendar) :
                          new Years(period.Start.Year, period.End.Year - period.Start.Year + 1);

            if (OnVisitYears(years, context) && EnterYears(years, context))
            {
                ITimePeriodCollection yearsToVisit = years.GetYears();
                if (seekDirection == SeekDirection.Backward)
                {
                    yearsToVisit.SortByEnd();
                }
                foreach (Year year in yearsToVisit)
                {
                    if (!year.OverlapsWith(period) || OnVisitYear(year, context) == false)
                    {
                        continue;
                    }

                    // months
                    if (EnterMonths(year, context) == false)
                    {
                        continue;
                    }
                    ITimePeriodCollection monthsToVisit = year.GetMonths();
                    if (seekDirection == SeekDirection.Backward)
                    {
                        monthsToVisit.SortByEnd();
                    }
                    foreach (Month month in monthsToVisit)
                    {
                        if (!month.OverlapsWith(period) || OnVisitMonth(month, context) == false)
                        {
                            continue;
                        }

                        // days
                        if (EnterDays(month, context) == false)
                        {
                            continue;
                        }
                        ITimePeriodCollection daysToVisit = month.GetDays();
                        if (seekDirection == SeekDirection.Backward)
                        {
                            daysToVisit.SortByEnd();
                        }
                        foreach (Day day in daysToVisit)
                        {
                            if (!day.OverlapsWith(period) || OnVisitDay(day, context) == false)
                            {
                                continue;
                            }

                            // hours
                            if (EnterHours(day, context) == false)
                            {
                                continue;
                            }
                            ITimePeriodCollection hoursToVisit = day.GetHours();
                            if (seekDirection == SeekDirection.Backward)
                            {
                                hoursToVisit.SortByEnd();
                            }
                            foreach (Hour hour in hoursToVisit)
                            {
                                if (!hour.OverlapsWith(period) || OnVisitHour(hour, context) == false)
                                {
                                    // ReSharper disable RedundantJumpStatement
                                    continue;
                                    // ReSharper restore RedundantJumpStatement
                                }
                            }
                        }
                    }
                }
            }

            OnVisitEnd();
        } // StartPeriodVisit
Пример #5
0
        public void FiscalYearTest()
        {
            DateTime testDate = new DateTime(2008, 11, 18);
            Year     year     = new Year(testDate, TimeCalendar.New(YearMonth.October));

            Assert.Equal(YearMonth.October, year.YearBaseMonth);
            Assert.Equal(2008, year.BaseYear);

            // start & end
            Assert.Equal(year.Start.Year, testDate.Year);
            Assert.Equal(10, year.Start.Month);
            Assert.Equal(1, year.Start.Day);
            Assert.Equal(year.End.Year, testDate.Year + 1);
            Assert.Equal(9, year.End.Month);
            Assert.Equal(30, year.End.Day);

            // half years
            ITimePeriodCollection halfyears = year.GetHalfyears();

            foreach (Halfyear halfyear in halfyears)
            {
                switch (halfyear.YearHalfyear)
                {
                case YearHalfyear.First:
                    Assert.Equal(halfyear.Start, year.Start);
                    Assert.Equal(halfyear.Start.Year, testDate.Year);
                    Assert.Equal(10, halfyear.Start.Month);
                    Assert.Equal(1, halfyear.Start.Day);
                    Assert.Equal(halfyear.End.Year, testDate.Year + 1);
                    Assert.Equal(3, halfyear.End.Month);
                    Assert.Equal(31, halfyear.End.Day);
                    break;

                case YearHalfyear.Second:
                    Assert.Equal(halfyear.End, year.End);
                    Assert.Equal(halfyear.Start.Year, testDate.Year + 1);
                    Assert.Equal(4, halfyear.Start.Month);
                    Assert.Equal(1, halfyear.Start.Day);
                    Assert.Equal(halfyear.End.Year, testDate.Year + 1);
                    Assert.Equal(9, halfyear.End.Month);
                    Assert.Equal(30, halfyear.End.Day);
                    break;
                }
            }

            // half years
            ITimePeriodCollection quarters = year.GetQuarters();

            foreach (Quarter quarter in quarters)
            {
                switch (quarter.YearQuarter)
                {
                case YearQuarter.First:
                    Assert.Equal(quarter.Start, year.Start);
                    Assert.Equal(quarter.Start.Year, testDate.Year);
                    Assert.Equal(10, quarter.Start.Month);
                    Assert.Equal(1, quarter.Start.Day);
                    Assert.Equal(quarter.End.Year, testDate.Year);
                    Assert.Equal(12, quarter.End.Month);
                    Assert.Equal(31, quarter.End.Day);
                    break;

                case YearQuarter.Second:
                    Assert.Equal(quarter.Start.Year, testDate.Year + 1);
                    Assert.Equal(1, quarter.Start.Month);
                    Assert.Equal(1, quarter.Start.Day);
                    Assert.Equal(quarter.End.Year, testDate.Year + 1);
                    Assert.Equal(3, quarter.End.Month);
                    Assert.Equal(31, quarter.End.Day);
                    break;

                case YearQuarter.Third:
                    Assert.Equal(quarter.Start.Year, testDate.Year + 1);
                    Assert.Equal(4, quarter.Start.Month);
                    Assert.Equal(1, quarter.Start.Day);
                    Assert.Equal(quarter.End.Year, testDate.Year + 1);
                    Assert.Equal(6, quarter.End.Month);
                    Assert.Equal(30, quarter.End.Day);
                    break;

                case YearQuarter.Fourth:
                    Assert.Equal(quarter.End, year.End);
                    Assert.Equal(quarter.Start.Year, testDate.Year + 1);
                    Assert.Equal(7, quarter.Start.Month);
                    Assert.Equal(1, quarter.Start.Day);
                    Assert.Equal(quarter.End.Year, testDate.Year + 1);
                    Assert.Equal(9, quarter.End.Month);
                    Assert.Equal(30, quarter.End.Day);
                    break;
                }
            }

            // months
            ITimePeriodCollection months = year.GetMonths();
            int monthIndex = 0;

            foreach (Month month in months)
            {
                switch (monthIndex)
                {
                case 0:
                    Assert.Equal(month.Start, year.Start);
                    break;

                case TimeSpec.MonthsPerYear - 1:
                    Assert.Equal(month.End, year.End);
                    break;
                }

                DateTime startDate = new DateTime(year.BaseYear, year.Start.Month, 1).AddMonths(monthIndex);
                Assert.Equal(month.Start.Year, startDate.Year);
                Assert.Equal(month.Start.Month, startDate.Month);
                Assert.Equal(month.Start.Day, startDate.Day);
                Assert.Equal(month.End.Year, startDate.Year);
                Assert.Equal(month.End.Month, startDate.Month);

                monthIndex++;
            }
        }         // FiscalYearTest
Пример #6
0
        /// <summary>
        /// De-tangles a list of overlapping Verbrauch entries where entries can be subsets of other entries.
        /// </summary>
        /// <example>
        /// [---v1---)
        /// [-----v2------)
        /// [---------v3---------)
        /// is transformed into
        /// [--v1---)
        /// ........[-v2--)
        /// ..............[--v3--)
        /// </example>
        /// <param name="input"></param>
        /// <returns></returns>
        public static List <Verbrauch> Detangle(IEnumerable <Verbrauch> input)
        {
            //var filteredInput = KeepShortestSlices(input);
            HashSet <Verbrauch> resultSet = new HashSet <Verbrauch>();
            var groups = input.OrderBy(v => (v.Startdatum, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit)).GroupBy(v => new Tuple <Wertermittlungsverfahren, string, Mengeneinheit>
                                                                                                                           (
                                                                                                                               v.Wertermittlungsverfahren,
                                                                                                                               v.Obiskennzahl,
                                                                                                                               v.Einheit
                                                                                                                           ));

            foreach (var vGroup in groups)
            {
                HashSet <Verbrauch> subResult = new HashSet <Verbrauch>();

                // find pairs (x,y) where x.end == y.start:
                // |----x----|--------y--------|
                //var adjacentVerbrauchs = from x in vGroup join y in vGroup on x.enddatum equals y.startdatum select new { x, y };
                var adjacentVerbrauchs = from x in vGroup join y in vGroup on x.Enddatum equals y.Startdatum select new { x, y };
                foreach (var av in adjacentVerbrauchs)
                {
                    subResult.Add(av.x);
                    subResult.Add(av.y);
                }

                // |----x----|--------y--------|
                // |-------------z-------------|
                // ==> delete z from result where z.start == x.start and z.end == y.end
                //var fullyRedundantVerbrauchs = from av in adjacentVerbrauchs join z in vGroup on new { av.x.startdatum, av.y.enddatum } equals new { z.startdatum, z.enddatum } select new { av, z };
                var fullyRedundantVerbrauchs = from av in adjacentVerbrauchs join z in vGroup on new { av.x.Startdatum, av.y.Enddatum } equals new { z.Startdatum, z.Enddatum } select new { av, z };
                foreach (var frv in fullyRedundantVerbrauchs)
                {
                    if (frv.av.x.Wert + frv.av.y.Wert != frv.z.Wert)
                    {
                        throw new ArgumentException($"Inconsistent data detected: {JsonConvert.SerializeObject(frv.av.x)} + {JsonConvert.SerializeObject(frv.av.y)} ≠ {JsonConvert.SerializeObject(frv.z)}");
                    }
                    subResult.Remove(frv.z);
                }

                // |----------x----------|---y---|
                // |---------------z-------------|
                // or
                // |---y---|----------x----------|
                // |---------------z-------------|
                // or
                // |---x1--|-----y------|---x2---|
                // |--------------z--------------|
                // y and z are given. find x such that x.value == y.value+z.value
                //subResult.UnionWith(vGroup);
                subResult.UnionWith(vGroup);
                foreach (Verbrauch z in new HashSet <Verbrauch>(subResult))
                {
                    var ys = subResult.Where(y => z.Contains(y) && !z.Equals(y));
                    if (ys.Count() > 0)
                    {
                        TimePeriodSubtractor <TimeRange> tps    = new TimePeriodSubtractor <TimeRange>();
                        TimePeriodCollection             source = new TimePeriodCollection {
                            z.GetTimeRange()
                        };
                        TimePeriodCollection subtract = new TimePeriodCollection();
                        subtract.AddAll(ys.Select(y => y.GetTimeRange()));
                        ITimePeriodCollection subtractionResult = tps.SubtractPeriods(source, subtract);
                        var xs = new HashSet <Verbrauch>();
                        foreach (var tr in subtractionResult)
                        {
                            Verbrauch v = new Verbrauch()
                            {
                                Einheit = z.Einheit,
                                Wertermittlungsverfahren = z.Wertermittlungsverfahren,
                                Obiskennzahl             = z.Obiskennzahl,
                                Startdatum = tr.Start,
                                Enddatum   = tr.End
                            };
                            xs.Add(v);
                        }
                        var totalXWert     = z.Wert - ys.Select(y => y.Wert).Sum();
                        var totalXDuration = xs.Select(x => x.GetDuration().TotalSeconds).Sum();
                        foreach (var x in xs)
                        {
                            x.Wert = (totalXWert * (decimal)x.GetDuration().TotalSeconds) / ((decimal)totalXDuration);
                        }
                        subResult.Remove(z);
                        subResult.UnionWith(xs);
                    }
                }
                resultSet.UnionWith(subResult);
            }
            List <Verbrauch> result = new List <Verbrauch>(resultSet);

            result.Sort(new VerbrauchDateTimeComparer());
            return(result);
        }
        }         // PeriodMapper

        // ----------------------------------------------------------------------
        public virtual ITimePeriodCollection SubtractPeriods(ITimePeriodContainer sourcePeriods, ITimePeriodCollection subtractingPeriods,
                                                             bool combinePeriods = true)
        {
            if (sourcePeriods == null)
            {
                throw new ArgumentNullException("sourcePeriods");
            }
            if (subtractingPeriods == null)
            {
                throw new ArgumentNullException("subtractingPeriods");
            }

            if (sourcePeriods.Count == 0)
            {
                return(new TimePeriodCollection());
            }

            if (subtractingPeriods.Count == 0 && !combinePeriods)
            {
                return(new TimePeriodCollection(sourcePeriods));
            }

            // combined source periods
            sourcePeriods = timePeriodCombiner.CombinePeriods(sourcePeriods);

            // combined subtracting periods
            if (subtractingPeriods.Count == 0)
            {
                return(new TimePeriodCollection(sourcePeriods));
            }
            subtractingPeriods = timePeriodCombiner.CombinePeriods(subtractingPeriods);

            // invert subtracting periods
            sourcePeriods.AddAll(timeGapCalculator.GetGaps(subtractingPeriods, new TimeRange(sourcePeriods.Start, sourcePeriods.End)));

            return(timePeriodIntersector.IntersectPeriods(sourcePeriods, combinePeriods));
        }         // SubtractPeriods
Пример #8
0
        private ITimePeriodCollection CombinePeriods(ITimePeriodCollection periods)
        {
            var periodCombiner = new TimePeriodCombiner <TimeRange>();

            return(periodCombiner.CombinePeriods(periods));
        }
Пример #9
0
        // ----------------------------------------------------------------------
        public double NetworkDays( DateTime start, DateTime end, IEnumerable<DateTime> holidays = null, ITimePeriodCollection holidayPeriods = null )
        {
            Day startDay = new Day( start < end ? start : end );
            Day endDay = new Day( end > start ? end : start );
            if ( startDay.Equals( endDay ) )
            {
                return 0;
            }

            CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
            filter.AddWorkingWeekDays(); // only working days
            if ( holidays != null )
            {
                foreach ( DateTime holiday in holidays )
                {
                    filter.ExcludePeriods.Add( new Day( holiday ) );
                }
            }
            if ( holidayPeriods != null )
            {
                filter.ExcludePeriods.AddAll( holidayPeriods );
            }

            CalendarTimeRange testPeriod = new CalendarTimeRange( start, end );
            CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, testPeriod );
            collector.CollectDays();

            double networkDays = 0.0;
            foreach ( ICalendarTimeRange period in collector.Periods )
            {
                networkDays += Math.Round( period.Duration.TotalDays, 2 );
            }
            return networkDays;
        }
Пример #10
0
        // ----------------------------------------------------------------------
        public TimeSpan CalcWorkingPeriod( DateTime start, DateTime end,
            ITimePeriodCollection excludePeriods = null)
        {
            if ( start.Equals( end ) )
            {
                return TimeSpan.Zero;
            }

            // test range
            TimeRange testRange = new TimeRange( start, end );

            // search range
            DateTime searchStart = new Day( testRange.Start ).Start;
            DateTime serachEnd = new Day( testRange.End ).GetNextDay().Start;
            TimeRange searchPeriod = new TimeRange( searchStart, serachEnd );

            // search filter
            CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
            filter.AddWorkingWeekDays(); // working days
            if ( excludePeriods != null )
            {
                filter.ExcludePeriods.AddAll( excludePeriods );
            }
            filter.CollectingHours.Add( new HourRange( 07, 12 ) ); // working hours
            filter.CollectingHours.Add( new HourRange( 13, 19 ) ); // working hours

            // collect working hours
            TimeCalendar calendar = new TimeCalendar( new TimeCalendarConfig { EndOffset = TimeSpan.Zero } );
            CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, searchPeriod, SeekDirection.Forward, calendar );
            collector.CollectHours();

            TimeSpan workingPeriod = new TimeSpan();
            foreach ( ICalendarTimeRange period in collector.Periods )
            {
                // get the intersection of the test-range and the day working-hours
                ITimePeriod intersection = testRange.GetIntersection( period );
                if ( intersection == null )
                {
                    continue;
                }
                workingPeriod = workingPeriod.Add( intersection.Duration );
            }
            return workingPeriod;
        }
Пример #11
0
        // ----------------------------------------------------------------------
        public double CalculateBusinessHours( CalendarTimeRange testPeriod, ITimePeriodCollection holidays = null )
        {
            CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
            filter.CollectingMonths.Add( new MonthRange( YearMonth.January, YearMonth.January ) );
            filter.CollectingDays.Add( new DayRange( 1, 1 ) );
            filter.AddWorkingWeekDays(); // only working days
            filter.CollectingHours.Add( new HourRange( 8, 12 ) );  // opening hours morning
            filter.CollectingHours.Add( new HourRange( 13, 18 ) ); // opening hours afternoon
            if ( holidays != null )
            {
                filter.ExcludePeriods.AddAll( holidays );
            }

            CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, testPeriod );
            collector.CollectHours();

            double businessHours = 0.0;
            foreach ( ICalendarTimeRange period in collector.Periods )
            {
                businessHours += Math.Round( period.Duration.TotalHours, 2 );
            }
            return businessHours;
        }
Пример #12
0
        // ----------------------------------------------------------------------
        private ITimePeriod GetCommonIntersection( ITimePeriodCollection periods )
        {
            if ( periods.Count == 0 )
            {
                return null;
            }

            ITimeRange timeRange = new TimeRange( periods[ 0 ] );
            if ( periods.Count > 1 )
            {
                for ( int i = 1; i < periods.Count; i++ )
                {
                    timeRange = timeRange.GetIntersection( periods[ i ] );
                    if ( timeRange == null )
                    {
                        return null;
                    }
                }
            }

            return timeRange;
        }