JavaScript에서 Date 객체를 수신하기 위해 JSON을 구문 분석하는 방법은 무엇입니까?


117

다음과 같은 JSON 조각이 있습니다.

\/Date(1293034567877)\/

이 .NET 코드의 결과입니다.

var obj = DateTime.Now;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializer.Serialize(obj).Dump();

이제 내가 직면 한 문제는 JavaScript에서 이것으로부터 Date 객체를 만드는 방법입니다. 내가 찾을 수있는 것은 놀라운 정규식 솔루션 (많은 버그가 포함되어 있음)뿐이었습니다.

이것이 JavaScrip에 모두 포함되어 있기 때문에 우아한 솔루션이 없다고 믿기 어렵습니다 .JavaScript 코드로 간주되는 JSON (JavaScript Object Notation)을 읽으려는 JavaScript 코드를 의미합니다. 여기서 잘 해.

또한 작업 할 수없는 평가 솔루션 (보안 위협으로 지적되는 것 외에)도 보았습니다.

정말 우아하게 할 방법이 없나요?

실제 대답이없는 비슷한 질문 :
GWT로 ASP.NET JSON 날짜 형식을 구문 분석하는 방법


2
타임 스탬프를 클라이언트에 전달하고 호출 new Date()할 수 있습니다.
jAndy 2010-12-22

타임 스탬프가 있었다면 할 수 있지만 JavaScript가 이해하지 못하는 JSON이 있습니다. [sic!]
Piotr Owsiak 2010

답변:


51

날짜에 대한 표준 JSON 표현은 없습니다. @jAndy가 제안한대로하고 a DateTime를 전혀 직렬화하지 않아야 합니다. RFC 1123 날짜 문자열 ToString("r")이나 Unix-epoch의 초 수 또는 JavaScript에서 Date.


3
고마워요 제가 죽은 길을 가고 있었는데, 당신은 JSON이 날짜 유형을 지원하지 않는다는 것을 처음으로 지적했습니다.
Piotr Owsiak 2010

3
JSON은 숫자, 문자열, 객체, 배열 및 리터럴 true, false 및 null을 지원합니다. Date는 이들 중 어느 것도 아니기 때문에 문자열이 아닌 객체로 저장해야하는 복잡한 유형이므로 "$ type"과 같은 특수 멤버에 유형 이름과 같은 유형 정보를 포함 할 수 있습니다. 실제 개체 구성원. 이러한 메타 멤버는 나중에 강력한 형식의 런타임 개체로 JSON 개체를 되살리는 데 사용할 수 있습니다. 불필요하게 예약 된 문자열 패턴을 만들고 모든 문자열에서 일치 시키려고하기 때문에 문자열에 날짜를 붙이는 관행은 어리석은 일이라고 생각합니다.
Triynko 2013

4
이제 표준 JSON 날짜 형식이 있습니다. tools.ietf.org/html/rfc7493#section-4.3
브라이언 라슨

128

JSON.parse함수는 선택적 DateTime 리바이 버 함수를받습니다. 다음과 같은 기능을 사용할 수 있습니다.

dateTimeReviver = function (key, value) {
    var a;
    if (typeof value === 'string') {
        a = /\/Date\((\d*)\)\//.exec(value);
        if (a) {
            return new Date(+a[1]);
        }
    }
    return value;
}

그런 다음 전화

JSON.parse(somejsonstring, dateTimeReviver);

그리고 당신의 날짜가 올 것입니다.


1
잘 발견되고 매우 유용합니다.
noup

5
원시 유형 (문자열)으로 원시 유형이 아닌 데이터를 인코딩하는 이러한 관행은 제정신이 아닙니다. 의미있는 속성이있는 JSON 개체의 날짜를 인코딩하거나 더 나아가 JSON 개체에 "$ type"속성을 포함하여 구문 분석 / 역 직렬화 루틴이 유형을 적절하게 되 살리고 모든 항목을 압축하려는 경우 사용자 지정 변환기를 사용할 수 있도록합니다. 정보를 "ticks"또는 "ms_since_epoch"와 같은 단일 속성 값으로 변환합니다.
Triynko 2013

