using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
+using System.Runtime.Serialization;
namespace System
{
///
[Serializable]
[StructLayout (LayoutKind.Auto)]
- public struct DateTime : IFormattable, IConvertible, IComparable
-#if NET_2_0
- , IComparable<DateTime>, IEquatable <DateTime>
-#endif
+ public struct DateTime : IFormattable, IConvertible, IComparable, ISerializable, IComparable<DateTime>, IEquatable <DateTime>
{
+#if MONOTOUCH
+ static DateTime () {
+ if (MonoTouchAOTHelper.FalseFlag) {
+ var comparer = new System.Collections.Generic.GenericComparer <DateTime> ();
+ var eqcomparer = new System.Collections.Generic.GenericEqualityComparer <DateTime> ();
+ }
+ }
+#endif
private TimeSpan ticks;
-#if NET_2_0
DateTimeKind kind;
-#endif
private const int dp400 = 146097;
private const int dp100 = 36524;
private static readonly string[] ParseTimeFormats = new string [] {
"H:m:s.fffffffzzz",
"H:m:s.fffffff",
+ "H:m:s tt zzz",
"H:m:szzz",
"H:m:s",
"H:mzzz",
"M/yyyy/dT",
"yyyy'\u5E74'M'\u6708'd'\u65E5",
-#if NET_2_0
+
"yyyy/d/MMMM",
"yyyy/MMM/d",
-#else
- "yyyy/MMMM/d",
- "yyyy/d/MMM",
-#endif
"d/MMMM/yyyy",
"MMM/d/yyyy",
"d/yyyy/MMMM",
};
private static readonly string[] DayMonthShortFormats = new string [] {
"d/MMMM",
-#if NET_2_0
"MMM/yy",
-#else // In .Net 1.0 Feb 03 is always Feb 3rd (and not Feb 2003)
- "MMM/d",
-#endif
"yyyy/MMMM",
};
ticks, MinValue.Ticks, MaxValue.Ticks);
throw new ArgumentOutOfRangeException ("ticks", msg);
}
-#if NET_2_0
kind = DateTimeKind.Unspecified;
-#endif
}
public DateTime (int year, int month, int day)
ticks = new TimeSpan (AbsoluteDays(year,month,day), hour, minute, second, millisecond);
-#if NET_2_0
kind = DateTimeKind.Unspecified;
-#endif
}
public DateTime (int year, int month, int day, Calendar calendar)
if (calendar == null)
throw new ArgumentNullException ("calendar");
ticks = calendar.ToDateTime (year, month, day, hour, minute, second, millisecond).ticks;
-#if NET_2_0
kind = DateTimeKind.Unspecified;
-#endif
}
internal DateTime (bool check, TimeSpan value)
ticks = value;
-#if NET_2_0
kind = DateTimeKind.Unspecified;
-#endif
}
-#if NET_2_0
public DateTime (long ticks, DateTimeKind kind) : this (ticks)
{
CheckDateTimeKind (kind);
{
CheckDateTimeKind (kind);
this.kind = kind;
- }
-#endif
+ }
+ //
+ // Not visible, but can be invoked during deserialization
+ //
+ DateTime (SerializationInfo info, StreamingContext context)
+ {
+ if (info.HasKey ("dateData")){
+ long dateData = info.GetInt64 ("dateData");
+ kind = (DateTimeKind) (dateData >> 62);
+ ticks = new TimeSpan (dateData & 0x3fffffffffffffff);
+ } else if (info.HasKey ("ticks")){
+ ticks = new TimeSpan (info.GetInt64 ("ticks"));
+ kind = DateTimeKind.Unspecified;
+ } else {
+ kind = DateTimeKind.Unspecified;
+ ticks = new TimeSpan (0);
+ }
+ }
+
+
/* Properties */
public DateTime Date
get
{
DateTime ret = new DateTime (Year, Month, Day);
-#if NET_2_0
ret.kind = kind;
-#endif
return ret;
}
}
}
}
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern long GetTimeMonotonic ();
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern long GetNow ();
// This is boxed, so we avoid locking.
DateTime ret = dt + (TimeSpan) to_local_time_span_object;
-#if NET_2_0
ret.kind = DateTimeKind.Local;
-#endif
return ret;
}
}
get {
DateTime now = Now;
DateTime today = new DateTime (now.Year, now.Month, now.Day);
-#if NET_2_0
today.kind = now.kind;
-#endif
return today;
}
}
public static DateTime UtcNow
{
get {
-#if NET_2_0
return new DateTime (GetNow (), DateTimeKind.Utc);
-#else
- return new DateTime (GetNow ());
-#endif
}
}
}
}
-#if NET_2_0
public DateTimeKind Kind {
get {
return kind;
}
}
-#endif
/* methods */
- public DateTime Add (TimeSpan ts)
+ public DateTime Add (TimeSpan value)
{
- DateTime ret = AddTicks (ts.Ticks);
-#if NET_2_0
+ DateTime ret = AddTicks (value.Ticks);
ret.kind = kind;
-#endif
return ret;
}
- public DateTime AddDays (double days)
+ public DateTime AddDays (double value)
{
- return AddMilliseconds (Math.Round (days * 86400000));
+ return AddMilliseconds (Math.Round (value * 86400000));
}
- public DateTime AddTicks (long t)
+ public DateTime AddTicks (long value)
{
- if ((t + ticks.Ticks) > MAX_VALUE_TICKS || (t + ticks.Ticks) < 0) {
+ if ((value + ticks.Ticks) > MAX_VALUE_TICKS || (value + ticks.Ticks) < 0) {
throw new ArgumentOutOfRangeException();
}
- DateTime ret = new DateTime (t + ticks.Ticks);
-#if NET_2_0
+ DateTime ret = new DateTime (value + ticks.Ticks);
ret.kind = kind;
-#endif
return ret;
}
- public DateTime AddHours (double hours)
+ public DateTime AddHours (double value)
{
- return AddMilliseconds (hours * 3600000);
+ return AddMilliseconds (value * 3600000);
}
- public DateTime AddMilliseconds (double ms)
+ public DateTime AddMilliseconds (double value)
{
- if ((ms * TimeSpan.TicksPerMillisecond) > long.MaxValue ||
- (ms * TimeSpan.TicksPerMillisecond) < long.MinValue) {
+ if ((value * TimeSpan.TicksPerMillisecond) > long.MaxValue ||
+ (value * TimeSpan.TicksPerMillisecond) < long.MinValue) {
throw new ArgumentOutOfRangeException();
}
- long msticks = (long) (ms * TimeSpan.TicksPerMillisecond);
+ long msticks = (long) Math.Round (value * TimeSpan.TicksPerMillisecond);
return AddTicks (msticks);
}
return AddTicks (msticks);
}
- public DateTime AddMinutes (double minutes)
+ public DateTime AddMinutes (double value)
{
- return AddMilliseconds (minutes * 60000);
+ return AddMilliseconds (value * 60000);
}
public DateTime AddMonths (int months)
day = maxday;
temp = new DateTime (year, month, day);
-#if NET_2_0
temp.kind = kind;
-#endif
return temp.Add (this.TimeOfDay);
}
- public DateTime AddSeconds (double seconds)
+ public DateTime AddSeconds (double value)
{
- return AddMilliseconds (seconds*1000);
+ return AddMilliseconds (value * 1000);
}
- public DateTime AddYears (int years )
+ public DateTime AddYears (int value)
{
- return AddMonths(years * 12);
+ return AddMonths (value * 12);
}
public static int Compare (DateTime t1, DateTime t2)
return 0;
}
- public int CompareTo (object v)
+ public int CompareTo (object value)
{
- if ( v == null)
+ if (value == null)
return 1;
- if (!(v is System.DateTime))
+ if (!(value is System.DateTime))
throw new ArgumentException (Locale.GetText (
"Value is not a System.DateTime"));
- return Compare (this, (DateTime) v);
+ return Compare (this, (DateTime) value);
}
-#if NET_2_0
public bool IsDaylightSavingTime ()
{
if (kind == DateTimeKind.Utc)
return new DateTime (value.Ticks, kind);
}
-#else
-
- internal long ToBinary ()
- {
- return Ticks;
- }
-
- internal static DateTime FromBinary (long dateData)
- {
- return new DateTime (dateData & 0x3fffffffffffffff);
- }
-#endif
-
public static int DaysInMonth (int year, int month)
{
int[] days ;
return days[month];
}
- public override bool Equals (object o)
+ public override bool Equals (object value)
{
- if (!(o is System.DateTime))
+ if (!(value is System.DateTime))
return false;
- return ((DateTime) o).ticks == ticks;
+ return ((DateTime) value).ticks == ticks;
}
public static bool Equals (DateTime t1, DateTime t2 )
return new DateTime (w32file_epoch + fileTime).ToLocalTime ();
}
-#if NET_1_1
public static DateTime FromFileTimeUtc (long fileTime)
{
if (fileTime < 0)
return new DateTime (w32file_epoch + fileTime);
}
-#endif
public static DateTime FromOADate (double d)
{
return results;
}
-#if NET_2_0
private void CheckDateTimeKind (DateTimeKind kind) {
if ((kind != DateTimeKind.Unspecified) && (kind != DateTimeKind.Utc) && (kind != DateTimeKind.Local))
throw new ArgumentException ("Invalid DateTimeKind value.", "kind");
}
-#endif
public override int GetHashCode ()
{
return Parse (s, null);
}
- public static DateTime Parse (string s, IFormatProvider fp)
+ public static DateTime Parse (string s, IFormatProvider provider)
{
- return Parse (s, fp, DateTimeStyles.AllowWhiteSpaces);
+ return Parse (s, provider, DateTimeStyles.AllowWhiteSpaces);
}
- public static DateTime Parse (string s, IFormatProvider fp, DateTimeStyles styles)
+ public static DateTime Parse (string s, IFormatProvider provider, DateTimeStyles styles)
{
-
- const string formatExceptionMessage = "String was not recognized as a valid DateTime.";
-#if !NET_2_0
- const string argumentYearRangeExceptionMessage = "Valid values are between 1 and 9999, inclusive.";
-#endif
-
if (s == null)
- throw new ArgumentNullException (Locale.GetText ("s is null"));
- if (fp == null)
- fp = CultureInfo.CurrentCulture;
- DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (fp);
+ throw new ArgumentNullException ("s");
+
+ DateTime res;
+ DateTimeOffset dto;
+ Exception exception = null;
+ if (!CoreParse (s, provider, styles, out res, out dto, true, ref exception))
+ throw exception;
+
+ return res;
+ }
+
+ const string formatExceptionMessage = "String was not recognized as a valid DateTime.";
+
+ internal static bool CoreParse (string s, IFormatProvider provider, DateTimeStyles styles,
+ out DateTime result, out DateTimeOffset dto, bool setExceptionOnError, ref Exception exception)
+ {
+ dto = new DateTimeOffset (0, TimeSpan.Zero);
+ if (s == null || s.Length == 0) {
+ if (setExceptionOnError)
+ exception = new FormatException (formatExceptionMessage);
+ result = MinValue;
+ return false;
+ }
+
+ if (provider == null)
+ provider = CultureInfo.CurrentCulture;
+ DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
- bool longYear = false;
- DateTime result;
// Try first all the combinations of ParseAllDateFormats & ParseTimeFormats
- string[] allDateFormats = YearMonthDayFormats (dfi);
+ string[] allDateFormats = YearMonthDayFormats (dfi, setExceptionOnError, ref exception);
+ if (allDateFormats == null){
+ result = MinValue;
+ return false;
+ }
+
+ bool longYear = false;
for (int i = 0; i < allDateFormats.Length; i++) {
string firstPart = allDateFormats [i];
bool incompleteFormat = false;
- if (_DoParse (s, firstPart, "", false, out result, dfi, styles, true, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, firstPart, "", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
+ return true;
+
if (!incompleteFormat)
continue;
for (int j = 0; j < ParseTimeFormats.Length; j++) {
- if (_DoParse (s, firstPart, ParseTimeFormats [j], false, out result, dfi, styles, true, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, firstPart, ParseTimeFormats [j], false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
+ return true;
}
}
- string[] monthDayFormats = IsDayBeforeMonth (dfi) ? DayMonthShortFormats : MonthDayShortFormats;
+
+ //
+ // Month day formats
+ //
+ int dayIndex = dfi.MonthDayPattern.IndexOf('d');
+ int monthIndex = dfi.MonthDayPattern.IndexOf('M');
+ if (dayIndex == -1 || monthIndex == -1){
+ result = MinValue;
+ if (setExceptionOnError)
+ exception = new FormatException (Locale.GetText("Order of month and date is not defined by {0}", dfi.MonthDayPattern));
+ return false;
+ }
+ bool is_day_before_month = dayIndex < monthIndex;
+ string[] monthDayFormats = is_day_before_month ? DayMonthShortFormats : MonthDayShortFormats;
for (int i = 0; i < monthDayFormats.Length; i++) {
bool incompleteFormat = false;
- if (_DoParse (s, monthDayFormats[i], "", false, out result, dfi, styles, true, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, monthDayFormats[i], "", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
+ return true;
}
+
for (int j = 0; j < ParseTimeFormats.Length; j++) {
string firstPart = ParseTimeFormats [j];
bool incompleteFormat = false;
- if (_DoParse (s, firstPart, "", false, out result, dfi, styles, false, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, firstPart, "", false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
+ return true;
if (!incompleteFormat)
continue;
for (int i = 0; i < monthDayFormats.Length; i++) {
- if (_DoParse (s, firstPart, monthDayFormats [i], false, out result, dfi, styles, false, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, firstPart, monthDayFormats [i], false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
+ return true;
}
for (int i = 0; i < allDateFormats.Length; i++) {
string dateFormat = allDateFormats [i];
if (dateFormat[dateFormat.Length - 1] == 'T')
continue; // T formats must be before the time part
- if (_DoParse (s, firstPart, dateFormat, false, out result, dfi, styles, false, ref incompleteFormat, ref longYear))
- return result;
+ if (_DoParse (s, firstPart, dateFormat, false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
+ return true;
}
}
// Try as a last resort all the patterns
- if (ParseExact (s, dfi.GetAllDateTimePatternsInternal (), dfi, styles, out result, false, ref longYear))
- return result;
-
-#if NET_2_0
- // .NET does not throw an ArgumentOutOfRangeException, but .NET 1.1 does.
- throw new FormatException (formatExceptionMessage);
-#else
- if (longYear) {
- throw new ArgumentOutOfRangeException ("year",
- argumentYearRangeExceptionMessage);
- }
-
- throw new FormatException (formatExceptionMessage);
-#endif
- }
+ if (ParseExact (s, dfi.GetAllDateTimePatternsInternal (), dfi, styles, out result, false, ref longYear, setExceptionOnError, ref exception))
+ return true;
- public static DateTime ParseExact (string s, string format, IFormatProvider fp)
- {
- return ParseExact (s, format, fp, DateTimeStyles.None);
+ if (!setExceptionOnError)
+ return false;
+
+ // .NET 2.x does not throw an ArgumentOutOfRangeException, but .NET 1.1 does.
+ exception = new FormatException (formatExceptionMessage);
+ return false;
}
- private static bool IsDayBeforeMonth (DateTimeFormatInfo dfi)
+ public static DateTime ParseExact (string s, string format, IFormatProvider provider)
{
- int dayIndex = dfi.MonthDayPattern.IndexOf('d');
- int monthIndex = dfi.MonthDayPattern.IndexOf('M');
- if (dayIndex == -1 || monthIndex == -1)
- throw new FormatException (Locale.GetText("Order of month and date is not defined by {0}", dfi.MonthDayPattern));
-
- return dayIndex < monthIndex;
+ return ParseExact (s, format, provider, DateTimeStyles.None);
}
- private static string[] YearMonthDayFormats (DateTimeFormatInfo dfi)
+ private static string[] YearMonthDayFormats (DateTimeFormatInfo dfi, bool setExceptionOnError, ref Exception exc)
{
int dayIndex = dfi.ShortDatePattern.IndexOf('d');
int monthIndex = dfi.ShortDatePattern.IndexOf('M');
int yearIndex = dfi.ShortDatePattern.IndexOf('y');
- if (dayIndex == -1 || monthIndex == -1 || yearIndex == -1)
- throw new FormatException (Locale.GetText("Order of year, month and date is not defined by {0}", dfi.ShortDatePattern));
+ if (dayIndex == -1 || monthIndex == -1 || yearIndex == -1){
+ if (setExceptionOnError)
+ exc = new FormatException (Locale.GetText("Order of year, month and date is not defined by {0}", dfi.ShortDatePattern));
+ return null;
+ }
if (yearIndex < monthIndex)
if (monthIndex < dayIndex)
return ParseYearMonthDayFormats;
else if (yearIndex < dayIndex)
return ParseYearDayMonthFormats;
- else
+ else {
// The year cannot be between the date and the month
- throw new FormatException (Locale.GetText("Order of date, year and month defined by {0} is not supported", dfi.ShortDatePattern));
+ if (setExceptionOnError)
+ exc = new FormatException (Locale.GetText("Order of date, year and month defined by {0} is not supported", dfi.ShortDatePattern));
+ return null;
+ }
else if (dayIndex < monthIndex)
return ParseDayMonthYearFormats;
else if (dayIndex < yearIndex)
return ParseMonthDayYearFormats;
- else
+ else {
// The year cannot be between the month and the date
- throw new FormatException (Locale.GetText("Order of month, year and date defined by {0} is not supported", dfi.ShortDatePattern));
+ if (setExceptionOnError)
+ exc = new FormatException (Locale.GetText("Order of month, year and date defined by {0} is not supported", dfi.ShortDatePattern));
+ return null;
+ }
}
private static int _ParseNumber (string s, int valuePos,
string secondPart,
bool exact,
out DateTime result,
+ out DateTimeOffset dto,
DateTimeFormatInfo dfi,
DateTimeStyles style,
bool firstPartIsDate,
ref bool incompleteFormat,
ref bool longYear)
{
-#if NET_2_0
- DateTimeKind explicit_kind = DateTimeKind.Unspecified;
-#endif
- bool useutc = false, use_localtime = true;
+ bool useutc = false;
bool use_invariant = false;
bool sloppy_parsing = false;
- bool afterTimePart = firstPartIsDate && secondPart == "";
+ dto = new DateTimeOffset (0, TimeSpan.Zero);
bool flexibleTwoPartsParsing = !exact && secondPart != null;
incompleteFormat = false;
int valuePos = 0;
string format = firstPart;
bool afterTFormat = false;
DateTimeFormatInfo invInfo = DateTimeFormatInfo.InvariantInfo;
- if (format.Length == 1) {
- if (format == "u")
- use_localtime = false;
+ if (format.Length == 1)
format = DateTimeUtils.GetStandardPattern (format [0], dfi, out useutc, out use_invariant);
- }
- else if (!exact && CultureInfo.InvariantCulture.CompareInfo.IndexOf (format, "GMT", CompareOptions.Ordinal) >= 0)
- useutc = true;
-#if NET_2_0
- if ((style & DateTimeStyles.AssumeUniversal) != 0)
- useutc = true;
-#endif
result = new DateTime (0);
if (format == null)
return false;
+ if (s == null)
+ return false;
+
if ((style & DateTimeStyles.AllowLeadingWhite) != 0) {
format = format.TrimStart (null);
if (flexibleTwoPartsParsing && pos + num == 0)
{
bool isLetter = IsLetter(s, valuePos);
- if (afterTimePart && isLetter) {
+ if (isLetter) {
if (s [valuePos] == 'Z')
num_parsed = 1;
else
chars = format;
len = chars.Length;
isFirstPart = false;
- if (!firstPartIsDate || format == "")
- afterTimePart = true;
continue;
}
break;
return false;
break;
-#if NET_2_0
case 'F':
leading_zeros = false;
goto case 'f';
-#endif
case 'f':
if (num > 6 || fractionalSeconds != -1)
return false;
else if (num == 1)
tzoffset = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
else {
- tzoffset = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
+ tzoffset = _ParseNumber (s, valuePos, 1, 2, true, /*sloppy_parsing*/true, out num_parsed);
valuePos += num_parsed;
if (num_parsed < 0)
return false;
num_parsed = 0;
}
break;
-#if NET_2_0
case 'K':
if (s [valuePos] == 'Z') {
valuePos++;
- useutc = true;
- explicit_kind = DateTimeKind.Utc;
+ useutc = true;
}
else if (s [valuePos] == '+' || s [valuePos] == '-') {
if (tzsign != -1)
tzoffmin = _ParseNumber (s, valuePos, 0, 2, true, sloppy_parsing, out num_parsed);
num = 2;
- explicit_kind = DateTimeKind.Local;
if (num_parsed < 0)
return false;
}
break;
-#endif
+
// LAMESPEC: This should be part of UTCpattern
// string and thus should not be considered here.
//
num_parsed = 1;
useutc = true;
break;
+ case 'G':
+ if (s [valuePos] != 'G')
+ return false;
+ if ((pos + 2 < len) && (valuePos + 2 < s.Length) &&
+ (chars [pos + 1] == 'M') && (s[valuePos + 1] == 'M') &&
+ (chars [pos + 2] == 'T') && (s[valuePos + 2] == 'T'))
+ {
+ useutc = true;
+ num = 2;
+ num_parsed = 3;
+ }
+ else {
+ num = 0;
+ num_parsed = 1;
+ }
+ break;
case ':':
if (!_ParseTimeSeparator (s, valuePos, dfi, exact, out num_parsed))
return false;
switch (chars [pos]) {
case 'm':
case 's':
-#if NET_2_0
case 'F':
-#endif
case 'f':
case 'z':
if (s.Length > valuePos && s [valuePos] == 'Z' &&
num = 0;
}
-#if NET_2_0
+ if (pos + 1 < len && chars [pos] == '.' && chars [pos + 1] == 'F') {
+ pos++;
+ while (pos < len && chars [pos] == 'F') // '.FFF....' can be mapped to nothing. See bug #444103
+ pos++;
+ }
while (pos < len && chars [pos] == 'K') // 'K' can be mapped to nothing
pos++;
-#endif
+
if (pos < len)
return false;
if (dayofweek != -1 && dayofweek != (int) result.DayOfWeek)
return false;
- // If no timezone was specified, default to the local timezone.
- TimeSpan utcoffset;
-
- if (useutc) {
- if ((style & DateTimeStyles.AdjustToUniversal) != 0)
- use_localtime = false;
- utcoffset = new TimeSpan (0, 0, 0);
- } else if (tzsign == -1) {
- TimeZone tz = TimeZone.CurrentTimeZone;
- utcoffset = tz.GetUtcOffset (result);
+ if (tzsign == -1) {
+ if (result != DateTime.MinValue) {
+ try {
+ dto = new DateTimeOffset (result);
+ } catch { } // We handle this error in DateTimeOffset.Parse
+ }
} else {
- if ((style & DateTimeStyles.AdjustToUniversal) != 0)
- use_localtime = false;
-
if (tzoffmin == -1)
tzoffmin = 0;
if (tzoffset == -1)
tzoffset = 0;
- if (tzsign == 1)
+ if (tzsign == 1) {
tzoffset = -tzoffset;
-
- utcoffset = new TimeSpan (tzoffset, tzoffmin, 0);
+ tzoffmin = -tzoffmin;
+ }
+ try {
+ dto = new DateTimeOffset (result, new TimeSpan (tzoffset, tzoffmin, 0));
+ } catch {} // We handle this error in DateTimeOffset.Parse
}
-
- long newticks = (result.ticks - utcoffset).Ticks;
-
- result = new DateTime (false, new TimeSpan (newticks));
-#if NET_2_0
- if (explicit_kind != DateTimeKind.Unspecified)
- result.kind = explicit_kind;
- else if (use_localtime)
- result = result.ToLocalTime ();
- else
+ bool adjustToUniversal = (style & DateTimeStyles.AdjustToUniversal) != 0;
+
+ if (tzsign != -1) {
+ long newticks = (result.ticks - dto.Offset).Ticks;
+ if (newticks < 0)
+ newticks += TimeSpan.TicksPerDay;
+ result = new DateTime (false, new TimeSpan (newticks));
result.kind = DateTimeKind.Utc;
-#else
- if (use_localtime)
- result = result.ToLocalTime ();
-#endif
-
+ if ((style & DateTimeStyles.RoundtripKind) != 0)
+ result = result.ToLocalTime ();
+ }
+ else if (useutc || ((style & DateTimeStyles.AssumeUniversal) != 0))
+ result.kind = DateTimeKind.Utc;
+ else if ((style & DateTimeStyles.AssumeLocal) != 0)
+ result.kind = DateTimeKind.Local;
+
+ bool adjustToLocal = !adjustToUniversal && (style & DateTimeStyles.RoundtripKind) == 0;
+ if (result.kind != DateTimeKind.Unspecified)
+ {
+ if (adjustToUniversal)
+ result = result.ToUniversalTime ();
+ else if (adjustToLocal)
+ result = result.ToLocalTime ();
+ }
return true;
}
public static DateTime ParseExact (string s, string format,
- IFormatProvider fp, DateTimeStyles style)
+ IFormatProvider provider, DateTimeStyles style)
{
if (format == null)
throw new ArgumentNullException ("format");
string [] formats = new string [1];
formats[0] = format;
- return ParseExact (s, formats, fp, style);
+ return ParseExact (s, formats, provider, style);
}
public static DateTime ParseExact (string s, string[] formats,
- IFormatProvider fp,
+ IFormatProvider provider,
DateTimeStyles style)
{
- DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (fp);
-
+ DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
+ CheckStyle (style);
if (s == null)
throw new ArgumentNullException ("s");
if (formats == null)
DateTime result;
bool longYear = false;
- if (!ParseExact (s, formats, dfi, style, out result, true, ref longYear))
- throw new FormatException ();
+ Exception e = null;
+ if (!ParseExact (s, formats, dfi, style, out result, true, ref longYear, true, ref e))
+ throw e;
return result;
+ }
+
+ private static void CheckStyle (DateTimeStyles style)
+ {
+ if ( (style & DateTimeStyles.RoundtripKind) != 0)
+ {
+ if ((style & DateTimeStyles.AdjustToUniversal) != 0 || (style & DateTimeStyles.AssumeLocal) != 0 ||
+ (style & DateTimeStyles.AssumeUniversal) != 0)
+ throw new ArgumentException ("The DateTimeStyles value RoundtripKind cannot be used with the values AssumeLocal, Asersal or AdjustToUniversal.", "style");
+ }
+ if ((style & DateTimeStyles.AssumeUniversal) != 0 && (style & DateTimeStyles.AssumeLocal) != 0)
+ throw new ArgumentException ("The DateTimeStyles values AssumeLocal and AssumeUniversal cannot be used together.", "style");
}
-#if NET_2_0
public static bool TryParse (string s, out DateTime result)
{
- try {
- result = Parse (s);
- } catch {
- result = MinValue;
- return false;
+ if (s != null){
+ try {
+ Exception exception = null;
+ DateTimeOffset dto;
+
+ return CoreParse (s, null, DateTimeStyles.AllowWhiteSpaces, out result, out dto, false, ref exception);
+ } catch { }
}
- return true;
+ result = MinValue;
+ return false;
}
public static bool TryParse (string s, IFormatProvider provider, DateTimeStyles styles, out DateTime result)
{
- try {
- result = Parse (s, provider, styles);
- } catch {
- result = MinValue;
- return false;
- }
- return true;
+ if (s != null){
+ try {
+ Exception exception = null;
+ DateTimeOffset dto;
+
+ return CoreParse (s, provider, styles, out result, out dto, false, ref exception);
+ } catch {}
+ }
+ result = MinValue;
+ return false;
}
public static bool TryParseExact (string s, string format,
- IFormatProvider fp,
+ IFormatProvider provider,
DateTimeStyles style,
out DateTime result)
{
string[] formats;
-
formats = new string [1];
formats[0] = format;
- return TryParseExact (s, formats, fp, style, out result);
+ return TryParseExact (s, formats, provider, style, out result);
}
public static bool TryParseExact (string s, string[] formats,
- IFormatProvider fp,
+ IFormatProvider provider,
DateTimeStyles style,
out DateTime result)
{
- DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (fp);
+ try {
+ DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
- bool longYear = false;
- return ParseExact (s, formats, dfi, style, out result, true, ref longYear);
+ bool longYear = false;
+ Exception e = null;
+ return ParseExact (s, formats, dfi, style, out result, true, ref longYear, false, ref e);
+ } catch {
+ result = MinValue;
+ return false;
+ }
}
-#endif
private static bool ParseExact (string s, string [] formats,
- DateTimeFormatInfo dfi, DateTimeStyles style, out DateTime ret,
- bool exact, ref bool longYear)
+ DateTimeFormatInfo dfi, DateTimeStyles style, out DateTime ret,
+ bool exact, ref bool longYear,
+ bool setExceptionOnError, ref Exception exception)
{
int i;
bool incompleteFormat = false;
DateTime result;
string format = formats[i];
if (format == null || format == String.Empty)
- throw new FormatException ("Invalid Format String");
+ break;
- if (_DoParse (s, formats[i], null, exact, out result, dfi, style, false, ref incompleteFormat, ref longYear)) {
+ DateTimeOffset dto;
+ if (_DoParse (s, formats[i], null, exact, out result, out dto, dfi, style, false, ref incompleteFormat, ref longYear)) {
ret = result;
return true;
}
}
+
+ if (setExceptionOnError)
+ exception = new FormatException ("Invalid format string");
ret = DateTime.MinValue;
return false;
}
- public TimeSpan Subtract(DateTime dt)
+ public TimeSpan Subtract (DateTime value)
{
- return new TimeSpan(ticks.Ticks) - dt.ticks;
+ return new TimeSpan (ticks.Ticks) - value.ticks;
}
- public DateTime Subtract(TimeSpan ts)
+ public DateTime Subtract(TimeSpan value)
{
TimeSpan newticks;
- newticks = (new TimeSpan (ticks.Ticks)) - ts;
- DateTime ret = new DateTime(true,newticks);
-#if NET_2_0
+ newticks = (new TimeSpan (ticks.Ticks)) - value;
+ DateTime ret = new DateTime (true,newticks);
ret.kind = kind;
-#endif
return ret;
}
return(universalTime.Ticks - w32file_epoch);
}
-#if NET_1_1
public long ToFileTimeUtc()
{
if (Ticks < w32file_epoch) {
return (Ticks - w32file_epoch);
}
-#endif
public string ToLongDateString()
{
return ToString ("G", null);
}
- public string ToString (IFormatProvider fp)
+ public string ToString (IFormatProvider provider)
{
- return ToString (null, fp);
+ return ToString (null, provider);
}
public string ToString (string format)
return ToString (format, null);
}
- public string ToString (string format, IFormatProvider fp)
+ public string ToString (string format, IFormatProvider provider)
{
- DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance(fp);
+ DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
if (format == null || format == String.Empty)
format = "G";
public static DateTime operator +(DateTime d, TimeSpan t)
{
DateTime ret = new DateTime (true, d.ticks + t);
-#if NET_2_0
ret.kind = d.kind;
-#endif
return ret;
}
public static DateTime operator -(DateTime d,TimeSpan t)
{
DateTime ret = new DateTime (true, d.ticks - t);
-#if NET_2_0
ret.kind = d.kind;
-#endif
return ret;
}
throw new InvalidCastException();
}
- object IConvertible.ToType (Type conversionType, IFormatProvider provider)
+ object IConvertible.ToType (Type targetType, IFormatProvider provider)
{
- if (conversionType == null)
- throw new ArgumentNullException ("conversionType");
+ if (targetType == null)
+ throw new ArgumentNullException ("targetType");
- if (conversionType == typeof (DateTime))
+ if (targetType == typeof (DateTime))
return this;
- else if (conversionType == typeof (String))
+ else if (targetType == typeof (String))
return this.ToString (provider);
- else if (conversionType == typeof (Object))
+ else if (targetType == typeof (Object))
return this;
else
throw new InvalidCastException();
{
throw new InvalidCastException();
}
-
+
UInt32 IConvertible.ToUInt32(IFormatProvider provider)
{
throw new InvalidCastException();
{
throw new InvalidCastException();
}
+
+ void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ long t = ticks.Ticks;
+ info.AddValue ("ticks", t);
+
+ // This is the new .NET format, encodes the kind on the top bits
+ info.AddValue ("dateData", t | (((uint)kind) << 62));
+ }
+
}
}