/// <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); }
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(); }