예제 #1
0
        /// <summary>
        /// Determine if this instance of PQ semantically equals another
        /// instance of a data type.
        /// </summary>
        public override BL SemanticEquals(IAny other)
        {
            // Base equality
            var baseEq = base.SemanticEquals(other);

            if (!(bool)baseEq)
            {
                return(baseEq);
            }

            // Values are equal?
            PQ pqOther = other as PQ;

            if (pqOther == null)
            {
                return(false);
            }
            else if (this.Value.HasValue && pqOther.Value.HasValue)
            {
                return(pqOther.Convert(this.Unit).Value.Value == this.Value.Value);
            }
            else if (this.UncertainRange != null && !this.UncertainRange.IsNull &&
                     pqOther.UncertainRange != null && !pqOther.UncertainRange.IsNull)
            {
                return(this.UncertainRange.Equals(pqOther.UncertainRange));
            }
            return(false);
        }
예제 #2
0
 /// <summary>
 /// Compares this PQ to another PQ
 /// </summary>
 /// <exception cref="T:System.ArgumentException">When the units of both PQ instances do not match</exception>
 public int CompareTo(PQ other)
 {
     if (other == null || other.IsNull)
     {
         return(1);
     }
     else if (this.IsNull && !other.IsNull)
     {
         return(-1);
     }
     else if (this.Value.HasValue && !other.Value.HasValue)
     {
         return(1);
     }
     else if (other.Value.HasValue && !this.Value.HasValue)
     {
         return(-1);
     }
     else if (!other.Value.HasValue && !this.Value.HasValue)
     {
         return(0);
     }
     else if (!this.IsUnitComparable(other.Unit))
     {
         throw new ArgumentException("Units must match to compare PQ");
     }
     else
     {
         return(this.Value.Value.CompareTo(other.Convert(this.Unit).Value.Value));
     }
 }
예제 #3
0
        /// <summary>
        /// Gets the number of days (total) between <paramref name="a"/>
        /// and <paramref name="b"/>
        /// </summary>
        internal static PQ GetLeapDays(TS a, TS b)
        {
            if (a == null || b == null)
            {
                return(null);
            }

            PQ  retVal = new PQ(0, "d");
            TS  low = a, high = b;
            int val = 1;

            if (a.CompareTo(b) > 0)
            {
                low  = b;
                high = a;
                val  = -1;
            }
            for (int i = low.DateValue.Year; i < high.DateValue.Year; i++)
            {
                if (DateTime.IsLeapYear(i))
                {
                    retVal += new PQ(val, "d");
                }
            }
            return(retVal);
        }
예제 #4
0
        /// <summary>
        /// Validate the data type and return the validation errors detected
        /// </summary>
        public override IEnumerable <IResultDetail> ValidateEx()
        {
            List <IResultDetail> retVal = new List <IResultDetail>(base.ValidateEx());

            if (this.Offset != null)
            {
                if (this.Offset.Low != null && !this.Offset.Low.IsNull && !PQ.IsValidTimeFlavor(this.Offset.Low))
                {
                    retVal.Add(new DatatypeValidationResultDetail(ResultDetailType.Error, "EIVL", "When populated, the Offset.Low property must contain a valid PQ.TIME instance", null));
                }
                if (this.Offset.High != null && !this.Offset.High.IsNull && !PQ.IsValidTimeFlavor(this.Offset.High))
                {
                    retVal.Add(new DatatypeValidationResultDetail(ResultDetailType.Error, "EIVL", "When populated, the Offset.High property must contain a valid PQ.TIME instance", null));
                }
                if (this.Offset.Width != null && !this.Offset.Width.IsNull && !PQ.IsValidTimeFlavor(this.Offset.Width))
                {
                    retVal.Add(new DatatypeValidationResultDetail(ResultDetailType.Error, "EIVL", "When populated, the Offset.Width property must contain a valid PQ.TIME instance", null));
                }
                if (this.Offset.Value != null && !this.Offset.Value.IsNull && !PQ.IsValidTimeFlavor(this.Offset.Value))
                {
                    retVal.Add(new DatatypeValidationResultDetail(ResultDetailType.Error, "EIVL", "When populated, the Offset.Value property must contain a valid PQ.TIME instance", null));
                }
            }
            string cc = Util.ToWireFormat(this.Event);

            if (!((cc.StartsWith("IC") || cc.StartsWith("AC") || cc.StartsWith("PC")) ^ (this.Offset != null)))
            {
                retVal.Add(new DatatypeValidationResultDetail(ResultDetailType.Error, "EIVL", "When the Event property implies before, after or between meals the Offset property must not be populated", null));
            }
            return(retVal);
        }
