admin管理员组文章数量:1302272
How can I convert a date time format from JSON.Net such as:
/Date(1154970000000+0700)/
To ISO-?? format 2011-12-18T23:34:59Z
Preferably in either Python or Javascript.
Ive decided on the latter as its seems in the JS world the most widely used, humanly readable and naturally sortable. I'll store offsets on a per user basis.
If an implementation is again a bit much too ask, if someone can tell me the correct name for both formats I might have more luck in understanding how to convert.
How can I convert a date time format from JSON.Net such as:
/Date(1154970000000+0700)/
To ISO-?? format 2011-12-18T23:34:59Z
Preferably in either Python or Javascript.
Ive decided on the latter as its seems in the JS world the most widely used, humanly readable and naturally sortable. I'll store offsets on a per user basis.
If an implementation is again a bit much too ask, if someone can tell me the correct name for both formats I might have more luck in understanding how to convert.
Share edited Aug 3, 2017 at 22:56 RobG 148k32 gold badges179 silver badges214 bronze badges asked Apr 26, 2011 at 5:46 user53791user537914 Answers
Reset to default 3[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 ponent 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)/
jsonDate = "/Date(1154970000000+0700)/";
var strDate = parseInt(jsonDate.replace(/\/Date\(([-\d]+).*$/, "$1"));
var strHour = parseInt(jsonDate.replace(/.*\d([+-]\d\d).*$/, "$1"), 10);
var strMin = parseInt(jsonDate.replace(/.*\d([+-])\d\d(\d\d).*$/, "$1$2"), 10);
var date = new Date(strDate);
if (!isNaN(strHour)) date.setHours(date.getHours() + strHour);
if (!isNaN(strMin)) date.setMinutes(date.getMinutes() + strMin);
var out = date.toISOString();
And the function to convert to ISO:
var toISOString = Date.prototype.toISOString ?
function(d){return d}:
(function(){
function t(i){return i<10?"0"+i:i};
function h(i){return i.length<2?"00"+i:i.length<3?"0"+i:3<i.length?Math.round(i/Math.pow(10,i.length-3)):i};
function toISOString(){
return "".concat(
this.getUTCFullYear(), "-",
t(this.getUTCMonth() + 1), "-",
t(this.getUTCDate()), "T",
t(this.getUTCHours()), ":",
t(this.getUTCMinutes()), ":",
t(this.getUTCSeconds()), ".",
h("" + this.getUTCMilliseconds()), "Z"
);
};
return function(d){
d.toISOString = toISOString;
return d;
}
})();
Returns timezone aware datetimes and provides correct output for John Machin's test cases and "/Date(1428145200000+1200)/"
Python >3.3 patible. For 2.7, use pytz.utc
instead of datetime.timezone.utc
.
from datetime import datetime, timedelta, timezone
import re
def jsondate(jsondate, tzinfo=timezone.utc):
"""Converts an ASP.NET json date: "/DATE(x)/" to tz-aware datetime object."""
regex = (
r"/Date\("
r"(?P<milleseconds>[\-]?\d+)"
r"(?P<offset>"
r"(?P<offset_sign>[\+\-])"
r"(?P<offset_hours>[01][0-9]|2[0-3])"
r"(?P<offset_mins>[0-5][0-9])"
r")?\)/"
)
try:
parts = re.match(regex, jsondate).groupdict()
except (AttributeError, TypeError):
raise ValueError("Unsupported ASP.NET JSON Date Format: %s" % jsondate)
since_epoch = timedelta(microseconds=1000 * int(parts['milleseconds']))
if parts.get('offset'):
since_epoch += timedelta(
hours=int("%s%s" % (parts['offset_sign'], parts['offset_hours'])),
minutes=int("%s%s" % (parts['offset_sign'], parts['offset_mins']))
)
return datetime(year=1970, month=1, day=1, tzinfo=tzinfo) + since_epoch
Here's a little class I wrote years ago to clean up this sort of invalid JSON that some .NET library generates:
class DotNETDecoder(simplejson.JSONDecoder):
'''
This is a decoder to convert .NET encoded JSON into python objects
The motivation for this is the way .NET encodes dates.
See:
https://msdn.microsoft./en-us/library/bb299886.aspx#intro_to_json_topic2
.NET encodes datetimes like this: "\/Date(628318530718)\/"
'''
def __init__(self, timezone, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.parse_string = self._date_parse_string(timezone)
self.scan_once = py_make_scanner(self)
@staticmethod
def _date_parse_string(timezone):
def _parse_string(string, idx, encoding, strict):
obj = scanstring(string, idx, encoding, strict)
if isinstance(obj[0], str):
match = date_match.search(obj[0])
if match:
return [dt.datetime.fromtimestamp(
int(match.group(1)) / 1000, timezone),
obj[1]]
return obj
return _parse_string
And a test case / example:
def test_can_decode_dotnet_json_dates():
jsonstr = '{"date": "Date(1330848000000)", "f": "b", "l": [], "i": 5}'
timezone = pytz.timezone('America/New_York')
obj = json.loads(jsonstr, cls=DotNETDecoder, timezone=timezone)
assert obj['date'] == timezone.localize(dt.datetime(2012, 3, 4, 3, 0))
assert obj['f'] == "b"
assert obj['i'] == 5
assert obj['l'] == []
本文标签: javascriptDate conversion NET JSON to ISOStack Overflow
版权声明:本文标题:javascript - Date conversion .NET JSON to ISO - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741700445a2393256.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论