2 * System.DateTimeOffset.cs
5 * Stephane Delcroix <stephane@delcroix.org>
6 * Marek Safar (marek.safar@gmail.com)
8 * Copyright (C) 2007 Novell, Inc (http://www.novell.com)
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Globalization;
32 using System.Runtime.InteropServices;
33 using System.Runtime.Serialization;
39 [StructLayout (LayoutKind.Auto)]
40 public struct DateTimeOffset : IComparable, IFormattable, ISerializable, IDeserializationCallback, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
43 static DateTimeOffset () {
44 if (MonoTouchAOTHelper.FalseFlag) {
45 var comparer = new System.Collections.Generic.GenericComparer <DateTimeOffset> ();
46 var eqcomparer = new System.Collections.Generic.GenericEqualityComparer <DateTimeOffset> ();
50 public static readonly DateTimeOffset MaxValue = new DateTimeOffset (DateTime.MaxValue, TimeSpan.Zero);
51 public static readonly DateTimeOffset MinValue = new DateTimeOffset (DateTime.MinValue, TimeSpan.Zero);
56 public DateTimeOffset (DateTime dateTime)
60 if (dateTime.Kind == DateTimeKind.Utc)
61 utc_offset = TimeSpan.Zero;
63 utc_offset = TimeZone.CurrentTimeZone.GetUtcOffset (dateTime);
65 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
66 throw new ArgumentOutOfRangeException ("The UTC date and time that results from applying the offset is earlier than MinValue or later than MaxValue.");
70 public DateTimeOffset (DateTime dateTime, TimeSpan offset)
72 if (dateTime.Kind == DateTimeKind.Utc && offset != TimeSpan.Zero)
73 throw new ArgumentException ("dateTime.Kind equals Utc and offset does not equal zero.");
75 if (dateTime.Kind == DateTimeKind.Local && offset != TimeZone.CurrentTimeZone.GetUtcOffset (dateTime))
76 throw new ArgumentException ("dateTime.Kind equals Local and offset does not equal the offset of the system's local time zone.");
78 if (offset.Ticks % TimeSpan.TicksPerMinute != 0)
79 throw new ArgumentException ("offset is not specified in whole minutes.");
81 if (offset < new TimeSpan (-14, 0 ,0) || offset > new TimeSpan (14, 0, 0))
82 throw new ArgumentOutOfRangeException ("offset is less than -14 hours or greater than 14 hours.");
87 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
88 throw new ArgumentOutOfRangeException ("The UtcDateTime property is earlier than MinValue or later than MaxValue.");
91 public DateTimeOffset (long ticks, TimeSpan offset) : this (new DateTime (ticks), offset)
95 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, TimeSpan offset) :
96 this (new DateTime (year, month, day, hour, minute, second), offset)
100 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset) :
101 this (new DateTime (year, month, day, hour, minute, second, millisecond), offset)
105 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset) :
106 this (new DateTime (year, month, day, hour, minute, second, millisecond, calendar), offset)
110 public DateTimeOffset Add (TimeSpan timeSpan)
112 return new DateTimeOffset (dt.Add (timeSpan).Ticks, utc_offset);
115 public DateTimeOffset AddDays (double days)
117 return new DateTimeOffset (dt.AddDays (days).Ticks, utc_offset);
120 public DateTimeOffset AddHours (double hours)
122 return new DateTimeOffset (dt.AddHours (hours).Ticks, utc_offset);
125 public static DateTimeOffset operator + (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
127 return dateTimeTz.Add (timeSpan);
130 public DateTimeOffset AddMilliseconds (double milliseconds)
132 return new DateTimeOffset (dt.AddMilliseconds (milliseconds).Ticks, utc_offset);
135 public DateTimeOffset AddMinutes (double minutes)
137 return new DateTimeOffset (dt.AddMinutes (minutes).Ticks, utc_offset);
140 public DateTimeOffset AddMonths (int months)
142 return new DateTimeOffset (dt.AddMonths (months).Ticks, utc_offset);
145 public DateTimeOffset AddSeconds (double seconds)
147 return new DateTimeOffset (dt.AddSeconds (seconds).Ticks, utc_offset);
150 public DateTimeOffset AddTicks (long ticks)
152 return new DateTimeOffset (dt.AddTicks (ticks).Ticks, utc_offset);
155 public DateTimeOffset AddYears (int years)
157 return new DateTimeOffset (dt.AddYears (years).Ticks, utc_offset);
160 public static int Compare (DateTimeOffset first, DateTimeOffset second)
162 return first.CompareTo (second);
165 public int CompareTo (DateTimeOffset other)
167 return UtcDateTime.CompareTo (other.UtcDateTime);
170 int IComparable.CompareTo (object obj)
172 return CompareTo ((DateTimeOffset) obj);
175 public static bool operator == (DateTimeOffset left, DateTimeOffset right)
177 return left.Equals (right);
180 public bool Equals (DateTimeOffset other)
182 return UtcDateTime == other.UtcDateTime;
185 public override bool Equals (object obj)
187 if (obj is DateTimeOffset)
188 return UtcDateTime == ((DateTimeOffset) obj).UtcDateTime;
192 public static bool Equals (DateTimeOffset first, DateTimeOffset second)
194 return first.Equals (second);
197 public bool EqualsExact (DateTimeOffset other)
199 return dt == other.dt && utc_offset == other.utc_offset;
202 public static DateTimeOffset FromFileTime (long fileTime)
204 if (fileTime < 0 || fileTime > MaxValue.Ticks)
205 throw new ArgumentOutOfRangeException ("fileTime is less than zero or greater than DateTimeOffset.MaxValue.Ticks.");
207 return new DateTimeOffset (DateTime.FromFileTime (fileTime), TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.FromFileTime (fileTime)));
211 public override int GetHashCode ()
213 return dt.GetHashCode () ^ utc_offset.GetHashCode ();
216 [System.Security.Permissions.SecurityPermission (System.Security.Permissions.SecurityAction.LinkDemand, SerializationFormatter = true)]
217 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
220 throw new ArgumentNullException ("info");
221 // An example SOAP serialization on MSFT is the following, so field
222 // names "DateTime" and "OffsetMinutes":
223 // <SOAP-ENV:Envelope ...>
225 // <a1:DateTimeOffset id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/ns/System">
226 // <DateTime xsi:type="xsd:dateTime">2007-01-02T12:30:50.0000000+00:00</DateTime>
227 // <OffsetMinutes>0</OffsetMinutes>
228 // </a1:DateTimeOffset>
230 // </SOAP-ENV:Envelope>
231 DateTime dt0 = new DateTime (dt.Ticks).Subtract (utc_offset);
232 info.AddValue ("DateTime", dt0);
233 // MSFT BinaryFormatter output contains primitive code 6, i.e. Int16.
234 info.AddValue ("OffsetMinutes", (Int16)utc_offset.TotalMinutes);
237 [System.Security.Permissions.SecurityPermission (System.Security.Permissions.SecurityAction.LinkDemand, SerializationFormatter = true)]
238 private DateTimeOffset(SerializationInfo info, StreamingContext context)
240 DateTime dt0 = (DateTime)info.GetValue ("DateTime", typeof(DateTime));
241 Int16 totalMinutes = info.GetInt16 ("OffsetMinutes");
242 utc_offset = TimeSpan.FromMinutes(totalMinutes);
243 dt = dt0.Add(utc_offset);
246 public static bool operator > (DateTimeOffset left, DateTimeOffset right)
248 return left.UtcDateTime > right.UtcDateTime;
251 public static bool operator >= (DateTimeOffset left, DateTimeOffset right)
253 return left.UtcDateTime >= right.UtcDateTime;
256 public static implicit operator DateTimeOffset (DateTime dateTime)
258 return new DateTimeOffset (dateTime);
261 public static bool operator != (DateTimeOffset left, DateTimeOffset right)
263 return left.UtcDateTime != right.UtcDateTime;
266 public static bool operator < (DateTimeOffset left, DateTimeOffset right)
268 return left.UtcDateTime < right.UtcDateTime;
271 public static bool operator <= (DateTimeOffset left, DateTimeOffset right)
273 return left.UtcDateTime <= right.UtcDateTime;
277 void IDeserializationCallback.OnDeserialization (object sender)
281 public static DateTimeOffset Parse (string input)
283 return Parse (input, null);
286 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider)
288 return Parse (input, formatProvider, DateTimeStyles.AllowWhiteSpaces);
291 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider, DateTimeStyles styles)
294 throw new ArgumentNullException ("input");
298 Exception exception = null;
299 if (!DateTime.CoreParse (input, formatProvider, styles, out d, out dto, true, ref exception))
302 if (d.Ticks != 0 && dto.Ticks == 0)
303 throw new ArgumentOutOfRangeException ("The UTC representation falls outside the 1-9999 year range");
308 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider)
310 return ParseExact (input, format, formatProvider, DateTimeStyles.AssumeLocal);
313 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
316 throw new ArgumentNullException ("format");
318 if (format == String.Empty)
319 throw new FormatException ("format is an empty string");
321 return ParseExact (input, new string [] {format}, formatProvider, styles);
324 public static DateTimeOffset ParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
327 throw new ArgumentNullException ("input");
329 if (input == String.Empty)
330 throw new FormatException ("input is an empty string");
333 throw new ArgumentNullException ("formats");
335 if (formats.Length == 0)
336 throw new FormatException ("Invalid format specifier");
338 if ((styles & DateTimeStyles.AssumeLocal) != 0 && (styles & DateTimeStyles.AssumeUniversal) != 0)
339 throw new ArgumentException ("styles parameter contains incompatible flags");
341 DateTimeOffset result;
342 if (!ParseExact (input, formats, DateTimeFormatInfo.GetInstance (formatProvider), styles, out result))
343 throw new FormatException ("Invalid format string");
348 private static bool ParseExact (string input, string [] formats,
349 DateTimeFormatInfo dfi, DateTimeStyles styles, out DateTimeOffset ret)
351 foreach (string format in formats)
353 if (format == null || format == String.Empty)
354 throw new FormatException ("Invalid format string");
356 DateTimeOffset result;
357 if (DoParse (input, format, false, out result, dfi, styles)) {
362 ret = DateTimeOffset.MinValue;
366 private static bool DoParse (string input,
369 out DateTimeOffset result,
370 DateTimeFormatInfo dfi,
371 DateTimeStyles styles)
373 if ((styles & DateTimeStyles.AllowLeadingWhite) != 0) {
374 format = format.TrimStart (null);
375 input = input.TrimStart (null);
378 if ((styles & DateTimeStyles.AllowTrailingWhite) != 0) {
379 format = format.TrimEnd (null);
380 input = input.TrimEnd (null);
383 bool allow_white_spaces = false;
384 if ((styles & DateTimeStyles.AllowInnerWhite) != 0)
385 allow_white_spaces = true;
387 bool useutc = false, use_invariants = false;
388 if (format.Length == 1)
389 format = DateTimeUtils.GetStandardPattern (format[0], dfi, out useutc, out use_invariants, true);
394 int partial_hour = -1; // for 'hh tt' formats
398 double fraction = -1;
400 TimeSpan offset = TimeSpan.MinValue;
402 result = DateTimeOffset.MinValue;
404 int fi = 0; //format iterator
405 int ii = 0; //input iterator
406 while (fi < format.Length) {
408 char ch = format [fi];
412 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
413 if (day != -1 || tokLen > 4)
417 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out day);
419 ii += ParseEnum (input, ii, tokLen == 3 ? dfi.AbbreviatedDayNames : dfi.DayNames, allow_white_spaces, out temp_int);
422 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
423 ii += ParseNumber (input, ii, tokLen, true, allow_white_spaces, out temp_int);
424 if (fraction >= 0 || tokLen > 7 || temp_int == -1)
426 fraction = (double)temp_int / Math.Pow (10, tokLen);
429 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
431 int read = ParseNumber (input, ii, tokLen, true, allow_white_spaces, out temp_int, out digits);
433 ii += ParseNumber (input, ii, digits, true, allow_white_spaces, out temp_int);
436 if (fraction >= 0 || tokLen > 7 || temp_int == -1)
438 fraction = (double)temp_int / Math.Pow (10, digits);
441 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
442 if (hour != -1 || tokLen > 2)
445 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out temp_int);
449 if (partial_hour == -1)
450 partial_hour = temp_int;
452 hour = partial_hour + temp_int;
455 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
456 if (hour != -1 || tokLen > 2)
459 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out hour);
462 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
463 if (minute != -1 || tokLen > 2)
466 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out minute);
469 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
470 if (month != -1 || tokLen > 4)
474 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out month);
476 ii += ParseEnum (input, ii, tokLen == 3 ? dfi.AbbreviatedMonthNames : dfi.MonthNames, allow_white_spaces, out month);
482 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
483 if (second != -1 || tokLen > 2)
485 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out second);
488 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
489 if (hour != -1 || tokLen > 2)
492 ii += ParseEnum (input, ii,
493 tokLen == 1 ? new string[] {new string (dfi.AMDesignator[0], 1), new string (dfi.PMDesignator[0], 0)}
494 : new string[] {dfi.AMDesignator, dfi.PMDesignator},
495 allow_white_spaces, out temp_int);
499 if (partial_hour == -1)
500 partial_hour = temp_int * 12;
502 hour = partial_hour + temp_int * 12;
508 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
510 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out year);
512 year += DateTime.Now.Year - DateTime.Now.Year % 100;
513 } else if (tokLen <= 4) { // yyy and yyyy accept up to 5 digits with leading 0
515 ii += ParseNumber (input, ii, 5, false, allow_white_spaces, out year, out digit_parsed);
516 if (digit_parsed < tokLen || (digit_parsed > tokLen && (year / Math.Pow (10, digit_parsed - 1) < 1)))
519 ii += ParseNumber (input, ii, tokLen, true, allow_white_spaces, out year);
522 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
523 if (offset != TimeSpan.MinValue || tokLen > 3)
526 int off_h, off_m = 0, sign;
528 ii += ParseEnum (input, ii, new string [] {"-", "+"}, allow_white_spaces, out sign);
529 ii += ParseNumber (input, ii, 2, tokLen != 1, false, out off_h);
531 ii += ParseEnum (input, ii, new string [] {dfi.TimeSeparator}, false, out temp_int);
532 ii += ParseNumber (input, ii, 2, true, false, out off_m);
534 if (off_h == -1 || off_m == -1 || sign == -1)
539 offset = new TimeSpan (sign * off_h, sign * off_m, 0);
543 ii += ParseEnum (input, ii, new string [] {dfi.TimeSeparator}, false, out temp_int);
549 ii += ParseEnum (input, ii, new string [] {dfi.DateSeparator}, false, out temp_int);
560 ii += ParseChar (input, ii, ' ', false, out temp_int);
566 ii += ParseChar (input, ii, format [fi + 1], allow_white_spaces, out temp_int);
571 //Console.WriteLine ("un-parsed character: {0}", ch);
573 ii += ParseChar (input, ii, format [fi], allow_white_spaces, out temp_int);
581 //Console.WriteLine ("{0}-{1}-{2} {3}:{4} {5}", year, month, day, hour, minute, offset);
582 if (offset == TimeSpan.MinValue && (styles & DateTimeStyles.AssumeLocal) != 0)
583 offset = TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.Now);
585 if (offset == TimeSpan.MinValue && (styles & DateTimeStyles.AssumeUniversal) != 0)
586 offset = TimeSpan.Zero;
588 if (hour < 0) hour = 0;
589 if (minute < 0) minute = 0;
590 if (second < 0) second = 0;
591 if (fraction < 0) fraction = 0;
592 if (year > 0 && month > 0 && day > 0) {
593 result = new DateTimeOffset (year, month, day, hour, minute, second, 0, offset);
594 result = result.AddSeconds (fraction);
595 if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
596 result = result.ToUniversalTime ();
603 private static int ParseNumber (string input, int pos, int digits, bool leading_zero, bool allow_leading_white, out int result)
606 return ParseNumber (input, pos, digits, leading_zero, allow_leading_white, out result, out digit_parsed);
609 private static int ParseNumber (string input, int pos, int digits, bool leading_zero, bool allow_leading_white, out int result, out int digit_parsed)
614 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++)
617 for (; pos < input.Length && Char.IsDigit (input[pos]) && digits > 0; pos ++, char_parsed++, digit_parsed++, digits --)
618 result = 10 * result + (byte) (input[pos] - '0');
620 if (leading_zero && digits > 0)
623 if (digit_parsed == 0)
629 private static int ParseEnum (string input, int pos, string [] enums, bool allow_leading_white, out int result)
633 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++)
636 for (int i = 0; i < enums.Length; i++)
637 if (input.Substring(pos).StartsWith (enums [i])) {
643 char_parsed += enums[result].Length;
648 private static int ParseChar (string input, int pos, char c, bool allow_leading_white, out int result)
652 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++, char_parsed++)
655 if (pos < input.Length && input[pos] == c){
663 public TimeSpan Subtract (DateTimeOffset value)
665 return UtcDateTime - value.UtcDateTime;
668 public DateTimeOffset Subtract (TimeSpan value)
673 public static TimeSpan operator - (DateTimeOffset left, DateTimeOffset right)
675 return left.Subtract (right);
678 public static DateTimeOffset operator - (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
680 return dateTimeTz.Subtract (timeSpan);
683 public long ToFileTime ()
685 return UtcDateTime.ToFileTime ();
688 public DateTimeOffset ToLocalTime ()
690 return new DateTimeOffset (UtcDateTime.ToLocalTime (), TimeZone.CurrentTimeZone.GetUtcOffset (UtcDateTime.ToLocalTime ()));
693 public DateTimeOffset ToOffset (TimeSpan offset)
695 return new DateTimeOffset (dt - utc_offset + offset, offset);
698 public override string ToString ()
700 return ToString (null, null);
703 public string ToString (IFormatProvider formatProvider)
705 return ToString (null, formatProvider);
708 public string ToString (string format)
710 return ToString (format, null);
713 public string ToString (string format, IFormatProvider formatProvider)
715 DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance(formatProvider);
717 if (format == null || format == String.Empty)
718 format = dfi.ShortDatePattern + " " + dfi.LongTimePattern + " zzz";
720 bool to_utc = false, use_invariant = false;
721 if (format.Length == 1) {
722 char fchar = format [0];
724 format = DateTimeUtils.GetStandardPattern (fchar, dfi, out to_utc, out use_invariant, true);
730 throw new FormatException ("format is not one of the format specifier characters defined for DateTimeFormatInfo");
732 return to_utc ? DateTimeUtils.ToString (UtcDateTime, TimeSpan.Zero, format, dfi) : DateTimeUtils.ToString (DateTime, Offset, format, dfi);
735 public DateTimeOffset ToUniversalTime ()
737 return new DateTimeOffset (UtcDateTime, TimeSpan.Zero);
740 public static bool TryParse (string input, out DateTimeOffset result)
743 result = Parse (input);
751 public static bool TryParse (string input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
754 result = Parse (input, formatProvider, styles);
762 public static bool TryParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
765 result = ParseExact (input, format, formatProvider, styles);
773 public static bool TryParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
776 result = ParseExact (input, formats, formatProvider, styles);
784 public DateTime Date {
785 get { return DateTime.SpecifyKind (dt.Date, DateTimeKind.Unspecified); }
788 public DateTime DateTime {
789 get { return DateTime.SpecifyKind (dt, DateTimeKind.Unspecified); }
793 get { return dt.Day; }
796 public DayOfWeek DayOfWeek {
797 get { return dt.DayOfWeek; }
800 public int DayOfYear {
801 get { return dt.DayOfYear; }
805 get { return dt.Hour; }
808 public DateTime LocalDateTime {
809 get { return UtcDateTime.ToLocalTime (); }
812 public int Millisecond {
813 get { return dt.Millisecond; }
817 get { return dt.Minute; }
821 get { return dt.Month; }
824 public static DateTimeOffset Now {
825 get { return new DateTimeOffset (DateTime.Now);}
828 public TimeSpan Offset {
829 get { return utc_offset; }
833 get { return dt.Second; }
837 get { return dt.Ticks; }
840 public TimeSpan TimeOfDay {
841 get { return dt.TimeOfDay; }
844 public DateTime UtcDateTime {
845 get { return DateTime.SpecifyKind (dt - utc_offset, DateTimeKind.Utc); }
848 public static DateTimeOffset UtcNow {
849 get { return new DateTimeOffset (DateTime.UtcNow); }
852 public long UtcTicks {
853 get { return UtcDateTime.Ticks; }
857 get { return dt.Year; }