How to Convert Date Like \/Date(1440156888750-0700)\/ to Something That Swift Can Handle

Converting Date to /Date(631148400000+0100)/ string in Swift

From Stand-Alone JSON Serialization:

DateTime values appear as JSON strings in the form of "/Date(700000+0500)/", where the first number (700000 in the example provided) is the number of milliseconds in the GMT time zone, regular (non-daylight savings) time since midnight, January 1, 1970. The number may be negative to represent earlier times. The part that consists of "+0500" in the example is optional and indicates that the time is of the Local kind - that is, should be converted to the local time zone on deserialization. If it is absent, the time is deserialized as Utc. The actual number ("0500" in this example) and its sign (+ or -) are ignored.

And from Use JSON.NET to parse json date of format Date(epochTime-offset)

... In this screwy format, the timestamp portion is still based solely on UTC. The offset is extra information. It doesn't change the timestamp. You can give a different offset, or omit it entirely and it's still the same moment in time.

So the number of ticks is the number of milliseconds since Januar 1, 1970 GMT. Adding a time zone specification would only change how the
date is presented locally in .NET, and one can simply omit that part
when generating a JSON date string:

extension Date {
var jsonDate: String {
let ticks = lround(timeIntervalSince1970 * 1000)
return "/Date(\(ticks))/"
}
}

Example:

print(Date().jsonDate) // /Date(1481446227993)/

How to convert C# date time variable to NSDate?

Please check below code:

let date : NSDate = NSDate(timeIntervalSince1970: 1454956200000)
let tz : NSTimeZone = NSTimeZone.defaultTimeZone(); //Default TimeZone. You can set any.
let seconds : Int = tz.secondsFromGMTForDate(date);
var date = NSDate(timeInterval:Double(seconds), sinceDate: date)

let dateForm = NSDateFormatter();

let locale = NSLocale.currentLocale();

dateForm.locale = locale
dateForm.dateFormat = "MMM dd"; //the formate in which u want to convert.

let strStartTime = dateForm.stringFromDate(date);

Parsing JSON (date) to Swift

That looks very similar to the JSON encoding for a date as used by Microsoft's ASP.NET AJAX, which
is described in An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET:

For example, Microsoft's ASP.NET AJAX uses neither of the described
conventions. Rather, it encodes .NET DateTime values as a JSON string,
where the content of the string is /Date(ticks)/ and where ticks
represents milliseconds since epoch (UTC). So November 29, 1989,
4:55:30 AM, in UTC is encoded as "\/Date(628318530718)\/".

The only difference is that you have the format /Date(ticks)/
and not \/Date(ticks)\/.

You have to extract the number between the parentheses. Dividing that by 1000
gives the number in seconds since 1 January 1970.

The following code shows how that could be done. It is implemented as
a "failable convenience initializer" for NSDate:

extension NSDate {
convenience init?(jsonDate: String) {

let prefix = "/Date("
let suffix = ")/"
// Check for correct format:
if jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) {
// Extract the number as a string:
let from = jsonDate.startIndex.advancedBy(prefix.characters.count)
let to = jsonDate.endIndex.advancedBy(-suffix.characters.count)
// Convert milliseconds to double
guard let milliSeconds = Double(jsonDate[from ..< to]) else {
return nil
}
// Create NSDate with this UNIX timestamp
self.init(timeIntervalSince1970: milliSeconds/1000.0)
} else {
return nil
}
}
}

Example usage (with your date string):

if let theDate = NSDate(jsonDate: "/Date(1420420409680)/") {
print(theDate)
} else {
print("wrong format")
}

This gives the output


2015-01-05 01:13:29 +0000

Update for Swift 3 (Xcode 8):

extension Date {
init?(jsonDate: String) {

let prefix = "/Date("
let suffix = ")/"

// Check for correct format:
guard jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) else { return nil }

// Extract the number as a string:
let from = jsonDate.index(jsonDate.startIndex, offsetBy: prefix.characters.count)
let to = jsonDate.index(jsonDate.endIndex, offsetBy: -suffix.characters.count)

// Convert milliseconds to double
guard let milliSeconds = Double(jsonDate[from ..< to]) else { return nil }

// Create NSDate with this UNIX timestamp
self.init(timeIntervalSince1970: milliSeconds/1000.0)
}
}

Example:

if let theDate = Date(jsonDate: "/Date(1420420409680)/") {
print(theDate)
} else {
print("wrong format")
}

Use JSON.NET to parse json date of format Date(epochTime-offset)

/Date(1445301615000-0700)/

That is meant to represent a UTC time of 2015-10-19 17:40:15

Sorry, that's incorrect. The UTC time is 2015-10-20 00:45:15. Your value corresponds to the local time, in a time zone with a -07:00 offset at that instant.

In this screwy format, the timestamp portion is still based solely on UTC. The offset is extra information. It doesn't change the timestamp. You can give a different offset, or omit it entirely and it's still the same moment in time.

All of the following are equivalent, with regard to point-in-time.

/Date(1445301615000-0700)/
/Date(1445301615000)/
2015-10-20T00:40:15Z
2015-10-19T17:40:15-07:00

Notice that in in the ISO format, the offset does change the value, but in the MS format it does not.

It would be best if you did not use this format, as ISO8601 is a much saner choice for JSON. However if you're stuck with it, then it's best not to deserialize it to a DateTime. Instead, use a DateTimeOffset.

Consider:

string s = "\"/Date(1445301615000-0700)/\"";
DateTime dt = JsonConvert.DeserializeObject<DateTime>(s);
Console.WriteLine(dt.Kind); // Local

That's no good. basically, if there is any offset, it thinks it's your local time zone, which it might be, but it might not be.

string s = "\"/Date(1445301615000)/\"";
DateTime dt = JsonConvert.DeserializeObject<DateTime>(s);
Console.WriteLine(dt.Kind); // Utc

This is ok, but you've lost track of that local time.

string s = "\"/Date(1445301615000-0700)/\"";
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>(s);
Console.WriteLine(dto); // 10/19/2015 5:40:15 PM -07:00

That's much better. And if you do indeed want a UTC DateTime, then:

string s = "\"/Date(1445301615000-0700)/\"";
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>(s);
DateTime utc = dto.UtcDateTime;
Console.WriteLine(utc); // 10/20/2015 12:40:15 AM

So the key lesson is, regardless of format, if there is time zone offset information present in the data, then deserialize to DateTimeOffset. While using DateTime might work in some cases, you are asking .NET to interpret the offset and apply default behavior, which often will not be the desired behavior.



Related Topics



Leave a reply



Submit