7
음수도 처리 할 수 ​​있도록 / \ / Date ((-? \ d *)) \ //와 같이 정규식을 수정해야했습니다. .NET에서 JSON으로 변환 된 매우 오래된 DateTime (Epoch 이전)이있는 경우 음수가 나타납니다.
ClearCloud8 2014 년

@ ClearCloud8 : 백 슬래시를 놓쳤습니다 : / \ / Date \ ((-? \ d *) \) \ //
Jerther

1
이 기능에 대해 전혀 몰랐습니다. 이것은 매우 유용합니다!
keldar

50

Roy Tinker의 답변은 다음과 같습니다.

var date = new Date(parseInt(jsonDate.substr(6)));

그가 말했듯이 : substr 함수는 "/ Date ("부분을 취하고 parseInt 함수는 정수를 가져와 끝에 ") /"를 무시합니다. 결과 숫자는 Date 생성자에 전달됩니다.

또 다른 옵션은 JavaScript가 쉽게 읽을 수 있도록 ASP 측에서 정보의 형식을 적절하게 지정하는 것입니다. 날짜에 대해 다음을 고려하십시오.

DateTime.Now()

다음과 같은 형식을 반환해야합니다.

7/22/2008 12:11:04 PM

Date이것을 다음과 같은 JavaScript 생성자에 전달 하면 :

var date = new Date('7/22/2008 12:11:04 PM');

이제 변수 date는 다음 값을 보유합니다.

Tue Jul 22 2008 12:11:04 GMT-0700 (Pacific Daylight Time)

당연히이 DateTime객체를 JS Date생성자가 허용 하는 모든 종류의 문자열 / int로 형식화 할 수 있습니다 .


감사합니다 treeface,이 답변은 최근에 도움이되었습니다!
Malice 2011

4
절대로 기본 date <-> 문자열 변환 형식에 의존하지 마십시오. 숫자 유형 도메인에 남아있는 Epoch 이후 밀리 초를 사용하는 것이 훨씬 더 간단하고 안정적입니다.
Johan Boulé 2012 년

2
이 답변은 두 가지 솔루션을 제공합니다. 첫 번째는 정확하고 (parseInt) 두 번째는 잘못되었으므로 찬성 또는 반대 투표를할지 확실하지 않습니다! 단순히 문자열로 출력하는 문제는 서버가 한 국가 (예 : 미국)에 있고 브라우저가 다른 국가 (예 : 영국)에 있으면 날짜를 쉽게 뒤집을 수 있다는 것입니다.
mike nelson 2013 년

첫 번째 대답은 나에게 단서의 모든 종류를 제공합니다
Nick.McDermaid

" 날짜에이 작업을 고려하십시오 ... " 까지 OK 대답 입니다. 구현에 따른 구문 분석 및 시간대 문제를 도입하는 비표준 형식을 제안하는 것은 좋은 생각이 아닙니다. OP 형식이 바람직합니다 (이상적이지는 않지만).
RobG

21

JSON에서 JavaScript 스타일 ISO8601 날짜를 사용하는 경우 MDN 에서 사용할 수 있습니다.

var jsonDate = (new Date()).toJSON();
var backToDate = new Date(jsonDate);
console.log(jsonDate); //2015-10-26T07:46:36.611Z

2
imo 이것은 가장 우아한 대답이며 받아 들여 져야합니다.
John

1
실제로 매우 우아하지만 이것은 질문에서 언급 된 특정 날짜 형식과 관련이 없습니다.
asiop

@aslop-사용자가 날짜를 ISO로 /에서 변환 할 수없는 경우 JSON이 문제 중 가장 적습니다.
LeeGee 2018-04-12

7