예제 #5
0
        /// <summary>
        /// Translates this IVL by the specified quantity
        /// </summary>
        /// <exception cref="T:System.InvalidOperationException">Thrown when the function cannot determine the
        /// a reliable translation point (ie: either low or high are null)</exception>
        public IVL <T> Translate(PQ translation)
        {
            if (this.IsNull)
            {
                return new IVL <T>()
                       {
                           NullFlavor = this.NullFlavor
                       }
            }
            ;

            // Low and high references
            T low   = this.Low,
              high  = this.High,
              value = this.Value;

            // Is a width specified? If so, then we need a
            // valid low/high to translate
            if (low == null || high == null)
            {
                // Determine if we can calculate bounds
                if (this.Width != null && (low is IPqTranslatable <T> || high is IPqTranslatable <T>))
                {
                    if (low != null)
                    {
                        high = (low as IPqTranslatable <T>).Translate(Width);
                    }
                    else if (high != null)
                    {
                        low = (high as IPqTranslatable <T>).Translate(-Width);
                    }
                }
                else if (value == null)
                {
                    throw new InvalidOperationException("Cannot determine set bounds");
                }
            }

            // Translate
            IPqTranslatable <T> pqLow   = low as IPqTranslatable <T>,
                                pqHigh  = high as IPqTranslatable <T>,
                                pqValue = value as IPqTranslatable <T>;

            low   = low == null ? default(T) : pqLow.Translate(translation);
            high  = pqHigh == null ? default(T) : pqHigh.Translate(translation);
            value = pqValue == null ? default(T) : pqValue.Translate(translation);

            return(new IVL <T>(low, high)
            {
                Value = value, LowClosed = this.LowClosed, HighClosed = this.HighClosed
            });
        }
예제 #6
0
        /// <summary>
        /// Determine if this PQ equals another instance of PQ
        /// </summary>
        public bool Equals(PQ other)
        {
            bool result = false;

            if (other != null)
            {
                result = base.Equals((QTY <Nullable <Decimal> >)other) &&
                         (other.CodingRationale != null ? other.CodingRationale.Equals(this.CodingRationale) : this.CodingRationale == null) &&
                         other.Precision == this.Precision &&
                         (other.Translation != null ? other.Translation.Equals(this.Translation) : this.Translation == null) &&
                         other.Unit == this.Unit;
            }
            return(result);
        }
예제 #7
0
        /// <summary>
        /// Determine if this instance of PIVL contains <paramref name="member"/> according
        /// to the PIVL's definition
        /// </summary>
        /// <remarks>
        /// <para>Please note that the contains method does not adhere to the <see cref="P:Alignment"/> property and
        /// the determination of containment is defined strictly on <see cref="P:Phase"/> and <see cref="P:Period"/>.</para>
        /// <para>The algorithm for determining containment is as follows:</para>
        /// <list type="number">
        ///     <item><description>Distance <paramref name="member"/> from the low bound of <see cref="P:Phase"/></description></item>
        ///     <item><description>Divide the result of the previous operation by <see cref="P:Period"/></description></item>
        ///     <item><description>Round the result of the previous operation to a whole number based on the unit specified in <see cref="P:Period"/></description></item>
        ///     <item><description>Multiply the result of the previous operation by the <see cref="P:Period"/></description></item>
        ///     <item><description>Translate <see cref="P:Phase"/> by the result of the previous operation</description></item>
        ///     <item><description>Determine if <paramref name="member"/> resides in the translated <see cref="P:Phase"/> from the previous operation</description></item>
        /// </list>
        /// </remarks>
        /// <param name="member">The proposed member of the set</param>
        /// <returns>True if the PIVL contains <paramref name="member"/></returns>
        /// <exception cref="T:System.ArgumentException">When the distance between two instances of <typeparamref name="T"/> is not calculable. This occurs when
        /// <typeparamref name="T"/> does not implement <see cref="T:MARC.Everest.DataTypes.Interfaces.IDistanceable{T}"/></exception>
        /// <exception cref="T:System.InvalidOperationException">When the <see cref="P:Phase"/> property is not populated</exception>
        public bool Contains(T member)
        {
            // Algorithm:
            //  phase.translate((int)((member - low) / period) * period)
            //

            if (!(member is IDistanceable <T>))
            {
                throw new ArgumentException("Unable to calculate the distance between objects of specified type", "member");
            }
            if (this.Phase == null)
            {
                throw new InvalidOperationException("Cannot determine containment of a PIVL that is not bound with a Phase");
            }

            var distMemb = member as IDistanceable <T>;
            var period   = this.Period;

            if (period == null && this.Frequency != null) // If frequency is specified, then make period the reciprocal
            {
                period = this.Frequency.Denominator / this.Frequency.Numerator;
            }

            // Get the distance between the target iteration and the phase
            PQ desiredTranslation = distMemb.Distance(this.Phase.Low);

            // Get the desired translation in repeats
            desiredTranslation      /= period;
            desiredTranslation.Value = Math.Round(desiredTranslation.Value.Value, 0);

            if (this.Count != null && this.Count.CompareTo((int)desiredTranslation.Value) > 0) // number of iterations exceeds limit
            {
                return(false);
            }
            else if (desiredTranslation.Value < 0) // Happens before offset, meaning first
            {
                return(false);
            }

            // Correct to periods we need to translate by
            desiredTranslation *= period;

            // Translate phase
            var translatedPhase = this.Phase.Translate(desiredTranslation);

            return(translatedPhase.Contains(member));
        }
