Skip to content

Commit 373a0a3

Browse files
committed
ISO and JavaScript object date handling
1 parent 2871719 commit 373a0a3

File tree

4 files changed

+99
-32
lines changed

4 files changed

+99
-32
lines changed

RestSharp.Tests/JsonTests.cs

+32-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
using Newtonsoft.Json.Linq;
1717
using RestSharp.Deserializers;
1818
using Xunit;
19+
using Newtonsoft.Json;
20+
using Newtonsoft.Json.Converters;
1921

2022
namespace RestSharp.Tests
2123
{
@@ -90,10 +92,24 @@ public void Ignore_ReadOnly_Property_That_Exists_In_Data() {
9092
}
9193

9294
[Fact]
93-
public void Can_Deserialize_Names_With_Underscores_On_Default_Root() {
95+
public void Can_Deserialize_Iso_Json_Dates() {
96+
var doc = CreateIsoDateJson();
97+
var d = new JsonDeserializer();
98+
var bd = d.Deserialize<Birthdate>(doc);
99+
100+
Assert.Equal(new DateTime(1910, 9, 25, 9, 30, 25, DateTimeKind.Utc), bd.Value);
101+
}
102+
103+
[Fact]
104+
public void Can_Deserialize_JScript_Json_Dates() {
105+
var doc = CreateJScriptDateJson();
106+
var d = new JsonDeserializer();
107+
var bd = d.Deserialize<Birthdate>(doc);
108+
109+
Assert.Equal(new DateTime(1910, 9, 25, 9, 30, 25, DateTimeKind.Utc), bd.Value);
94110
}
95111

96-
private static string CreateJsonWithUnderscores() {
112+
private string CreateJsonWithUnderscores() {
97113
var doc = new JObject();
98114
doc["name"] = "John Sheehan";
99115
doc["start_date"] = new DateTime(2009, 9, 25, 0, 6, 1);
@@ -129,8 +145,21 @@ private static string CreateJsonWithUnderscores() {
129145
return doc.ToString();
130146
}
131147

148+
private string CreateIsoDateJson() {
149+
var bd = new Birthdate();
150+
bd.Value = new DateTime(1910, 9, 25, 9, 30, 25, DateTimeKind.Utc);
151+
152+
return JsonConvert.SerializeObject(bd, new IsoDateTimeConverter());
153+
}
154+
155+
private string CreateJScriptDateJson() {
156+
var bd = new Birthdate();
157+
bd.Value = new DateTime(1910, 9, 25, 9, 30, 25, DateTimeKind.Utc);
158+
159+
return JsonConvert.SerializeObject(bd, new JavaScriptDateTimeConverter());
160+
}
132161

133-
private static string CreateJson() {
162+
private string CreateJson() {
134163
var doc = new JObject();
135164
doc["Name"] = "John Sheehan";
136165
doc["StartDate"] = new DateTime(2009, 9, 25, 0, 6, 1);

RestSharp.Tests/SampleClasses.cs

+5
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,9 @@ public class FoeList : List<Foe>
7272
{
7373
public string Team { get; set; }
7474
}
75+
76+
public class Birthdate
77+
{
78+
public DateTime Value { get; set; }
79+
}
7580
}

RestSharp/Extensions.cs

+61-24
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Globalization;
1717
using System.IO;
1818
using System.Text.RegularExpressions;
19+
using System.Collections.Generic;
1920

2021
namespace RestSharp
2122
{
@@ -47,39 +48,75 @@ public static bool IsSubclassOfRawGeneric(this Type toCheck, Type generic) {
4748
}
4849

4950
public static DateTime ParseJsonDate(this string input) {
50-
if (input.Contains("/Date(")) {
51-
var regex = new Regex(@"\\/Date\((\d+)(-|\+)?([0-9]{4})?\)\\/");
52-
if (regex.IsMatch(input)) {
53-
var matches = regex.Matches(input);
54-
var match = matches[0];
55-
var ms = Convert.ToInt64(match.Groups[1].Value);
56-
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
57-
var dt = epoch.AddMilliseconds(ms);
58-
59-
// adjust if time zone modifier present
60-
if (match.Groups[3] != null) {
61-
var mod = DateTime.ParseExact(match.Groups[3].Value, "hhmm", CultureInfo.InvariantCulture);
62-
if (match.Groups[2].Value == "+") {
63-
dt = dt.Add(mod.TimeOfDay);
64-
}
65-
else {
66-
dt = dt.Subtract(mod.TimeOfDay);
67-
}
68-
}
51+
input = input.Replace("\n", "");
52+
input = input.Replace("\r", "");
6953

70-
return dt;
71-
}
54+
if (input.StartsWith("\"")) {
55+
// remove leading/trailing quotes
56+
input = input.Substring(1, input.Length - 2);
57+
}
58+
59+
if (input.Contains("/Date(")) {
60+
return ExtractDate(input, @"\\/Date\((-?\d+)(-|\+)?([0-9]{4})?\)\\/");
7261
}
7362
else if (input.Contains("new Date(")) {
74-
// TODO: implement parsing
63+
input = input.Replace(" ", "");
64+
// because all whitespace is removed, match against newDate( instead of new Date(
65+
return ExtractDate(input, @"newDate\((-?\d+)*\)");
66+
}
67+
else if (input.Matches(@"([0-9-])*T([0-9\:]*)Z?")) {
68+
return ParseIso8601Date(input);
7569
}
76-
else if (input.Matches(@"([0-9-])*T([0-9\:]*)Z")) {
77-
// TODO: implement parsing
70+
71+
return default(DateTime);
72+
}
73+
74+
private static DateTime ParseIso8601Date(string input) {
75+
var formats = new string[] {
76+
"u",
77+
"s",
78+
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
79+
"yyyy-MM-ddTHH:mm:ssZ",
80+
"yyyy-MM-dd HH:mm:ssZ",
81+
"yyyy-MM-ddTHH:mm:ss",
82+
"yyyy-MM-ddTHH:mm:sszzzzzz"
83+
};
84+
85+
DateTime date;
86+
if (DateTime.TryParseExact(input, formats,
87+
CultureInfo.InvariantCulture,
88+
DateTimeStyles.None, out date)) {
89+
return date;
7890
}
7991

8092
return default(DateTime);
8193
}
8294

95+
private static DateTime ExtractDate(string input, string pattern) {
96+
DateTime dt = DateTime.MinValue;
97+
var regex = new Regex(pattern);
98+
if (regex.IsMatch(input)) {
99+
var matches = regex.Matches(input);
100+
var match = matches[0];
101+
var ms = Convert.ToInt64(match.Groups[1].Value);
102+
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
103+
dt = epoch.AddMilliseconds(ms);
104+
105+
// adjust if time zone modifier present
106+
if (match.Groups.Count > 2 && match.Groups[3] != null) {
107+
var mod = DateTime.ParseExact(match.Groups[3].Value, "hhmm", CultureInfo.InvariantCulture);
108+
if (match.Groups[2].Value == "+") {
109+
dt = dt.Add(mod.TimeOfDay);
110+
}
111+
else {
112+
dt = dt.Subtract(mod.TimeOfDay);
113+
}
114+
}
115+
116+
}
117+
return dt;
118+
}
119+
83120
public static bool Matches(this string input, string pattern) {
84121
return Regex.IsMatch(input, pattern);
85122
}

RestSharp/RestRequest.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace RestSharp
2222
public class RestRequest
2323
{
2424
public RestRequest() {
25-
Initialize();
25+
Parameters = new List<Parameter>();
2626
}
2727

2828
public RestRequest(Method verb)
@@ -41,10 +41,6 @@ public RestRequest(string action, Method verb)
4141
Verb = verb;
4242
}
4343

44-
private void Initialize() {
45-
Parameters = new List<Parameter>();
46-
}
47-
4844
public void AddObject(object obj, params string[] whitelist) {
4945
// automatically create parameters from object props
5046
var type = obj.GetType();

0 commit comments

Comments
 (0)