JSON 날짜를 JavaScript에서 일반 날짜 형식으로 변환 할 수 있습니다.

var date = new Date(parseInt(jsonDate.substr(6)));

6

문제 :

new Date(1293034567877);

이렇게하면 "Wed Dec 22 2010 16:16:07 GMT + 0000 (GMT Standard Time)"이 반환됩니다.

아니면 json에서 번호를 가져와야합니까?


3
솔루션에 어떤 문제가 있습니까? 1293034567877은 제가 가지고있는 JSON이 아닙니다. 그렇죠? 또한 JSON에서 숫자를 가져올 필요가 없으며 JSON에서 날짜를 가져와야합니다. 나는 정규식으로 모든 것을 할 수있는 것보다 JavaScript에서 조금 더 많은 것을 기대하고 있습니다. 코드를 읽을 수 있어야하고 만화 저주처럼 보이지 않아야합니다.
Piotr Owsiak 2010

7
나는 이상한 형식으로 날짜 개체의 직렬화를 생성하는 .NET을 비난합니다 \/Date(1293034567877)\/. 정상인 경우 epoch 시간을 출력하고이를 사용하여 Date 객체를 초기화 할 수 있습니다.
Quentin

2
@treeface : JSON이 자바 스크립트가 아니라면이 일반적인 오해에 대해 튜토리얼과 책이 비난받을 것이라고 생각합니다. 어쨌든 나는 기꺼이 바로 정정했습니다. Date를 String으로 표현할 수 있다는 제안은 모든 것이 String으로 표현 될 수 있다고 말할 수 있습니다. 그러나 이것은 우리의 일을 더 쉽게 만들어주지는 않지만 몹시 고통스럽고 지옥 같은 것입니다. 내 문제는 JSON을 직렬화 형식으로 고려했다는 사실에서 비롯된 것 같습니다 (XML보다 대역폭을 적게 사용하고 JavaScript에서 더 잘 작동한다고 광고 됨). 적어도 고통스럽지 않은 것은 아닙니다.
Piotr Owsiak

1
@treeface : JSON에 대한 귀하의 주장을 Google에서 확인한 결과 JSON이 JavaScript라는 사실을 알게되었습니다. 실제로 JavaScript의 하위 집합입니다. RFC # 4627 "JSON (JavaScript Object Notation)을위한 애플리케이션 / json 미디어 유형"을 참조하고 "JSON의 디자인 목표는 최소, 이식 가능, 텍스트 및 JavaScript의 하위 집합이어야했습니다."라는 문을 찾으십시오. 이제 생각해 보면 JSON에서 eval ()을 호출 할 수 있다는 것이 분명해 보입니다.
Piotr Owsiak 2011 년

1
@David Dorward : 프로그래머가 세부 사항을 처리하도록 남겨 두는 것보다 복잡한 추가 라이브러리 (.NET, Java, Ruby, Python 또는 사용중인 언어 / 플랫폼) 내부 깊숙한 곳에 구현하는 것이 좋습니다. 또한 JSON에서 부울 및 정수 데이터 유형 지원이 필요하지 않으며 문자열에 넣을 수 있습니다. 그렇다면 JSON에서 anythong을 얻는 것이 얼마나 끔찍한 지 상상할 수 있습니까?
Piotr Owsiak 2011 년

2

나는 이것이 매우 오래된 스레드라는 것을 알고 있지만, 나처럼 이것에 부딪 치는 사람들을 돕기 위해 이것을 게시하고 싶습니다.

타사 스크립트를 사용하는 데 신경 쓰지 않는다면 moment, js 를 사용할 수 있습니다. 그런 다음 .format ()을 사용하여 원하는대로 포맷 할 수 있습니다.


2

데이트는 항상 악몽입니다. 이전 질문에 대답하면 아마도 이것이 가장 우아한 방법 일 것입니다.

