2 * System.DateTimeOffset
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 #if NET_2_0 // Introduced by .NET 3.5 for 2.0 mscorlib
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Runtime.Serialization;
40 [StructLayout (LayoutKind.Auto)]
41 public struct DateTimeOffset : IComparable, IFormattable, ISerializable, IDeserializationCallback, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
43 public static readonly DateTimeOffset MaxValue = new DateTimeOffset (DateTime.MaxValue);
44 public static readonly DateTimeOffset MinValue = new DateTimeOffset (DateTime.MaxValue);
49 public DateTimeOffset (DateTime dateTime)
53 if (dateTime.Kind == DateTimeKind.Utc)
54 utc_offset = TimeSpan.Zero;
56 utc_offset = TimeZone.CurrentTimeZone.GetUtcOffset (dateTime);
58 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
59 throw new ArgumentOutOfRangeException ("The UTC date and time that results from applying the offset is earlier than MinValue or later than MaxValue.");
63 public DateTimeOffset (DateTime dateTime, TimeSpan offset)
65 if (dateTime.Kind == DateTimeKind.Utc && offset != TimeSpan.Zero)
66 throw new ArgumentException ("dateTime.Kind equals Utc and offset does not equal zero.");
68 if (dateTime.Kind == DateTimeKind.Local && offset != TimeZone.CurrentTimeZone.GetUtcOffset (dateTime))
69 throw new ArgumentException ("dateTime.Kind equals Local and offset does not equal the offset of the system's local time zone.");
71 if (offset.Ticks % TimeSpan.TicksPerMinute != 0)
72 throw new ArgumentException ("offset is not specified in whole minutes.");
74 if (offset < new TimeSpan (-14, 0 ,0) || offset > new TimeSpan (14, 0, 0))
75 throw new ArgumentOutOfRangeException ("offset is less than -14 hours or greater than 14 hours.");
80 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
81 throw new ArgumentOutOfRangeException ("The UtcDateTime property is earlier than MinValue or later than MaxValue.");
84 public DateTimeOffset (long ticks, TimeSpan offset) : this (new DateTime (ticks), offset)
88 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, TimeSpan offset) :
89 this (new DateTime (year, month, day, hour, minute, second), offset)
93 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset) :
94 this (new DateTime (year, month, day, hour, minute, second, millisecond), offset)
98 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset) :
99 this (new DateTime (year, month, day, hour, minute, second, millisecond, calendar), offset)
103 public DateTimeOffset Add (TimeSpan timeSpan)
105 return new DateTimeOffset (dt.Add (timeSpan), utc_offset);
108 public DateTimeOffset AddDays (double days)
110 return new DateTimeOffset (dt.AddDays (days), utc_offset);
113 public DateTimeOffset AddHours (double hours)
115 return new DateTimeOffset (dt.AddHours (hours), utc_offset);
118 public static DateTimeOffset operator + (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
120 return dateTimeTz.Add (timeSpan);
123 public DateTimeOffset AddMilliseconds (double milliseconds)
125 return new DateTimeOffset (dt.AddMilliseconds (milliseconds), utc_offset);
128 public DateTimeOffset AddMinutes (double minutes)
130 return new DateTimeOffset (dt.AddMinutes (minutes), utc_offset);
133 public DateTimeOffset AddMonths (int months)
135 return new DateTimeOffset (dt.AddMonths (months), utc_offset);
138 public DateTimeOffset AddSeconds (double seconds)
140 return new DateTimeOffset (dt.AddSeconds (seconds), utc_offset);
143 public DateTimeOffset AddTicks (long ticks)
145 return new DateTimeOffset (dt.AddTicks (ticks), utc_offset);
148 public DateTimeOffset AddYears (int years)
150 return new DateTimeOffset (dt.AddYears (years), utc_offset);
153 public static int Compare (DateTimeOffset first, DateTimeOffset second)
155 return first.CompareTo (second);
158 public int CompareTo (DateTimeOffset other)
160 return UtcDateTime.CompareTo (other.UtcDateTime);
163 public int CompareTo (object other)
165 return UtcDateTime.CompareTo (other);
168 public static bool operator == (DateTimeOffset left, DateTimeOffset right)
170 return left.Equals (right);
173 public bool Equals (DateTimeOffset other)
175 return UtcDateTime == other.UtcDateTime;
178 public override bool Equals (object other)
180 return UtcDateTime == ((DateTimeOffset) other).UtcDateTime;
183 public static bool Equals (DateTimeOffset first, DateTimeOffset second)
185 return first.Equals (second);
188 public bool EqualsExact (DateTimeOffset other)
190 return dt == other.dt && utc_offset == other.utc_offset;
193 public static DateTimeOffset FromFileTime (long fileTime)
195 if (fileTime < 0 || fileTime > MaxValue.Ticks)
196 throw new ArgumentOutOfRangeException ("fileTime is less than zero or greater than DateTimeOffset.MaxValue.Ticks.");
198 return new DateTimeOffset (DateTime.FromFileTime (fileTime), TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.FromFileTime (fileTime)));
202 public override int GetHashCode ()
204 return dt.GetHashCode () ^ utc_offset.GetHashCode ();
207 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
210 throw new ArgumentNullException ("info");
212 info.AddValue ("datetime", dt);
213 info.AddValue ("offset", utc_offset);
216 public static bool operator > (DateTimeOffset left, DateTimeOffset right)
218 return left.UtcDateTime > right.UtcDateTime;
221 public static bool operator >= (DateTimeOffset left, DateTimeOffset right)
223 return left.UtcDateTime >= right.UtcDateTime;
226 public static implicit operator DateTimeOffset (DateTime dateTime)
228 return new DateTimeOffset (dateTime);
231 public static bool operator != (DateTimeOffset left, DateTimeOffset right)
233 return left.UtcDateTime != right.UtcDateTime;
236 public static bool operator < (DateTimeOffset left, DateTimeOffset right)
238 return left.UtcDateTime < right.UtcDateTime;
241 public static bool operator <= (DateTimeOffset left, DateTimeOffset right)
243 return left.UtcDateTime <= right.UtcDateTime;
246 void IDeserializationCallback.OnDeserialization (object sender)
251 public static DateTimeOffset Parse (string input)
254 throw new ArgumentNullException ("input");
256 throw new NotImplementedException ();
260 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider)
263 throw new ArgumentNullException ("input");
265 throw new NotImplementedException ();
269 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider, DateTimeStyles styles)
272 throw new ArgumentNullException ("input");
274 throw new NotImplementedException ();
278 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider)
281 throw new ArgumentNullException ("input");
284 throw new ArgumentNullException ("format");
286 if (input == String.Empty)
287 throw new FormatException ("input is an empty string");
289 if (format == String.Empty)
290 throw new FormatException ("format is an empty string");
292 throw new NotImplementedException ();
296 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
299 throw new ArgumentNullException ("input");
302 throw new ArgumentNullException ("format");
304 if (input == String.Empty)
305 throw new FormatException ("input is an empty string");
307 if (format == String.Empty)
308 throw new FormatException ("format is an empty string");
310 throw new NotImplementedException ();
314 public static DateTimeOffset ParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
317 throw new ArgumentNullException ("input");
320 if (input == String.Empty)
321 throw new FormatException ("input is an empty string");
323 throw new NotImplementedException ();
326 public TimeSpan Subtract (DateTimeOffset other)
328 return UtcDateTime - other.UtcDateTime;
331 public DateTimeOffset Subtract (TimeSpan timeSpan)
333 return Add (-timeSpan);
336 public static TimeSpan operator - (DateTimeOffset left, DateTimeOffset right)
338 return left.Subtract (right);
341 public static DateTimeOffset operator - (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
343 return dateTimeTz.Subtract (timeSpan);
346 public long ToFileTime ()
348 return UtcDateTime.ToFileTime ();
351 public DateTimeOffset ToLocalTime ()
353 return new DateTimeOffset (UtcDateTime.ToLocalTime (), TimeZone.CurrentTimeZone.GetUtcOffset (UtcDateTime.ToLocalTime ()));
356 public DateTimeOffset ToOffset (TimeSpan offset)
358 return new DateTimeOffset (dt - utc_offset + offset, offset);
362 public override string ToString ()
364 throw new NotImplementedException ();
368 public string ToString (IFormatProvider formatProvider)
370 throw new NotImplementedException ();
374 public string ToString (string format)
376 throw new NotImplementedException ();
380 public string ToString (string format, IFormatProvider formatProvider)
382 throw new NotImplementedException ();
385 public DateTimeOffset ToUniversalTime ()
387 return new DateTimeOffset (UtcDateTime, TimeSpan.Zero);
390 public static bool TryParse (string input, out DateTimeOffset result)
393 result = Parse (input);
401 public static bool TryParse (string input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
404 result = Parse (input, formatProvider, styles);
412 public static bool TryParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
415 result = ParseExact (input, format, formatProvider, styles);
423 public static bool TryParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
426 result = ParseExact (input, formats, formatProvider, styles);
434 public DateTime Date {
435 get { return DateTime.SpecifyKind (dt.Date, DateTimeKind.Unspecified); }
438 public DateTime DateTime {
439 get { return DateTime.SpecifyKind (dt, DateTimeKind.Unspecified); }
443 get { return dt.Day; }
446 public DayOfWeek DayOfWeek {
447 get { return dt.DayOfWeek; }
450 public int DayOfYear {
451 get { return dt.DayOfYear; }
455 get { return dt.Hour; }
458 public DateTime LocalDateTime {
459 get { return UtcDateTime.ToLocalTime (); }
462 public int Millisecond {
463 get { return dt.Millisecond; }
467 get { return dt.Minute; }
471 get { return dt.Month; }
474 public static DateTimeOffset Now {
475 get { return new DateTimeOffset (DateTime.Now);}
478 public TimeSpan Offset {
479 get { return utc_offset; }
483 get { return dt.Second; }
487 get { return dt.Ticks; }
490 public TimeSpan TimeOfDay {
491 get { return dt.TimeOfDay; }
494 public DateTime UtcDateTime {
495 get { return DateTime.SpecifyKind (dt - utc_offset, DateTimeKind.Utc); }
498 public static DateTimeOffset UtcNow {
499 get { return new DateTimeOffset (DateTime.UtcNow); }
502 public long UtcTicks {
503 get { return UtcDateTime.Ticks; }
507 get { return dt.Year; }