예제 #1
0
 /// <summary>
 /// Test if the time ranges [startdatum, enddatum) overlap.
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <returns>true iff [<paramref name="v1"/>.startdatum, <paramref name="v1"/>.enddatum) and [<paramref name="v2"/>.startdatum, <paramref name="v2"/>.enddatum) overlap</returns>
 public static bool OverlapsWith(this Verbrauch v1, Verbrauch v2)
 {
     return(v1.OverlapsWith(new TimeRange(v2.Startdatum, v2.Enddatum, true)));
 }
예제 #2
0
 public static bool Contains(this Verbrauch v1, Verbrauch v2)
 {
     return(v1.OverlapsWith(v2) && v1.Startdatum <= v2.Startdatum && v1.Enddatum >= v2.Enddatum);
 }
예제 #3
0
        public static HashSet <Verbrauch> Merge(this Verbrauch v1, Verbrauch v2, bool redundant, Boolean biased)
        {
            HashSet <Verbrauch> result = new HashSet <Verbrauch>();

            if (v1.Obiskennzahl == v2.Obiskennzahl && v1.Wertermittlungsverfahren == v2.Wertermittlungsverfahren && v1.Einheit == v2.Einheit)
            {
                if (v1.OverlapsWith(v2))
                {
                    // don't wanna deal with time running backwards.
                    //Debug.Assert(v1.enddatum >= v1.startdatum);
                    //Debug.Assert(v2.enddatum >= v2.startdatum);
                    TimeRange  tr1     = new TimeRange(v1.Startdatum, v1.Enddatum);
                    TimeRange  tr2     = new TimeRange(v2.Startdatum, v2.Enddatum);
                    ITimeRange overlap = v1.GetIntersection(v2);
                    if (v1.Einheit.IsExtensive())
                    {
                        Verbrauch vmerge = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren
                        };
                        if (redundant)
                        {
                            decimal exclusiveV1Wert = (decimal)(tr1.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v1.Wert / ((decimal)tr1.Duration.TotalSeconds);
                            decimal exclusiveV2Wert = (decimal)(tr2.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v2.Wert / ((decimal)tr2.Duration.TotalSeconds);
                            decimal overlapV1Wert   = ((decimal)overlap.Duration.TotalSeconds * v1.Wert) / (decimal)(tr1.Duration.TotalSeconds);
                            decimal overlapV2Wert   = ((decimal)overlap.Duration.TotalSeconds * v2.Wert) / (decimal)(tr2.Duration.TotalSeconds);
                            if (biased == true)
                            {
                                // biased ==> assume that v2 is contained in v1
                                vmerge.Startdatum = v1.Startdatum;
                                vmerge.Enddatum   = v1.Enddatum;
                                if (exclusiveV1Wert == 0.0M && exclusiveV2Wert == 0.0M && overlapV1Wert == overlapV2Wert)
                                {
                                    vmerge.Wert = overlapV1Wert;
                                }
                                else
                                {
                                    vmerge.Wert = v1.Wert - overlapV2Wert; // overlapV1Wert;
                                }
                            }
                            else if (biased == false)
                            {
                                vmerge.Startdatum = v1.Startdatum;
                                vmerge.Enddatum   = v2.Startdatum;
                                vmerge.Wert       = v1.Wert - overlapV2Wert;
                            }
                            else // biased null
                            {
                                vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                                vmerge.Enddatum   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                                if (overlapV1Wert != overlapV2Wert)
                                {
                                    throw new ArgumentException("The inequality is unsolvable.");
                                }
                                vmerge.Wert = exclusiveV1Wert + overlapV1Wert + exclusiveV2Wert;
                            }
                        }
                        else
                        {
                            vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                            vmerge.Enddatum   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                            vmerge.Wert       = v1.Wert + v2.Wert;
                        }
                        result.Add(vmerge);
                    }
                    else
                    {
                        Verbrauch vmerge1 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum,
                            Enddatum                 = overlap.Start,
                            Wert = v1.Startdatum < v2.Startdatum ? v1.Wert : v2.Wert
                        };
                        Verbrauch vmerge2 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = overlap.Start,
                            Enddatum                 = overlap.End
                        };
                        if (redundant)
                        {
                            if (v1.Wert != v2.Wert)
                            {
                                throw new ArgumentException($"Data cannot be redundant if values ({v1.Wert}{v1.Einheit} vs. {v2.Wert}{v2.Einheit}) don't match for interval [{vmerge2.Startdatum}, {vmerge2.Enddatum}).");
                            }
                            vmerge2.Wert = v1.Wert;
                        }
                        else
                        {
                            vmerge2.Wert = v1.Wert + v2.Wert;
                        }
                        Verbrauch vmerge3 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = overlap.End,
                            Enddatum                 = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum,
                            Wert = v1.Enddatum > v2.Enddatum ? v1.Wert : v2.Wert
                        };
                        result.Add(vmerge1);
                        result.Add(vmerge2);
                        result.Add(vmerge3);
                    }
                }
                else if (v1.Startdatum == v2.Enddatum || v2.Startdatum == v1.Enddatum)
                {
                    DateTime  start  = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                    DateTime  stop   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                    Verbrauch vmerge = new Verbrauch()
                    {
                        Obiskennzahl             = v1.Obiskennzahl,
                        Einheit                  = v1.Einheit,
                        Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                        Startdatum               = start,
                        Enddatum                 = stop
                    };
                    if (v1.Einheit.IsExtensive())
                    {
                        vmerge.Wert = v1.Wert + v2.Wert;
                        result.Add(vmerge);
                    }
                    else if (v1.Wert == v2.Wert) // implicitly intensive
                    {
                        vmerge.Wert = v1.Wert;
                        result.Add(vmerge);
                    }
                    else
                    {
                        // merging intensive verbrauch with different values is not possible.
                        result.Add(v1);
                        result.Add(v2);
                    }
                }
                else
                {
                    // laaaangweilig ;)
                    result.Add(v1);
                    result.Add(v2);
                }
            }
            else
            {
                // laaaangweilig ;)
                result.Add(v1);
                result.Add(v2);
            }
            result.RemoveWhere(v => v.Einheit.IsIntensive() && new TimeRange(v.Startdatum, v.Enddatum).Duration.TotalMilliseconds == 0);
            return(result);
        }