问题
JSON
{
"title":"Mozilla Firefox",
"id":24,
"parent":2,
"dateAdded":1356753810000000,
"lastModified":1356753810000000,
"type":"text/x-moz-place-container",
"children":[]
}
C#
class Bookmark
{
public string title;
public string id;
[JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))]
public DateTime dateAdded;
[JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))]
public DateTime lastModified;
public string type;
public string root;
public long parent;
public List<Bookmark> children;
}
private static void Main(string[] args)
{
var json = File.ReadAllText(@"T:/bookmarks-2013-11-13.json");
var bookmarks = JsonConvert.DeserializeObject<Bookmark>(json);
}
I get an exception when I try running this,
Additional information: Error reading date. Unexpected token: Integer. Path 'dateAdded'
I thought by using the JavaScriptDateTimeConverter
, JSON.NET could figure out how to deserialize those unix timestamps (ms μs since epoch). What's the easiest way to do this?
Having trouble finding documentation on the converters... it probably wouldn't be too hard to write one myself if necessary.
Edit: Those are actually microseconds, not milliseconds.
回答1:
I cleaned up Cris's solution a tad and implemented WriteJson
:
class Bookmark
{
public string title;
public long id;
[JsonConverter(typeof(MicrosecondEpochConverter))]
public DateTime dateAdded;
[JsonConverter(typeof(MicrosecondEpochConverter))]
public DateTime lastModified;
public string type;
public string root;
public long parent;
public List<Bookmark> children;
public string uri;
public override string ToString()
{
return string.Format("{0} - {1}", title, uri);
}
}
public class MicrosecondEpochConverter : DateTimeConverterBase
{
private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue(((DateTime)value - _epoch).TotalMilliseconds + "000");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null) { return null; }
return _epoch.AddMilliseconds((long)reader.Value / 1000d);
}
}
internal class Program
{
private static void Main(string[] args)
{
var jsonString = File.ReadAllText(@"T:/bookmarks-2013-11-13.json");
var rootMark = JsonConvert.DeserializeObject<Bookmark>(jsonString);
var ret = JsonConvert.SerializeObject(rootMark);
}
}
回答2:
You can create a custom DateTime converter
var bookmarks = JsonConvert.DeserializeObject<Bookmark>(json,
new MyDateTimeConverter());
public class MyDateTimeConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var t = long.Parse((string)reader.Value);
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(t);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
another approach is to double annotate the class member,
[JsonProperty(PropertyName="dateAdded")]
[JsonConverter(typeof(JavaScriptDateTimeConverter))]
public DateTime dateAdded;
回答3:
There's a built-in way to convert from unix timestamp to DateTime without having to write your own class:
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime lastModified;
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Converters_UnixDateTimeConverter.htm
The annotation in Cris' answer is not correct, as JavaScriptDateTimeConverter
is for Date(52231943)
format rather than the Unix timestamp from the OP.
I realize this question is a few years old now so it's highly likely this class has been added since this question has been asked, but this may help anyone who comes across the same issue.
回答4:
Hmmm ...the tricky bit is that DateTime constructor doesn't accept a timestamp as an argument.
Here's a solution from this article: How to convert a Unix timestamp to DateTime and vice versa?
public static DateTime UnixTimeStampToDateTime( double unixTimeStamp )
{
// Unix timestamp is seconds past epoch
System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0);
dtDateTime = dtDateTime.AddSeconds( unixTimeStamp ).ToLocalTime();
return dtDateTime;
}
You'll have to call this, probably best by using default constructor in your class, or having another property that will return this in it's get
method.
回答5:
That is how I did it and it worked
In my ViewModel I have a Public property of Type DateTime
Public DateTime TimeToBeShown {get; set;}
In My Model, I have the public property of type Long which gets the date from API as a JSON Format.
Public long DateThatIsComingAsJsonFormat {get; set;}
var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeToBeShown=dateTime.AddSeconds(somethingfromloop.CreatedTime).ToLocalTime();
Bind to TimeToBeShown in Xaml
来源:https://stackoverflow.com/questions/19971494/how-to-deserialize-a-unix-timestamp-%ce%bcs-to-a-datetime-from-json