eval(("new " + "/Date(1455418800000)/").replace(/\//g,""))

eval을 사용하여 문자열을 자바 스크립트 코드로 변환합니다. 그런 다음 "/"를 제거하고 교체 함수는 정규식입니다. new로 시작하면 문장이 다음을 실행합니다.

new Date(1455418800000)

오래 전에 사용하기 시작한 한 가지는 틱으로 표시되는 long 값입니다. 왜? 글쎄, 현지화하고 모든 서버 또는 모든 클라이언트에서 날짜가 어떻게 구성되어 있는지 생각하지 마십시오. 사실 데이터베이스에서도 사용합니다.

아마도이 답변에 꽤 늦었지만 여기에있는 사람을 도울 수 있습니다.


Btw, 몇 년 동안 영어가 그 어느 때보 다 나 빠지고 있습니다 ...하지만 내 자신을 이해하게 한 것 같습니다.
Gabriel Andrés Brancolini

귀하의 답변은 훌륭하게 작동하고 잼에서 나를 도왔습니다. 감사.
BoredBsee

1

AngularJS가 .NET JSON 날짜를 구문 분석 할 수 없습니다. /Date(xxxxxxxxxxxxx)/ 문자열도 ..

나는 날짜를 덤핑하는 대신 ISO 8601 문자열 표현으로 형식을 지정 하여이 문제를 해결했습니다. Date 객체를 직접 .

다음은 ASP.NET MVC 코드 샘플입니다.

return Json(new { 
  date : DateTime.Now.ToString("O") //ISO 8601 Angular understands this format
});

시도 RFC 1123했지만 작동하지 않습니다. Angular는 이것을 Date 대신 문자열로 취급합니다.

return Json(new { 
  date : DateTime.Now.ToString("R") //RFC 1123 Angular won't parse this
});

0

나는 이와 같은 일에 .Net을 사용하지 않았습니다. 다음과 같이 인쇄 할 수 있다면 작동합니다.

다른 방법으로 해당 JSON 문자열 을 구문 분석하지 않거나 사용자가 JSON 구문 분석기가 내장 된 최신 브라우저를 가질 것으로 기대 하지 않는 한 JS 프레임 워크 또는 JSON2를 사용하여 서버에서 출력 한 JSON 문자열을 실제 JSON으로 구문 분석해야합니다. 목적.

// JSON received from server is in string format
var jsonString = '{"date":1251877601000}';

//use JSON2 or some JS library to parse the string
var jsonObject =  JSON.parse( jsonString );

//now you have your date!
alert( new Date(jsonObject.date) );

Wiki 링크

Firefox 3.5 및 Internet Explorer 8과 같은 최신 브라우저에는 JSON 구문 분석을위한 특수 기능이 포함되어 있습니다. 기본 브라우저 지원이 eval ()보다 더 효율적이고 안전하므로 기본 JSON 지원이 다음 ECMAScript 표준에 포함될 것으로 예상됩니다. [6]


JSON2 파일에 연결

라이브 예


알지만 JSON 및 날짜 유형의 문제는 "new Date (") 추가 작업 b) 소비자에게 전달해야하는 추가 지식을 명시 적으로 수행해야한다는 것입니다. 나는 이것이 어떻게 처리되는지 알게되어 정말 실망스럽고 기본적으로 JSON 사양의 실수라고 생각합니다.
Piotr Owsiak 2010

0

이 질문에 대한 대답은 nuget을 사용하여 JSON.NET을 얻은 다음 JsonResult메서드 내에서 사용 하는 것입니다.

JsonConvert.SerializeObject(/* JSON OBJECT TO SEND TO VIEW */);

보기 내에서 간단하게 다음을 수행하십시오 javascript.

JSON.parse(/* Converted JSON object */)

ajax 호출 인 경우 :

var request = $.ajax({ url: "@Url.Action("SomeAjaxAction", "SomeController")", dataType: "json"});
request.done(function (data, result) { var safe = JSON.parse(data); var date = new Date(safe.date); });