예제 #8
0
        /// <summary>
        /// Validate this EIVL
        /// </summary>
        public override bool Validate()
        {
            bool valid = (NullFlavor != null) ^ (Offset != null || Event != null);

            if (this.Offset != null)
            {
                valid &= this.Offset.Low == null || this.Offset.Low.IsNull || PQ.IsValidTimeFlavor(this.Offset.Low);
                valid &= this.Offset.High == null || this.Offset.High.IsNull || PQ.IsValidTimeFlavor(this.Offset.High);
                valid &= this.Offset.Width == null || this.Offset.Width.IsNull || PQ.IsValidTimeFlavor(this.Offset.Width);
                valid &= this.Offset.Value == null || this.Offset.Value.IsNull || PQ.IsValidTimeFlavor(this.Offset.Value);
            }
            string cc = Util.ToWireFormat(this.Event);

            valid &= (cc.StartsWith("IC") || cc.StartsWith("AC") || cc.StartsWith("PC")) ^ (this.Offset != null);

            return(valid);
        }
예제 #9
0
 /// <summary>
 /// Create a new instance of the PIVL type using the phase and period specified
 /// </summary>
 /// <param name="phase">The phase of the PIVL</param>
 /// <param name="period">The period of the PIVL</param>
 /// <param name="count">The maximum number of times the PIVL can repreat</param>
 public PIVL(IVL <T> phase, PQ period, INT count) : this(phase, period)
 {
     this.Count = count;
 }
예제 #10
0
 /// <summary>
 /// Create a new instance of the PIVL type using the phase and period specified
 /// </summary>
 /// <param name="phase">The phase of the PIVL</param>
 /// <param name="period">The period of the PIVL</param>
 public PIVL(IVL <T> phase, PQ period)
 {
     this.Phase = phase; this.Period = period;
 }
예제 #11
0
 /// <summary>
 /// Calculate the distance between this PQ and
 /// another PQ with the same unit of measure
 /// </summary>
 /// <exception cref="T:System.InvalidOperationException">Thrown units of this and <paramref name="other"/> are not comparable</exception>
 public PQ Distance(PQ other)
 {
     return(this - other);
 }
예제 #12
0
 /// <summary>
 /// Scales this PQ by <paramref name="scale"/>
 /// </summary>
 /// <param name="scale">The scale by which this instance should be scaled</param>
 /// <remarks>Results in a new PQ with the result</remarks>
 public PQ Scale(PQ scale)
 {
     return(this * scale);
 }
예제 #13
0
 /// <summary>
 /// Translates this PQ by a factor of <paramref name="translation"/>
 /// by applying the addition operator
 /// </summary>
 /// <param name="translation">The quantity to translate (or shift) this PQ by</param>
 /// <remarks>Results in a new PQ containing the result of the translation</remarks>
 /// <exception cref="T:System.ArgumentException">If the units of the PQ do not match</exception>
 public PQ Translate(PQ translation)
 {
     return(this + translation);
 }
예제 #14
0
 public static bool IsValidTimeFlavor(PQ a)
 {
     return(s_tickMap.ContainsKey(a.Unit));
 }
예제 #15
0
 /// <summary>
 /// Validates that this TS meets the basic validation criteria
 /// </summary>
 /// <remarks>
 /// <para>Basic validation criteria is considered:</para>
 /// <list type="bullet">
 ///     <item><description>If <see cref="P:NullFlavor"/> is not null, then <see cref="P:DateValue"/> and <see cref="P:UncertainRange"/> cannot be set</description></item>
 ///     <item><description>If <see cref="P:DateValue"/> or <see cref="P:UncertainRange"/> are populated, then <see cref="P:NullFlavor"/> cannot be set</description></item>
 ///     <item><description>Both <see cref="P:DateValue"/> and <see cref="P:UncertainRange"/> cannot be set at the same time</description></item>
 ///     <item><description>Any uncertainty (<see cref="P:Uncertainty"/>, or <see cref="P:UncertainRange"/>) must contain valid <see cref="T:PQ"/>.TIME or <see cref="T:IVL`1"/>of PQ.TIME</description></item>
 /// </list>
 /// </remarks>
 public override bool Validate()
 {
     return((NullFlavor != null) ^ ((DateValue != default(DateTime) || UncertainRange != null) &&
                                    ((this.Uncertainty != null && this.Uncertainty is PQ && PQ.IsValidTimeFlavor(this.Uncertainty as PQ)) || (this.Uncertainty == null)) &&
                                    ((this.UncertainRange != null && this.UncertainRange.Low is PQ && this.UncertainRange.High is PQ && PQ.IsValidTimeFlavor(this.UncertainRange.Low as PQ) && PQ.IsValidTimeFlavor(this.UncertainRange.High as PQ)) || this.UncertainRange == null) &&
                                    (((DateValue != default(DateTime)) ^ (this.UncertainRange != null)) || (this.DateValue == null && this.UncertainRange == null))));
 }