using System; using System.Runtime.CompilerServices; namespace CPF.Windows.Json.Deserialize { internal class DateTimeResolve : DefaultJsonResolve { [FuncLable(FuncType.SameType)] #if !Net4 [MethodImpl(MethodImplOptions.AggressiveInlining)] #endif internal unsafe static DateTime ReadDateTime(JsonReader reader, JsonDeserializeHandler handler) { reader.ReadQuotes(); char* ip = reader.Pointer; char c = ip[0]; if (c >= '0' && c <= '9') { //https://tools.ietf.org/html/rfc3339 //http://en.wikipedia.org/wiki/ISO_8601 //\"2019-02-11T18:42:04.0068385Z\" //\"2019-02-11T18:42:04.0068385+08:00\" return ReadISO8601Date(reader); } else if (c == '\\') { // "\/Date(628318530718)\/" return ReadMicrosoftDate(reader, handler); } else { //Mon, 11 Feb 2019 18:39:32 GMT return ReadRFC1123DateTime(reader); } } #if !Net4 [MethodImpl(MethodImplOptions.AggressiveInlining)] #endif static unsafe DateTime ReadMicrosoftDate(JsonReader reader, JsonDeserializeHandler handler) { if (!reader.StrCompair("\\/Date(")) goto Throw; long l = PrimitiveResolve.ReadLong(reader, handler); DateTime dt = new DateTime(l * 10000L + 621355968000000000L); if (reader.StrCompair(")\\/\"")) return dt; Throw: throw new JsonDeserializationTypeResolutionException( reader, typeof(DateTime), "Unresolvable Date"); } #if !Net4 [MethodImpl(MethodImplOptions.AggressiveInlining)] #endif static unsafe DateTime ReadISO8601Date(JsonReader reader) { // ISO8601 / RFC3339 (the internet "profile"* of ISO8601) is a plague // See: http://en.wikipedia.org/wiki/ISO_8601 & // http://tools.ietf.org/html/rfc3339 // *is bullshit // Here are the possible formats for dates // YYYY-MM-DD // YYYY-MM // YYYY-DDD (ordinal date) // YYYY-Www (week date, the W is a literal) // YYYY-Www-D // YYYYMMDD // YYYYWww // YYYYWwwD // YYYYDDD // Here are the possible formats for times // hh // hh:mm // hhmm // hh:mm:ss // hhmmss // hh,fff* // hh:mm,fff* // hhmm,fff* // hh:mm:ss,fff* // hhmmss,fff* // hh.fff* // hh:mm.fff* // hhmm.fff* // hh:mm:ss.fff* // hhmmss.fff* // * arbitrarily many (technically an "agreed upon" number, I'm agreeing on 7 because that's out to a Tick) // Here are the possible formats for timezones // Z // +hh // +hh:mm // +hhmm // -hh // -hh:mm // -hhmm // they are concatenated to form a full instant, with T as a separator between date & time // i.e. T