/// <summary>
 /// Constructs a DvDateTimeZone from a clock date-time and a time zone offset from UTC.
 /// </summary>
 /// <param name="dt">The clock time</param>
 /// <param name="offset">The offset</param>
 public DvDateTimeZone(DvDateTime dt, DvTimeSpan offset)
 {
     if (dt.IsNA || offset.IsNA || !TryValidateOffset(offset.Ticks, out _offset))
     {
         _dateTime = DvDateTime.NA;
         _offset   = DvInt2.NA;
     }
     else
     {
         _dateTime = ValidateDate(dt, ref _offset);
     }
     AssertValid();
 }
        /// <summary>
        /// Given a number of ticks for the date time portion and a number of minutes for
        /// the time zone offset, this constructs a new DvDateTimeZone. If anything is invalid,
        /// it produces NA.
        /// </summary>
        /// <param name="ticks">The number of clock ticks in the date time portion</param>
        /// <param name="offset">The time zone offset in minutes</param>
        public DvDateTimeZone(DvInt8 ticks, DvInt2 offset)
        {
            var dt = new DvDateTime(ticks);

            if (dt.IsNA || offset.IsNA || MinMinutesOffset > offset.RawValue || offset.RawValue > MaxMinutesOffset)
            {
                _dateTime = DvDateTime.NA;
                _offset   = DvInt2.NA;
            }
            else
            {
                _offset   = offset;
                _dateTime = ValidateDate(dt, ref _offset);
            }
            AssertValid();
        }
        /// <summary>
        /// This method takes a DvDateTime representing clock time, and a TimeSpan representing an offset,
        /// validates that both the clock time and the UTC time (which is the clock time minus the offset)
        /// are within the valid range, and returns a DvDateTime representing the UTC time (dateTime-offset).
        /// </summary>
        /// <param name="dateTime">The clock time</param>
        /// <param name="offset">The offset. This value is assumed to be validated as a legal offset:
        /// a value in whole minutes, between -14 and 14 hours.</param>
        /// <returns>The UTC DvDateTime representing the input clock time minus the offset</returns>
        private static DvDateTime ValidateDate(DvDateTime dateTime, ref DvInt2 offset)
        {
            Contracts.Assert(!dateTime.IsNA);
            Contracts.Assert(!offset.IsNA);

            // Validate that both the UTC and clock times are legal.
            Contracts.Assert(MinMinutesOffset <= offset.RawValue && offset.RawValue <= MaxMinutesOffset);
            var offsetTicks = offset.RawValue * TicksPerMinute;
            // This operation cannot overflow because offset should have already been validated to be within
            // 14 hours and the DateTime instance is more than that distance from the boundaries of Int64.
            long utcTicks = dateTime.Ticks.RawValue - offsetTicks;
            var  dvdt     = new DvDateTime(utcTicks);

            if (dvdt.IsNA)
            {
                offset = DvInt2.NA;
            }
            return(dvdt);
        }
        /// <summary>
        /// This method takes a TimeSpan offset, validates that it is a legal offset for DvDateTimeZone (i.e.
        /// in whole minutes, and between -14 and 14 hours), and returns the offset in number of minutes.
        /// </summary>
        /// <param name="offsetTicks"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        private static bool TryValidateOffset(DvInt8 offsetTicks, out DvInt2 offset)
        {
            if (offsetTicks.IsNA || offsetTicks.RawValue % TicksPerMinute != 0)
            {
                offset = DvInt2.NA;
                return(false);
            }

            long  mins = offsetTicks.RawValue / TicksPerMinute;
            short res  = (short)mins;

            if (res != mins || res > MaxMinutesOffset || res < MinMinutesOffset)
            {
                offset = DvInt2.NA;
                return(false);
            }
            offset = res;
            Contracts.Assert(!offset.IsNA);
            return(true);
        }
示例#5
0
 public void Conv(ref short?src, ref DvInt2 dst) => dst = src ?? DvInt2.NA;
 // This assumes (and asserts) that the dt/offset combination is valid.
 // Callers should do the validation.
 private DvDateTimeZone(DvDateTime dt, DvInt2 offset)
 {
     _dateTime = dt;
     _offset   = offset;
     AssertValid();
 }