Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2010-09-12 07:39:39 +0400
committerJamesNK <james@newtonking.com>2010-09-12 07:39:39 +0400
commit235770442ac9d8ee3bcf3428c5202dde431cecca (patch)
tree2cfe53fafa430bc2cb9cdf70d133a0e7e78c6043 /Src/Newtonsoft.Json
parent11ce71ee8b72a0892cbfdfa22d5343e0dffa7fa8 (diff)
-Added JsonReader.ReadAsDateTimeOffset
-Fixed losing timezone information when deserializing DateTimeOffsets
Diffstat (limited to 'Src/Newtonsoft.Json')
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonReader.cs17
-rw-r--r--Src/Newtonsoft.Json/JsonReader.cs8
-rw-r--r--Src/Newtonsoft.Json/JsonTextReader.cs77
-rw-r--r--Src/Newtonsoft.Json/JsonValidatingReader.cs14
-rw-r--r--Src/Newtonsoft.Json/Linq/JTokenReader.cs16
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs12
6 files changed, 130 insertions, 14 deletions
diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs
index 4b94357..8db767a 100644
--- a/Src/Newtonsoft.Json/Bson/BsonReader.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -150,6 +150,23 @@ namespace Newtonsoft.Json.Bson
return (byte[])Value;
}
+#if !NET20
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="DateTimeOffset"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="DateTimeOffset"/>.
+ /// </returns>
+ public override DateTimeOffset ReadAsDateTimeOffset()
+ {
+ Read();
+ if (TokenType != JsonToken.Date)
+ throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+
+ return new DateTimeOffset((DateTime)Value);
+ }
+#endif
+
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs
index d516578..2ec2883 100644
--- a/Src/Newtonsoft.Json/JsonReader.cs
+++ b/Src/Newtonsoft.Json/JsonReader.cs
@@ -210,6 +210,14 @@ namespace Newtonsoft.Json
/// <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.</returns>
public abstract byte[] ReadAsBytes();
+#if !NET20
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="DateTimeOffset"/>.
+ /// </summary>
+ /// <returns>A <see cref="DateTimeOffset"/>.</returns>
+ public abstract DateTimeOffset ReadAsDateTimeOffset();
+#endif
+
/// <summary>
/// Skips the children of the current token.
/// </summary>
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 9121732..7b45688 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -41,7 +41,10 @@ namespace Newtonsoft.Json
private enum ReadType
{
Read,
- ReadAsBytes
+ ReadAsBytes,
+#if !NET20
+ ReadAsDateTimeOffset
+#endif
}
private readonly TextReader _reader;
@@ -190,6 +193,22 @@ namespace Newtonsoft.Json
return new JsonReaderException(message, null, _currentLineNumber, _currentLinePosition);
}
+ private TimeSpan ReadOffset(string offsetText)
+ {
+ bool negative = (offsetText[0] == '-');
+
+ int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+ int minutes = 0;
+ if (offsetText.Length >= 5)
+ minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+
+ TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
+ if (negative)
+ offset = offset.Negate();
+
+ return offset;
+ }
+
private void ParseDate(string text)
{
string value = text.Substring(6, text.Length - 8);
@@ -200,30 +219,44 @@ namespace Newtonsoft.Json
if (index == -1)
index = value.IndexOf('-', 1);
+ TimeSpan offset = TimeSpan.Zero;
+
if (index != -1)
{
kind = DateTimeKind.Local;
+ offset = ReadOffset(value.Substring(index));
value = value.Substring(0, index);
}
long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
+
DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
- DateTime dateTime;
- switch (kind)
+#if !NET20
+ if (_readType == ReadType.ReadAsDateTimeOffset)
{
- case DateTimeKind.Unspecified:
- dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
- break;
- case DateTimeKind.Local:
- dateTime = utcDateTime.ToLocalTime();
- break;
- default:
- dateTime = utcDateTime;
- break;
+ SetToken(JsonToken.Date, new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset));
}
+ else
+#endif
+ {
+ DateTime dateTime;
- SetToken(JsonToken.Date, dateTime);
+ switch (kind)
+ {
+ case DateTimeKind.Unspecified:
+ dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
+ break;
+ case DateTimeKind.Local:
+ dateTime = utcDateTime.ToLocalTime();
+ break;
+ default:
+ dateTime = utcDateTime;
+ break;
+ }
+
+ SetToken(JsonToken.Date, dateTime);
+ }
}
private const int LineFeedValue = StringUtils.LineFeed;
@@ -299,6 +332,24 @@ namespace Newtonsoft.Json
throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
}
+#if !NET20
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="DateTimeOffset"/>.
+ /// </summary>
+ /// <returns>A <see cref="DateTimeOffset"/>.</returns>
+ public override DateTimeOffset ReadAsDateTimeOffset()
+ {
+ _readType = ReadType.ReadAsDateTimeOffset;
+ if (!ReadInternal())
+ throw CreateJsonReaderException("Unexpected end when reading date: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+
+ if (TokenType == JsonToken.Date)
+ return (DateTimeOffset)Value;
+
+ throw CreateJsonReaderException("Unexpected token when reading date: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
+ }
+#endif
+
private bool ReadInternal()
{
while (true)
diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs
index 4a46a90..b90abc6 100644
--- a/Src/Newtonsoft.Json/JsonValidatingReader.cs
+++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs
@@ -318,6 +318,20 @@ namespace Newtonsoft.Json
return data;
}
+#if !NET20
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="DateTimeOffset"/>.
+ /// </summary>
+ /// <returns>A <see cref="DateTimeOffset"/>.</returns>
+ public override DateTimeOffset ReadAsDateTimeOffset()
+ {
+ DateTimeOffset dateTimeOffset = _reader.ReadAsDateTimeOffset();
+
+ ValidateCurrentToken();
+ return dateTimeOffset;
+ }
+#endif
+
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
diff --git a/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
index b09037d..7bd68fe 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
@@ -54,6 +54,22 @@ namespace Newtonsoft.Json.Linq
throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
+#if !NET20
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="DateTimeOffset"/>.
+ /// </summary>
+ /// <returns>A <see cref="DateTimeOffset"/>.</returns>
+ public override DateTimeOffset ReadAsDateTimeOffset()
+ {
+ Read();
+
+ if (TokenType == JsonToken.Date)
+ return new DateTimeOffset((DateTime)Value);
+
+ throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+ }
+#endif
+
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index 4ca5afb..2ab3295 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -928,10 +928,20 @@ namespace Newtonsoft.Json.Serialization
continue;
}
- if (property.PropertyType == typeof(byte[]))
+ // don't read properties with converters as a specific value
+ // the value might be a string which will then get converted which will error if read as date for example
+ bool hasConverter = (GetConverter(GetContractSafe(property.PropertyType), property.Converter) != null);
+
+ if (property.PropertyType == typeof(byte[]) && !hasConverter)
{
reader.ReadAsBytes();
}
+#if !NET20
+ else if (property.PropertyType == typeof(DateTimeOffset) && !hasConverter)
+ {
+ reader.ReadAsDateTimeOffset();
+ }
+#endif
else
{
if (!reader.Read())