internal static string ToAttributeValue(DateTimeStyles styles) { string[] textArray = new string[basicRecArray.Length]; int count = 0; // Composite must match exactly for (int i = 0; i < compositeRecArray.Length; i++) { if (styles == compositeRecArray[i].Styles) { textArray[count++] = compositeRecArray[i].Text; break; } } if (count > 0) { return(FtCommaText.Get(textArray, 0, count)); } else { foreach (BasicRec rec in basicRecArray) { if (styles.HasFlag(rec.Flag)) { textArray[count++] = rec.Text; } } return(FtCommaText.Get(textArray, 0, count)); } }
/// <summary> /// Converts a <see cref="DateTime"/> object to string. /// </summary> /// <param name="date">The <see cref="DateTime"/> object to convert.</param> /// <param name="format">The output string format.</param> /// <param name="style">The formatting style.</param> /// <returns> /// A string representation of the <paramref name="date"/> value. /// </returns> public static string ToString(DateTime date, string format, DateTimeStyles style) { if (date == null) throw new ArgumentNullException(nameof(date)); if (format == null) throw new ArgumentNullException(nameof(format)); if (string.IsNullOrEmpty(format)) throw new FormatException(string.Format(RS.ArgumentIsEmptyString, nameof(format))); TimeSpan offset; if (date.Kind == DateTimeKind.Utc) offset = TimeSpan.Zero; else if (date.Kind == DateTimeKind.Unspecified && style.HasFlag(DateTimeStyles.AssumeUniversal)) offset = TimeSpan.Zero; else offset = GetUtcOffset(DateTime.Now); // E = Microsoft .NET JSON serializer // ref: http://www.abstractpath.com/2013/the-ridiculousness-of-microsoft-net-json-dates // example: /Date(700000+0500)/ // // The 700000 part is epoch time, but in ms instead of ticks. You need to * TimeSpan.TicksPerMilliseconds before // feeding it to the epoch calculation. // +0500 is just the tz of the machine that did the serialization. do not use it when deserializing // bcos the time is already in utc. if (format.Length == 1) { if (format[0] == 'E') return DateToString(date, offset, true, true); else if (format[0] == 'e') return DateToEpochTime(date, offset); else if (format[0] == 'i') return DateToISOFormat(date, offset, style.HasFlag(DateTimeStyles.AdjustToUniversal)); } return date.ToString(format); }
/// <summary> /// Converts a <see cref="DateTimeOffset"/> object to string. /// </summary> /// <param name="offset">The <see cref="DateTimeOffset"/> object to convert.</param> /// <param name="format">The output string format.</param> /// <param name="style">The formatting style.</param> /// <returns> /// A string representation of the <paramref name="offset"/> value. /// </returns> public static string ToString(DateTimeOffset offset, string format, DateTimeStyles style) { if (offset == null) throw new ArgumentNullException(nameof(offset)); if (format == null) throw new ArgumentNullException(nameof(format)); if (string.IsNullOrEmpty(format)) throw new FormatException(string.Format(RS.ArgumentIsEmptyString, nameof(format))); if (format.Length == 1) { if (format[0] == 'E') return DateToString(offset.DateTime, offset.Offset, true, true); else if (format[0] == 'e') return DateToEpochTime(offset.DateTime, offset.Offset); else if (format[0] == 'i') return DateToISOFormat(offset.DateTime, offset.Offset, style.HasFlag(DateTimeStyles.AdjustToUniversal)); } return offset.ToString(format); }
private static DateTime StringToDate(string value, string dateFormatString, char dateFormat, out TimeSpan offset, IFormatProvider provider, DateTimeStyles style, bool msPrecision = false) { offset = TimeSpan.Zero; DateTime dt; if (!string.IsNullOrEmpty(dateFormatString)) return DateTime.ParseExact(value, dateFormatString, provider, style); bool negativeOffset = false; int signIndex = -1; if (style.HasFlag(DateTimeStyles.AllowWhiteSpaces)) value = value.Trim(); else if (style.HasFlag(DateTimeStyles.AllowLeadingWhite)) value = value.TrimStart(); else if (style.HasFlag(DateTimeStyles.AllowTrailingWhite)) value = value.TrimEnd(); if (style.HasFlag(DateTimeStyles.AssumeLocal) && style.HasFlag(DateTimeStyles.AssumeUniversal)) throw new ArgumentException(string.Format(RS.InvalidDateTimeStylesCombo, "AssumeLocal", "AssumeUniversal"), nameof(style)); if (style.HasFlag(DateTimeStyles.AdjustToUniversal) && style.HasFlag(DateTimeStyles.RoundtripKind)) throw new ArgumentException(string.Format(RS.InvalidDateTimeStylesCombo, "AdjustToUniversal", "RoundtripKind"), nameof(style)); if (dateFormat == 'e' || dateFormat == 'E') { if (value == "-62135596800") return DateTime.MinValue; else if (value == "253402300800") return DateTime.MaxValue; if (value[0] == '-') signIndex = value.Substring(1).LastIndexOf('-'); else if (value[0] == '+') throw new FormatException(RS.EpochTimeCannotStartWithPlus); else signIndex = value.LastIndexOf('-'); if (signIndex >= 0) negativeOffset = true; else signIndex = value.LastIndexOf('+'); long unixTimestamp = signIndex < 0 ? ToInt64(value) : ToInt64(value.Substring(0, signIndex)); if (unixTimestamp == -62135596800) return DateTime.MinValue; else if (unixTimestamp == 253402300800) return DateTime.MaxValue; dt = new DateTime(s_unixEpochTicks, System.DateTimeKind.Utc); if (dateFormat == 'E' && msPrecision) dt = dt.AddTicks(unixTimestamp * TimeSpan.TicksPerMillisecond); else dt = dt.AddTicks(unixTimestamp); // AdjustToUniversal || RoundtripKind => offset = 0; time as utc // otherwise => offset = oslocal; time as utc convert to oslocal if (style.HasFlag(DateTimeStyles.AdjustToUniversal) || style.HasFlag(DateTimeStyles.RoundtripKind)) { return dt; } else { offset = GetUtcOffset(DateTime.Now); return dt.ToLocalTime(); } } if (dateFormat == 'i') { string dateText = value.Substring(0, 19); int diff = value.Length - dateText.Length; bool hasOffset = diff > 0; if (!hasOffset) { // unspecified dt = DateTime.ParseExact(dateText, "s", provider, DateTimeStyles.None); if (style.HasFlag(DateTimeStyles.AdjustToUniversal)) { // AdjustToUniversal && AssumeLocal => offset = 0; time as oslocal convert to utc // AdjustToUniversal && AssumeUniversal => offset = 0; time kind -> utc // AdjustToUniversal only => offset = oslocal; time as unspecified if (style.HasFlag(DateTimeStyles.AssumeLocal)) { return dt.ToUniversalTime(); } else if (style.HasFlag(DateTimeStyles.AssumeUniversal)) { return new DateTime(dt.Ticks, DateTimeKind.Utc); } else { offset = GetUtcOffset(DateTime.Now); return dt; } } else { // AssumeLocal => offset = oslocal; time kind -> local // AssumeUniversal => offset = 0; time as utc convert to local // otherwise => offset = oslocal; time kind unspecified if (style.HasFlag(DateTimeStyles.AssumeLocal)) { offset = GetUtcOffset(DateTime.Now); return new DateTime(dt.Ticks, DateTimeKind.Local); } else if (style.HasFlag(DateTimeStyles.AssumeUniversal)) { offset = GetUtcOffset(DateTime.Now); return dt.ToLocalTime(); } else { offset = GetUtcOffset(DateTime.Now); return dt; } } } string utcOffsetText; if (value[dateText.Length] == '.') { if (diff < 2) throw new FormatException(string.Format(RS.IsoDateExpectNumberAfterDot, value)); utcOffsetText = value.Substring(dateText.Length + 1, diff - 1); if (utcOffsetText[0] < 48 || utcOffsetText[0] > 57) throw new FormatException(string.Format(RS.IsoDateExpectNumberAfterDot, value)); } else { utcOffsetText = value.Substring(dateText.Length, diff); if (diff == 1 && utcOffsetText[0] != 'Z') throw new FormatException(string.Format(RS.IsoDateExpectEndWithZ, value)); else if (utcOffsetText[0] != '+' && utcOffsetText[0] != '-') throw new FormatException(string.Format(RS.IsoDateExpectContainPlusMinus, value)); } signIndex = utcOffsetText.IndexOf('-'); if (signIndex >= 0) negativeOffset = true; else signIndex = utcOffsetText.IndexOf('+'); // Ends with Z if (utcOffsetText[utcOffsetText.Length - 1] == 'Z') { if (signIndex >= 0) throw new FormatException(string.Format(RS.IsoDateExpectNotBothPlusMinus, value)); dt = new DateTime(DateTime.ParseExact(dateText, "s", provider, DateTimeStyles.AdjustToUniversal).Ticks, DateTimeKind.Utc); // 2015-05-31T00:00Z // 2015-05-31T00:00.3123Z if (utcOffsetText.Length > 1) dt = dt.AddTicks(ToInt32(utcOffsetText.Substring(0, utcOffsetText.Length - 1))); if (style.HasFlag(DateTimeStyles.AdjustToUniversal) || style.HasFlag(DateTimeStyles.RoundtripKind)) { return dt; } else { offset = GetUtcOffset(DateTime.Now); return dt.ToLocalTime(); } } // Doesn't end with Z and no +/- if (signIndex < 0) { dt = new DateTime(DateTime.ParseExact(dateText, "s", provider, DateTimeStyles.AdjustToUniversal).Ticks, DateTimeKind.Unspecified); dt = dt.AddTicks(ToInt32(utcOffsetText)); if (style.HasFlag(DateTimeStyles.AdjustToUniversal)) { if (style.HasFlag(DateTimeStyles.AssumeUniversal)) { return new DateTime(dt.Ticks, DateTimeKind.Utc); } else if (style.HasFlag(DateTimeStyles.AssumeLocal)) { return dt.ToUniversalTime(); } else { offset = GetUtcOffset(DateTime.Now); return dt; } } else { if (style.HasFlag(DateTimeStyles.AssumeUniversal)) { offset = GetUtcOffset(DateTime.Now); return dt.ToLocalTime(); } else if (style.HasFlag(DateTimeStyles.AssumeLocal)) { offset = GetUtcOffset(DateTime.Now); return new DateTime(dt.Ticks, DateTimeKind.Local); } else { offset = GetUtcOffset(DateTime.Now); return dt; } } } // From here we are sure text has +/- sign and doesn't end with Z dt = new DateTime(DateTime.ParseExact(dateText, "s", provider, DateTimeStyles.AssumeLocal).Ticks, DateTimeKind.Local); dt = dt.AddTicks(ToInt32(utcOffsetText.Substring(0, signIndex))); // hrs and minutes are always positive numbers. // we use `negativeOffset` flag to determine whether they should be + or -. int hours = utcOffsetText.Length >= (signIndex + 3) ? ToInt32(utcOffsetText.Substring(signIndex + 1, 2)) : 0; int minutes = utcOffsetText.Length >= (signIndex + 5) ? ToInt32(utcOffsetText.Substring(signIndex + 3, 2)) : 0; // say we are at +0800. ISO8601 time part is the time at +0800. // so to get utc, we need to minus 8 hours from that time part. // conversely, at -0800, we need to add 8 hours to get to utc. // since `hours` and `minutes` are always positive, we only need to flip it // when dealing with + offsets. if (!negativeOffset) { hours *= -1; minutes *= -1; } // adjust to utc => convert to utc // roundtrip => update offset and return date as local // otherwise => convert to utc and then convert to oslocal if (style.HasFlag(DateTimeStyles.AdjustToUniversal)) { offset = TimeSpan.Zero; return new DateTime(dt.AddHours(hours).AddMinutes(minutes).Ticks, DateTimeKind.Utc); } else if (style.HasFlag(DateTimeStyles.RoundtripKind)) { offset = negativeOffset ? new TimeSpan(hours * -1, minutes * -1, 0) : new TimeSpan(hours, minutes, 0); return dt; } else { offset = GetUtcOffset(DateTime.Now); return new DateTime(dt.AddHours(hours).AddMinutes(minutes).Ticks, DateTimeKind.Utc).ToLocalTime(); } } throw new FormatException(string.Format(RS.UnsupportedFormatSpecifier, dateFormat)); }