15

What is the format of the "creation_date" that is returned from a search of questions? I've been looking all over here and can't figure it out. I want to convert it to a regular DateTime object.

I am using Json.NET but since I don't know the format I'm looking for it's difficult.

Are there any code snippets out there?

2 Answers 2

12

This is a take on a class that has been floating around for a while. I first saw it in kevin's first api.

You can use this on all values that are declared as 'unix timestamp', both request and response

    ///<summary>
    ///</summary>
    public static class UnixDateTimeHelper
    {
        private const string InvalidUnixEpochErrorMessage = "Unix epoc starts January 1st, 1970";
        /// <summary>
        ///   Convert a long into a DateTime
        /// </summary>
        public static DateTime FromUnixTime(this Int64 self)
        {
            var ret = new DateTime(1970, 1, 1);
            return ret.AddSeconds(self);
        }

        /// <summary>
        ///   Convert a DateTime into a long
        /// </summary>
        public static Int64 ToUnixTime(this DateTime self)
        {

            if (self == DateTime.MinValue)
            {
                return 0;
            }

            var epoc = new DateTime(1970, 1, 1);
            var delta = self - epoc;

            if (delta.TotalSeconds < 0) throw new ArgumentOutOfRangeException(InvalidUnixEpochErrorMessage);

            return (long) delta.TotalSeconds;
        }
    }

And here is a JSON.net converter that you can use to automagically deserialize your json. I swiped this from Luke Foust's Stacky and fixed it up for use in current versions of JSON.net

    /// <summary>
    ///   Useful when serializing/deserializing json for use with the Stack Overflow API, which produces and consumes Unix Timestamp dates
    /// </summary>
    /// <remarks>
    ///   swiped from lfoust and fixed for latest json.net with some tweaks for handling out-of-range dates
    /// </remarks>
    [CLSCompliant(false)]
    public class UnixDateTimeConverter : DateTimeConverterBase
    {
        //public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
        //{
        //    if (reader.TokenType != JsonToken.Integer)
        //        throw new Exception("Wrong Token Type");

        //    long ticks = (long)reader.Value;
        //    return ticks.FromUnixTime();
        //}

        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param><param name="value">The value.</param><param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            long val;
            if (value is DateTime)
            {
                val = ((DateTime) value).ToUnixTime();
            }
            else
            {
                throw new Exception("Expected date object value.");
            }
            writer.WriteValue(val);
        }

        /// <summary>
        ///   Reads the JSON representation of the object.
        /// </summary>
        /// <param name = "reader">The <see cref = "JsonReader" /> to read from.</param>
        /// <param name = "objectType">Type of the object.</param>
        /// <param name = "existingValue">The existing value of object being read.</param>
        /// <param name = "serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            if (reader.TokenType != JsonToken.Integer)
                throw new Exception("Wrong Token Type");

            long ticks = (long) reader.Value;
            return ticks.FromUnixTime();
        }
    }

.

You would use this by decorating a field or property in your deserialization type like so:

/// <summary>
///   date this question was locked
/// </summary>
[JsonConverter(typeof (UnixDateTimeConverter))]
[JsonProperty("locked_date")]
public virtual DateTime LockedDate
{
    get { return lockedDate; }
    set
    {
        NotifyPropertyChanged("LockedDate");
        lockedDate = value;
    }
}
4
3

I am aware that the last activity in this thread was more than four years ago, but since it still shows up in Google searches, I would like to point out some errors in the conversion.

I have no comments to the JSON.net related part of the converter, since that is what I searched for. But the conversion from and to UNIX timestamps is wrong.

A UNIX timestamp is specified as the amount of seconds since the 1st of January, 1970. The code in the UnixDateTimeHelper class also reflects this, but since UNIX timestamps are specified in UTC, this should be reflected in the conversion:

///<summary>
///</summary>
public static class UnixDateTimeHelper
{
    private const string InvalidUnixEpochErrorMessage = "Unix epoc starts January 1st, 1970";
    /// <summary>
    ///   Convert a long into a DateTime
    /// </summary>
    public static DateTime FromUnixTime(this Int64 self)
    {
        var ret = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        return ret.AddSeconds(self);
    }

    /// <summary>
    ///   Convert a DateTime into a long
    /// </summary>
    public static Int64 ToUnixTime(this DateTime self)
    {

        if (self == DateTime.MinValue)
        {
            return 0;
        }

        var epoc = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        var delta = self.ToUniversalTime() - epoc;

        if (delta.TotalSeconds < 0) throw new ArgumentOutOfRangeException(InvalidUnixEpochErrorMessage);

        return (long) delta.TotalSeconds;
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .