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)
9 * Copyright 2012 Xamarin, Inc (http://www.xamarin.com)
11 * Permission is hereby granted, free of charge, to any person obtaining
12 * a copy of this software and associated documentation files (the
13 * "Software"), to deal in the Software without restriction, including
14 * without limitation the rights to use, copy, modify, merge, publish,
15 * distribute, sublicense, and/or sell copies of the Software, and to
16 * permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
19 * The above copyright notice and this permission notice shall be
20 * included in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
33 using System.Runtime.InteropServices;
34 using System.Runtime.Serialization;
40 [StructLayout (LayoutKind.Auto)]
41 public struct DateTimeOffset : IComparable, IFormattable, ISerializable, IDeserializationCallback, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
44 static DateTimeOffset () {
45 if (MonoTouchAOTHelper.FalseFlag) {
46 var comparer = new System.Collections.Generic.GenericComparer <DateTimeOffset> ();
47 var eqcomparer = new System.Collections.Generic.GenericEqualityComparer <DateTimeOffset> ();
51 public static readonly DateTimeOffset MaxValue = new DateTimeOffset (DateTime.MaxValue, TimeSpan.Zero);
52 public static readonly DateTimeOffset MinValue = new DateTimeOffset (DateTime.MinValue, TimeSpan.Zero);
57 public DateTimeOffset (DateTime dateTime)
61 if (dateTime.Kind == DateTimeKind.Utc)
62 utc_offset = TimeSpan.Zero;
64 utc_offset = TimeZone.CurrentTimeZone.GetUtcOffset (dateTime);
66 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
67 throw new ArgumentOutOfRangeException ("The UTC date and time that results from applying the offset is earlier than MinValue or later than MaxValue.");
71 public DateTimeOffset (DateTime dateTime, TimeSpan offset)
73 if (dateTime.Kind == DateTimeKind.Utc && offset != TimeSpan.Zero)
74 throw new ArgumentException ("dateTime.Kind equals Utc and offset does not equal zero.");
76 if (dateTime.Kind == DateTimeKind.Local && offset != TimeZone.CurrentTimeZone.GetUtcOffset (dateTime))
77 throw new ArgumentException ("dateTime.Kind equals Local and offset does not equal the offset of the system's local time zone.");
79 if (offset.Ticks % TimeSpan.TicksPerMinute != 0)
80 throw new ArgumentException ("offset is not specified in whole minutes.");
82 if (offset < new TimeSpan (-14, 0 ,0) || offset > new TimeSpan (14, 0, 0))
83 throw new ArgumentOutOfRangeException ("offset is less than -14 hours or greater than 14 hours.");
88 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
89 throw new ArgumentOutOfRangeException ("The UtcDateTime property is earlier than MinValue or later than MaxValue.");
92 public DateTimeOffset (long ticks, TimeSpan offset) : this (new DateTime (ticks), offset)
96 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, TimeSpan offset) :
97 this (new DateTime (year, month, day, hour, minute, second), offset)
101 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset) :
102 this (new DateTime (year, month, day, hour, minute, second, millisecond), offset)
106 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset) :
107 this (new DateTime (year, month, day, hour, minute, second, millisecond, calendar), offset)
111 public DateTimeOffset Add (TimeSpan timeSpan)
113 return new DateTimeOffset (dt.Add (timeSpan).Ticks, utc_offset);
116 public DateTimeOffset AddDays (double days)
118 return new DateTimeOffset (dt.AddDays (days).Ticks, utc_offset);
121 public DateTimeOffset AddHours (double hours)
123 return new DateTimeOffset (dt.AddHours (hours).Ticks, utc_offset);
126 public static DateTimeOffset operator + (DateTimeOffset dateTimeOffset, TimeSpan timeSpan)
128 return dateTimeOffset.Add (timeSpan);
131 public DateTimeOffset AddMilliseconds (double milliseconds)
133 return new DateTimeOffset (dt.AddMilliseconds (milliseconds).Ticks, utc_offset);
136 public DateTimeOffset AddMinutes (double minutes)
138 return new DateTimeOffset (dt.AddMinutes (minutes).Ticks, utc_offset);
141 public DateTimeOffset AddMonths (int months)
143 return new DateTimeOffset (dt.AddMonths (months).Ticks, utc_offset);
146 public DateTimeOffset AddSeconds (double seconds)
148 return new DateTimeOffset (dt.AddSeconds (seconds).Ticks, utc_offset);
151 public DateTimeOffset AddTicks (long ticks)
153 return new DateTimeOffset (dt.AddTicks (ticks).Ticks, utc_offset);
156 public DateTimeOffset AddYears (int years)
158 return new DateTimeOffset (dt.AddYears (years).Ticks, utc_offset);
161 public static int Compare (DateTimeOffset first, DateTimeOffset second)
163 return first.CompareTo (second);
166 public int CompareTo (DateTimeOffset other)
168 return UtcDateTime.CompareTo (other.UtcDateTime);
171 int IComparable.CompareTo (object obj)
173 return CompareTo ((DateTimeOffset) obj);
176 public static bool operator == (DateTimeOffset left, DateTimeOffset right)
178 return left.Equals (right);
181 public bool Equals (DateTimeOffset other)
183 return UtcDateTime == other.UtcDateTime;
186 public override bool Equals (object obj)
188 if (obj is DateTimeOffset)
189 return UtcDateTime == ((DateTimeOffset) obj).UtcDateTime;
193 public static bool Equals (DateTimeOffset first, DateTimeOffset second)
195 return first.Equals (second);
198 public bool EqualsExact (DateTimeOffset other)
200 return dt == other.dt && utc_offset == other.utc_offset;
203 public static DateTimeOffset FromFileTime (long fileTime)
205 if (fileTime < 0 || fileTime > MaxValue.Ticks)
206 throw new ArgumentOutOfRangeException ("fileTime is less than zero or greater than DateTimeOffset.MaxValue.Ticks.");
208 return new DateTimeOffset (DateTime.FromFileTime (fileTime), TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.FromFileTime (fileTime)));
212 public override int GetHashCode ()
214 return dt.GetHashCode () ^ utc_offset.GetHashCode ();
217 [System.Security.Permissions.SecurityPermission (System.Security.Permissions.SecurityAction.LinkDemand, SerializationFormatter = true)]
218 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
221 throw new ArgumentNullException ("info");
222 // An example SOAP serialization on MSFT is the following, so field
223 // names "DateTime" and "OffsetMinutes":
224 // <SOAP-ENV:Envelope ...>
226 // <a1:DateTimeOffset id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/ns/System">
227 // <DateTime xsi:type="xsd:dateTime">2007-01-02T12:30:50.0000000+00:00</DateTime>
228 // <OffsetMinutes>0</OffsetMinutes>
229 // </a1:DateTimeOffset>
231 // </SOAP-ENV:Envelope>
232 DateTime dt0 = new DateTime (dt.Ticks).Subtract (utc_offset);
233 info.AddValue ("DateTime", dt0);
234 // MSFT BinaryFormatter output contains primitive code 6, i.e. Int16.
235 info.AddValue ("OffsetMinutes", (Int16)utc_offset.TotalMinutes);
238 [System.Security.Permissions.SecurityPermission (System.Security.Permissions.SecurityAction.LinkDemand, SerializationFormatter = true)]
239 private DateTimeOffset(SerializationInfo info, StreamingContext context)
241 DateTime dt0 = (DateTime)info.GetValue ("DateTime", typeof(DateTime));
242 Int16 totalMinutes = info.GetInt16 ("OffsetMinutes");
243 utc_offset = TimeSpan.FromMinutes(totalMinutes);
244 dt = dt0.Add(utc_offset);
247 public static bool operator > (DateTimeOffset left, DateTimeOffset right)
249 return left.UtcDateTime > right.UtcDateTime;
252 public static bool operator >= (DateTimeOffset left, DateTimeOffset right)
254 return left.UtcDateTime >= right.UtcDateTime;
257 public static implicit operator DateTimeOffset (DateTime dateTime)
259 return new DateTimeOffset (dateTime);
262 public static bool operator != (DateTimeOffset left, DateTimeOffset right)
264 return left.UtcDateTime != right.UtcDateTime;
267 public static bool operator < (DateTimeOffset left, DateTimeOffset right)
269 return left.UtcDateTime < right.UtcDateTime;
272 public static bool operator <= (DateTimeOffset left, DateTimeOffset right)
274 return left.UtcDateTime <= right.UtcDateTime;
278 void IDeserializationCallback.OnDeserialization (object sender)
282 public static DateTimeOffset Parse (string input)
284 return Parse (input, null);
287 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider)
289 return Parse (input, formatProvider, DateTimeStyles.AllowWhiteSpaces);
292 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider, DateTimeStyles styles)
295 throw new ArgumentNullException ("input");
299 Exception exception = null;
301 if (!DateTime.CoreParse (input, formatProvider, styles, out d, out dto, true, ref exception))
303 } catch (ArgumentOutOfRangeException ex) {
304 throw new FormatException ("The UTC representation falls outside the 1-9999 year range", ex);
307 if (d.Ticks != 0 && dto.Ticks == 0)
308 throw new FormatException ("The UTC representation falls outside the 1-9999 year range");
313 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider)
315 return ParseExact (input, format, formatProvider, DateTimeStyles.AssumeLocal);
318 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
321 throw new ArgumentNullException ("format");
323 if (format == String.Empty)
324 throw new FormatException ("format is an empty string");
326 return ParseExact (input, new string [] {format}, formatProvider, styles);
329 public static DateTimeOffset ParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
332 throw new ArgumentNullException ("input");
334 if (input == String.Empty)
335 throw new FormatException ("input is an empty string");
338 throw new ArgumentNullException ("formats");
340 if (formats.Length == 0)
341 throw new FormatException ("Invalid format specifier");
343 if ((styles & DateTimeStyles.AssumeLocal) != 0 && (styles & DateTimeStyles.AssumeUniversal) != 0)
344 throw new ArgumentException ("styles parameter contains incompatible flags");
346 DateTimeOffset result;
347 if (!ParseExact (input, formats, DateTimeFormatInfo.GetInstance (formatProvider), styles, out result))
348 throw new FormatException ("Invalid format string");
353 private static bool ParseExact (string input, string [] formats,
354 DateTimeFormatInfo dfi, DateTimeStyles styles, out DateTimeOffset ret)
356 foreach (string format in formats)
358 if (format == null || format == String.Empty)
359 throw new FormatException ("Invalid format string");
361 DateTimeOffset result;
362 if (DoParse (input, format, false, out result, dfi, styles)) {
367 ret = DateTimeOffset.MinValue;
371 private static bool DoParse (string input,
374 out DateTimeOffset result,
375 DateTimeFormatInfo dfi,
376 DateTimeStyles styles)
378 if ((styles & DateTimeStyles.AllowLeadingWhite) != 0) {
379 format = format.TrimStart (null);
380 input = input.TrimStart (null);
383 if ((styles & DateTimeStyles.AllowTrailingWhite) != 0) {
384 format = format.TrimEnd (null);
385 input = input.TrimEnd (null);
388 bool allow_white_spaces = false;
389 if ((styles & DateTimeStyles.AllowInnerWhite) != 0)
390 allow_white_spaces = true;
392 result = DateTimeOffset.MinValue;
394 bool useutc = false, use_invariants = false;
395 if (format.Length == 1) {
396 format = DateTimeUtils.GetStandardPattern (format[0], dfi, out useutc, out use_invariants, true);
404 int partial_hour = -1; // for 'hh tt' formats
408 double fraction = -1;
410 TimeSpan offset = TimeSpan.MinValue;
412 int fi = 0; //format iterator
413 int ii = 0; //input iterator
414 while (fi < format.Length) {
416 char ch = format [fi];
420 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
421 if (day != -1 || tokLen > 4)
425 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out day);
427 ii += ParseEnum (input, ii, tokLen == 3 ? dfi.AbbreviatedDayNames : dfi.DayNames, allow_white_spaces, out temp_int);
430 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
431 ii += ParseNumber (input, ii, tokLen, true, allow_white_spaces, out temp_int);
432 if (fraction >= 0 || tokLen > 7 || temp_int == -1)
434 fraction = (double)temp_int / Math.Pow (10, tokLen);
437 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
439 int read = ParseNumber (input, ii, tokLen, true, allow_white_spaces, out temp_int, out digits);
441 ii += ParseNumber (input, ii, digits, true, allow_white_spaces, out temp_int);
444 if (fraction >= 0 || tokLen > 7 || temp_int == -1)
446 fraction = (double)temp_int / Math.Pow (10, digits);
449 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
450 if (hour != -1 || tokLen > 2)
453 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out temp_int);
457 if (partial_hour == -1)
458 partial_hour = temp_int;
460 hour = partial_hour + temp_int;
463 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
464 if (hour != -1 || tokLen > 2)
467 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out hour);
470 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
471 if (minute != -1 || tokLen > 2)
474 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out minute);
477 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
478 if (month != -1 || tokLen > 4)
482 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out month);
484 ii += ParseEnum (input, ii, tokLen == 3 ? dfi.AbbreviatedMonthNames : dfi.MonthNames, allow_white_spaces, out month);
490 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
491 if (second != -1 || tokLen > 2)
493 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out second);
496 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
497 if (hour != -1 || tokLen > 2)
500 ii += ParseEnum (input, ii,
501 tokLen == 1 ? new string[] {new string (dfi.AMDesignator[0], 1), new string (dfi.PMDesignator[0], 0)}
502 : new string[] {dfi.AMDesignator, dfi.PMDesignator},
503 allow_white_spaces, out temp_int);
507 if (partial_hour == -1)
508 partial_hour = temp_int * 12;
510 hour = partial_hour + temp_int * 12;
516 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
518 ii += ParseNumber (input, ii, 2, tokLen == 2, allow_white_spaces, out year);
520 year = dfi.Calendar.ToFourDigitYear (year);
521 } else if (tokLen <= 4) { // yyy and yyyy accept up to 5 digits with leading 0
523 ii += ParseNumber (input, ii, 5, false, allow_white_spaces, out year, out digit_parsed);
524 if (digit_parsed < tokLen || (digit_parsed > tokLen && (year / Math.Pow (10, digit_parsed - 1) < 1)))
527 ii += ParseNumber (input, ii, tokLen, true, allow_white_spaces, out year);
530 // The documentation is incorrect, they claim that K is the same as 'zz', but
531 // it actually allows the format to contain 4 digits for the offset
534 int off_h, off_m = 0, sign;
536 ii += ParseEnum (input, ii, new string [] {"-", "+"}, allow_white_spaces, out sign);
537 ii += ParseNumber (input, ii, 4, false, false, out off_h);
538 if (off_h == -1 || off_m == -1 || sign == -1)
543 offset = new TimeSpan (sign * off_h, sign * off_m, 0);
547 tokLen = DateTimeUtils.CountRepeat (format, fi, ch);
548 if (offset != TimeSpan.MinValue || tokLen > 3)
553 ii += ParseEnum (input, ii, new string [] {"-", "+"}, allow_white_spaces, out sign);
554 ii += ParseNumber (input, ii, 2, tokLen != 1, false, out off_h);
556 ii += ParseEnum (input, ii, new string [] {dfi.TimeSeparator}, false, out temp_int);
557 ii += ParseNumber (input, ii, 2, true, false, out off_m);
559 if (off_h == -1 || off_m == -1 || sign == -1)
564 offset = new TimeSpan (sign * off_h, sign * off_m, 0);
568 ii += ParseEnum (input, ii, new string [] {dfi.TimeSeparator}, false, out temp_int);
574 ii += ParseEnum (input, ii, new string [] {dfi.DateSeparator}, false, out temp_int);
585 ii += ParseChar (input, ii, ' ', false, out temp_int);
591 ii += ParseChar (input, ii, format [fi + 1], allow_white_spaces, out temp_int);
598 while (ii < input.Length) {
599 var ftoken = format [fi + tokLen];
601 if (ftoken == format [fi]) {
602 if (useutc && tokLen == 5 && input [ii - 3] == 'G' && input [ii - 2] == 'M' && input [ii - 1] == 'T') {
603 offset = TimeSpan.Zero;
609 if (ftoken != input [ii++])
615 //Console.WriteLine ("un-parsed character: {0}", ch);
617 ii += ParseChar (input, ii, format [fi], allow_white_spaces, out temp_int);
625 //Console.WriteLine ("{0}-{1}-{2} {3}:{4} {5}", year, month, day, hour, minute, offset);
626 if (offset == TimeSpan.MinValue) {
627 if ((styles & DateTimeStyles.AssumeUniversal) != 0) {
628 offset = TimeSpan.Zero;
629 } else if ((styles & DateTimeStyles.AssumeLocal) != 0) {
630 offset = use_invariants ?
632 TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.Now);
637 if (hour < 0) hour = 0;
638 if (minute < 0) minute = 0;
639 if (second < 0) second = 0;
640 if (fraction < 0) fraction = 0;
641 if (year > 0 && month > 0 && day > 0) {
642 result = new DateTimeOffset (year, month, day, hour, minute, second, 0, offset);
643 result = result.AddSeconds (fraction);
644 if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
645 result = result.ToUniversalTime ();
652 private static int ParseNumber (string input, int pos, int digits, bool leading_zero, bool allow_leading_white, out int result)
655 return ParseNumber (input, pos, digits, leading_zero, allow_leading_white, out result, out digit_parsed);
658 private static int ParseNumber (string input, int pos, int digits, bool leading_zero, bool allow_leading_white, out int result, out int digit_parsed)
663 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++)
666 for (; pos < input.Length && Char.IsDigit (input[pos]) && digits > 0; pos ++, char_parsed++, digit_parsed++, digits --)
667 result = 10 * result + (byte) (input[pos] - '0');
669 if (leading_zero && digits > 0)
672 if (digit_parsed == 0)
678 private static int ParseEnum (string input, int pos, string [] enums, bool allow_leading_white, out int result)
682 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++)
685 for (int i = 0; i < enums.Length; i++)
686 if (input.Substring(pos).StartsWith (enums [i])) {
692 char_parsed += enums[result].Length;
697 private static int ParseChar (string input, int pos, char c, bool allow_leading_white, out int result)
701 for (; allow_leading_white && pos < input.Length && input[pos] == ' '; pos++, char_parsed++)
704 if (pos < input.Length && input[pos] == c){
712 public TimeSpan Subtract (DateTimeOffset value)
714 return UtcDateTime - value.UtcDateTime;
717 public DateTimeOffset Subtract (TimeSpan value)
722 public static TimeSpan operator - (DateTimeOffset left, DateTimeOffset right)
724 return left.Subtract (right);
727 public static DateTimeOffset operator - (DateTimeOffset dateTimeOffset, TimeSpan timeSpan)
729 return dateTimeOffset.Subtract (timeSpan);
732 public long ToFileTime ()
734 return UtcDateTime.ToFileTime ();
737 public DateTimeOffset ToLocalTime ()
739 return new DateTimeOffset (UtcDateTime.ToLocalTime (), TimeZone.CurrentTimeZone.GetUtcOffset (UtcDateTime.ToLocalTime ()));
742 public DateTimeOffset ToOffset (TimeSpan offset)
744 return new DateTimeOffset (dt - utc_offset + offset, offset);
747 public override string ToString ()
749 return ToString (null, null);
752 public string ToString (IFormatProvider formatProvider)
754 return ToString (null, formatProvider);
757 public string ToString (string format)
759 return ToString (format, null);
762 public string ToString (string format, IFormatProvider formatProvider)
764 DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance(formatProvider);
766 if (format == null || format == String.Empty)
767 format = dfi.ShortDatePattern + " " + dfi.LongTimePattern + " zzz";
769 bool to_utc = false, use_invariant = false;
770 if (format.Length == 1) {
771 char fchar = format [0];
773 format = DateTimeUtils.GetStandardPattern (fchar, dfi, out to_utc, out use_invariant, true);
779 throw new FormatException ("format is not one of the format specifier characters defined for DateTimeFormatInfo");
781 return to_utc ? DateTimeUtils.ToString (UtcDateTime, TimeSpan.Zero, format, dfi) : DateTimeUtils.ToString (DateTime, Offset, format, dfi);
784 public DateTimeOffset ToUniversalTime ()
786 return new DateTimeOffset (UtcDateTime, TimeSpan.Zero);
789 public static bool TryParse (string input, out DateTimeOffset result)
792 result = Parse (input);
800 public static bool TryParse (string input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
803 result = Parse (input, formatProvider, styles);
811 public static bool TryParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
814 result = ParseExact (input, format, formatProvider, styles);
822 public static bool TryParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
825 result = ParseExact (input, formats, formatProvider, styles);
833 public DateTime Date {
834 get { return DateTime.SpecifyKind (dt.Date, DateTimeKind.Unspecified); }
837 public DateTime DateTime {
838 get { return DateTime.SpecifyKind (dt, DateTimeKind.Unspecified); }
842 get { return dt.Day; }
845 public DayOfWeek DayOfWeek {
846 get { return dt.DayOfWeek; }
849 public int DayOfYear {
850 get { return dt.DayOfYear; }
854 get { return dt.Hour; }
857 public DateTime LocalDateTime {
858 get { return UtcDateTime.ToLocalTime (); }
861 public int Millisecond {
862 get { return dt.Millisecond; }
866 get { return dt.Minute; }
870 get { return dt.Month; }
873 public static DateTimeOffset Now {
874 get { return new DateTimeOffset (DateTime.Now);}
877 public TimeSpan Offset {
878 get { return utc_offset; }
882 get { return dt.Second; }
886 get { return dt.Ticks; }
889 public TimeSpan TimeOfDay {
890 get { return dt.TimeOfDay; }
893 public DateTime UtcDateTime {
894 get { return DateTime.SpecifyKind (dt - utc_offset, DateTimeKind.Utc); }
897 public static DateTimeOffset UtcNow {
898 get { return new DateTimeOffset (DateTime.UtcNow); }
901 public long UtcTicks {
902 get { return UtcDateTime.Ticks; }
906 get { return dt.Year; }