Date conversion .NET JSON to ISO

[Replacement answer]

Here is a Python 2.x version. Only the print statements in the testing section need to be changed for Python 3.x.

As far as I can ascertain by googling: The main component is milliseconds since 1970-01-01. It can be negative. A + sign is NOT expected for positive numbers. This can be followed by an OPTIONAL offset from UTC, which consists of 5 characters: an mandatory sign (+ or -), 2 digits for hours, and 2 digits for minutes. All of the above is preceded by "/Date(" and followed by ")/".

This answer provides a function to convert the JSON.NET string to a Python datetime.datetime (timestamp) object, and 2 functions to return ISO format truncated to seconds and milliseconds respectively.

Script:

# /Date(1154970000000+0700)/
# 0123456............7654321
# without timezone:
# /Date(1154970000000)/
# 0123456............21
# dodgy case
# /Date(-1234)/
# 3210987654321
import datetime

def json_date_as_datetime(jd):
    sign = jd[-7]
    if sign not in '-+' or len(jd) == 13:
        millisecs = int(jd[6:-2])
    else:
        millisecs = int(jd[6:-7])
        hh = int(jd[-7:-4])
        mm = int(jd[-4:-2])
        if sign == '-': mm = -mm
        millisecs += (hh * 60 + mm) * 60000
    return datetime.datetime(1970, 1, 1) \
        + datetime.timedelta(microseconds=millisecs * 1000)

def datetime_as_iso(dt):
    return dt.strftime("%Y-%m-%dT%H:%M:%SZ") # truncates

def datetime_as_iso_ms(dt): # with millisecs as fraction
    return dt.strftime("%Y-%m-%dT%H:%M:%S.%%03dZ") \
        % (dt.microsecond // 1000) # truncate    

if __name__ == "__main__":

    tests = """\
    /Date(1154970000000+0700)/
    /Date(-1234)/
    /Date(1000+0200)/
    /Date(0+0000)/
    /Date(0)/
    /Date(0-0700)/
    /Date(0-0730)/
    /Date(0-0030)/
    /Date(-1577923200000+0000)/
    /Date(1)/
    /Date(499)/
    /Date(500)/
    /Date(501)/
    /Date(999)/
    /Date(1000)/
    /Date(-1)/
    """.splitlines()

    for test in tests:
        test = test.strip()
        if not test: continue
        d = json_date_as_datetime(test)
        print datetime_as_iso_ms(d), test

Output:

2006-08-08T00:00:00.000Z /Date(1154970000000+0700)/
1969-12-31T23:59:58.766Z /Date(-1234)/
1970-01-01T02:00:01.000Z /Date(1000+0200)/
1970-01-01T00:00:00.000Z /Date(0+0000)/
1970-01-01T00:00:00.000Z /Date(0)/
1969-12-31T17:00:00.000Z /Date(0-0700)/
1969-12-31T16:30:00.000Z /Date(0-0730)/
1969-12-31T23:30:00.000Z /Date(0-0030)/
1920-01-01T00:00:00.000Z /Date(-1577923200000+0000)/
1970-01-01T00:00:00.001Z /Date(1)/
1970-01-01T00:00:00.499Z /Date(499)/
1970-01-01T00:00:00.500Z /Date(500)/
1970-01-01T00:00:00.501Z /Date(501)/
1970-01-01T00:00:00.999Z /Date(999)/
1970-01-01T00:00:01.000Z /Date(1000)/
1969-12-31T23:59:59.999Z /Date(-1)/