일단 JSON.parse호출 되면 적절한 ISO 시간 인스턴스를 생성 new Date하므로 JSON 날짜를 인스턴스에 넣을 수 있습니다.JsonConvert


0
function parseJsonDate(jsonDate) {

    var fullDate = new Date(parseInt(jsonDate.substr(6)));
    var twoDigitMonth = (fullDate.getMonth() + 1) + ""; if (twoDigitMonth.length == 1) twoDigitMonth = "0" + twoDigitMonth;

    var twoDigitDate = fullDate.getDate() + ""; if (twoDigitDate.length == 1) twoDigitDate = "0" + twoDigitDate;
    var currentDate = twoDigitMonth + "/" + twoDigitDate + "/" + fullDate.getFullYear();

    return currentDate;
};

0

Callum이 언급했듯이 저에게 가장 좋은 방법은 Controller 메서드를 JsonResult 대신 문자열로 변경하는 것입니다.

public string GetValues()
{
  MyObject.DateFrom = DateTime.Now;
  return JsonConvert.SerializeObject(MyObject);
}

ajax 메소드에서 다음과 같이 할 수 있습니다.

 $.ajax({
 url: "/MyController/GetValues",
 type: "post",
 success: function (data) {
 var validData = JSON.parse(data);
//if you are using datepicker and you want set a format
$("#DateFrom").val($.datepicker.formatDate("dd/mm/yy", new Date(validData.DateFrom)));                                      
// if you want the date as returned
$("#DateFrom").val(new Date(validData.DateFrom))
}
});

0

eval 함수를 사용하면 앞뒤의 슬래시를 제거하기 만하면됩니다.

var date1 = "/Date(25200000)/"
eval("new " + date1.substring(1, date1.length - 1));

Thu Jan 01 1970 00:00:00 GMT-0700 (미국 산지 표준시)


0

이 형식으로 날짜를 제공하는 외부 API에 문제가 발생했습니다 /Date(123232313131+1000)/. Date다음 코드로 js 객체 를 돌릴 수있었습니다.

var val = '/Date(123232311-1000)/';
var pattern = /^\/Date\([0-9]+((\+|\-)[0-9]+)?\)\/$/;
var date = null;

// Check that the value matches /Date(123232311-1000)/ format
if (pattern.test(val)) {
  var number = val.replace('/Date(', '',).replace(')/', '');
  if (number.indexOf('+') >= 0) {
    var split = number.split('+');
    number = parseInt(split[0]) + parseInt(split[1]);
  } else if (number.indexOf('-') >= 0) {
    var split = number.split('-');
    number = parseInt(split[0]) - parseInt(split[1]);
  } else {
    number = parseInt(number);
    date = new Date(number);
  }
}

-1
//
// formats a .net date into a javascript compatible date
//
function FormatJsonDate(jsonDt) 
{              
    var MIN_DATE = -62135578800000; // const

    var date = new Date(parseInt(jsonDt.substr(6, jsonDt.length-8)));                                                       
    return date.toString() == new Date(MIN_DATE).toString() ? "" : (date.getMonth() + 1) + "\\" + date.getDate() + "\\" + date.getFullYear(); 
}

2
내가 코드를 이해하는 한 날짜 객체를 반환하지 않습니다.
Johan Boulé 2012 년

-1
function parseJsonDate(jsonDate) {

    var fullDate = new Date(parseInt(jsonDate.substr(6)));
    var twoDigitMonth = (fullDate.getMonth() + 1) + ""; if (twoDigitMonth.length == 1) twoDigitMonth = "0" + twoDigitMonth;

    var twoDigitDate = fullDate.getDate() + ""; if (twoDigitDate.length == 1) twoDigitDate = "0" + twoDigitDate;
    var currentDate = twoDigitMonth + "/" + twoDigitDate + "/" + fullDate.getFullYear();

    return currentDate;
};

//이 기능 사용

var objDate=parseJsonDate("\/Date(1443812400000)\/");
alert(objDate);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.