Microsoft JSON tarihini nasıl biçimlendiririm?


2000

Ajax'ta jQuery ile ilk çatlağımı alıyorum . Verilerimi sayfama alıyorum, ancak Tarih veri türleri için döndürülen JSON verilerinde bazı sorunlar yaşıyorum. Temel olarak, şöyle bir dize geri alıyorum:

/Date(1224043200000)/

Tamamen yeni birinden JSON'a - Bunu kısa tarih biçimine nasıl biçimlendirebilirim? Bu, jQuery kodunda bir yerde ele alınmalı mıdır? jQuery.UI.datepickerEklentiyi $.datepicker.formatDate()herhangi bir başarı olmadan kullanarak denedim .

FYI: İşte cevapların bir kombinasyonunu kullanarak bulduğum çözüm:

function getMismatch(id) {
  $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
      $("#AuthMerchId").text(result.AuthorizationMerchantId);
      $("#SttlMerchId").text(result.SettlementMerchantId);
      $("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
      $("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
      $("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
      $("#LastUpdatedBy").text(result.LastUpdateNt);
      $("#ProcessIn").text(result.ProcessIn);
    }
  );

  return false;
}

function formatJSONDate(jsonDate) {
  var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
  return newDate;
}

Bu çözüm nesnemi geri arama yönteminden aldı ve tarih biçimi kitaplığını kullanarak tarihleri ​​doğru bir şekilde görüntüledi.


26
Bu ilginç olabilir: hanselman.com/blog/…
citronas

6
/Date(...)/ biçimi Microsoft'un yerleşik JSON Tarih biçimine özgüdür - herhangi bir standardın parçası değildir ve Javascript'ten gelen JSON bir standarda sahiptir: Javascript'in belirttiği ISO biçimi: stackoverflow.com/a / 15952652/176877 Bu soru, Microsoft'un JSON Tarih biçimine özgüdür. Bunu açıklığa kavuşturmak için başlığı değiştirdim.
Chris Moschini

15
Dalga geçiyorsun! Microsoft JSON'a kendi dönüşlerini damgasını vurdu! ve tarihlerde !! Ne zaman öğrenecekler!
Nick.McDermaid

.NET tarafında Newtonsoft JSON kullanın ve JS tarafında güzel bir şekilde yazılmış değerler elde etmek için şunu kullanın: github.com/RickStrahl/json.date-extensions
baHI

JSON yerine JSON ++ kullanabilirsiniz. JSON ++ , JSON ile aynıdır ancak JavaScript türlerini destekler Date.
brillout

Yanıtlar:


1688

eval()gerekli değil. Bu iyi çalışır:

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

substr()Fonksiyon alır /Date(bölümünü ve parseInt()fonksiyon tamsayı alır ve yok sayar )/sonunda. Ortaya çıkan sayı kurucuya geçirilir Date.


Ben kasıtlı olarak radix (2. argüman parseInt) dışında kalmış; bkz aşağıda yorumumu .

Ayrıca, Rory'nin yorumuna tamamen katılıyorum : ISO-8601 tarihleri ​​bu eski formatta tercih edilir - bu nedenle bu format genellikle yeni geliştirme için kullanılmamalıdır. ISO-8601 biçimini kullanarak tarihleri ​​serileştiren harika bir alternatif için mükemmel Json.NET kütüphanesine bakın .

ISO-8601 biçimli JSON tarihleri ​​için dizeyi yapıcıya iletmeniz yeterlidir Date:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support

4
@Broam: MS biçimi değiştirirse, her iki yöntemin de (replace işlevi ve bu yanıt) değiştirilmesi gerekir.
Roy Tinker

23
Lütfen radix var date = new Date (parseInt (jsonDate.substr (6), 10)) ile güncelleyebilir misiniz?
James Kyburz

6
@JamesKyburz: Her kuralın istisnaları vardır ve bence bu bir istisna geçerlidir. .NET'in JSON tarih numaralarının hiçbir zaman önde gelen "0" değeri yoktur, bu nedenle güvenli bir şekilde alanı kaldırabiliriz.
Roy Tinker

22
Bu tarih biçiminin oldukça kötü olduğunu ve genel hareketin JSON'daki ISO-8601 biçimli tarihler olduğunu belirtmek gerekir. Bkz. Hanselman.com/blog/…
Rory

4
Bu yaklaşım saat dilimini dikkate almaz, bu nedenle sunucunuz ve kullanıcılarınız farklı saat dilimlerinde ciddi sorunlara neden olabilir. Aşağıda, WCF ve Javascript taraflarında bununla başa çıkmanın çok hızlı ve kolay bir yolunu açıklayan bir cevap gönderdim: stackoverflow.com/a/10743718/51061
Scott Willeke

135

JSON'dan bir tarih almak için bunu kullanabilirsiniz:

var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));

Ve sonra istediğiniz gibi görüntülemek için bir JavaScript Tarih Biçimi komut dosyası (küçültüldüğünde ve sıkıştırıldığında 1.2 KB) kullanabilirsiniz.


7
Çizgide yanlış bir şey yok, sıra \ //. İlk eğik çizgi kaçar, böylece bir yorum gibi sayılmaz. Editörünüz sizi kandırıyor, çizgi iyi çalışacak.
andreialecu

152
@rball, saçmalık:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
eyelidlessness

39
pst doğruydu, bunu 'eval' olmadan çeşitli şekillerde yapmak mümkündür. Crockford, daha az okunabilir ve daha az güvenli olduğu için 'eval Is Evil' olduğunu, ayrıca javascript derleyicisine çarptığı için daha az verimli ve daha tehlikeli olduğunu da ima edebilir.
Mark Rogers

13
@Edy: new Functionneredeyse şu kadar kötü eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel

5
@Edy: Bu başka bir değerlendirme şeklidir ve tıpkı 'kötülük' gibidir. Bunun yerine dizeyi ayrıştırın (aşağıdaki cevabımı görün)
Roy Tinker

98

Newtonsoft Json.NET kullananlar için , IE8, Firefox 3.5 ve Json.NET'teki Yerel JSON ile nasıl yapılacağını okuyun .

Ayrıca Json.NET tarafından yazılan tarihlerin biçimini değiştirmeye ilişkin belgeler de yararlıdır: Json.NET ile Tarihleri ​​Dizileştirme

Çok tembel olanlar için hızlı adımlar. JSON'da gevşek bir DateTime uygulaması olduğundan IsoDateTimeConverter(),. Json.NET 4.5'ten bu yana varsayılan tarih biçiminin ISO olduğunu ve aşağıdaki kodun gerekli olmadığını unutmayın.

string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());

JSON şu şekilde gelecek:

"fieldName": "2009-04-12T20:44:55"

Son olarak, ISO tarihini bir JavaScript tarihine dönüştürmek için bazı JavaScriptler:

function isoDateReviver(value) {
  if (typeof value === 'string') {
    var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
      if (a) {
        var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
        return new Date(utcMilliseconds);
      }
  }
  return value;
}

Böyle kullandım

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);

6
JavaScript Tarih oluşturucusu dizeyi sizin için ayrıştırabilir:new Date("2009-04-12T20:44:55")
David Hogue

5
Uyarı - Date () Yapıcı biçimleri ve ayrıştırma ECMAScript 6'dan önce standart değildir. Örneğin, IE 9, başka bir yerde UCT olarak ima edilen IS0-8601'de olsa bile yapıcıya verdiğiniz tarihi yerel bir saat olarak ele alır. Eski tarayıcıları destekliyorsanız tarih oluşturucusuna güvenmeyin. codeofmatt.com/2013/06/07/…
DanO

UTC olmayan bir tarih göndermek er ya da geç başınızı derde sokar.
Timtam

Burada partiye biraz geç, ama ne (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; bu bağlamda temsil eder misiniz?
yanant

@yanant - +a[1]vb normal ifadenin dizi parçalarını temsil eder ve +bir sayıya +a[1]eşit olur , bu yüzden eşittir 2009vb. İşte dizi dökümü: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong

67

Orijinal örnek:

/Date(1224043200000)/  

dahili JSON serileştirme kullanılarak WCF REST aracılığıyla tarih gönderirken WCF tarafından kullanılan biçimlendirmeyi yansıtmaz. (en azından .NET 3.5, SP1'de)

Cevabı burada yararlı buldum, ancak regex'te hafif bir düzenleme yapılması gerekiyor, çünkü zaman dilimi GMT ofseti WCF JSON'da (1970'ten beri) döndürülen numaraya ekleniyor gibi görünüyor.

Bir WCF hizmetinde:

[OperationContract]
[WebInvoke(
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.WrappedRequest
    )]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );

ApptVisitLinkInfo basitçe tanımlanmıştır:

public class ApptVisitLinkInfo {
    string Field1 { get; set; }
    DateTime Field2 { get; set; }
    ...
}

"Field2" hizmetten Json olarak döndürüldüğünde değer:

/Date(1224043200000-0600)/

Değerin bir parçası olarak dahil edilen saat dilimi farkına dikkat edin.

Değiştirilmiş normal ifade:

/\/Date\((.*?)\)\//gi

Biraz daha istekli ve sadece ilk sayı değil, parens arasındaki her şeyi kapıyor. Ortaya çıkan zaman sinze 1970, artı saat dilimi ofseti bir date nesnesi elde etmek için eval beslenebilir.

Değiştirme için ortaya çıkan JavaScript satırı:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");

10
bu yanlıştır, yeni Tarih (1224043200000-0600) tarihten 600 değerini çıkarır, bu durumda 600 milisaniye, olması gerektiği gibi 6 saat değil.
ariel


Bence zaman dilimi ofseti .NET (varsayılan davranış) DateTime nesnesinde bir saat dilimi varsa dahil olduğunu düşünüyorum. Tarihiniz UTC ise, DateTime.SpecifyKind (date, DateTimeKind.UTC) kullanın ve serileştirildiğinde, ofset olmadan uygun UTC değerini alırsınız; Yerel saatteyse, .ToUniversalTime () öğesini kullanın; UTC'ye dönüştürülecek ve sizin için zaten "Tür" belirtilmiş olacaktır.
jvenema

javascript -0100 ikili bir dize olacak, bu yüzden dikkatli olun!
verbedr

WCF'den JS'ye tarih dönüştürüldüğünde, tersine dönelim. Aynı WCF'ye iletmek istediğiniz tamsayı (date.getTime () kullanarak) tarihiniz mi var?
NitinSingh

65

Kendinizi tekrar etmeyin - kullanarak tarih dönüşümünü otomatikleştirin $.parseJSON()

Yayınınıza verilen yanıtlar JavaScript tarihlerine manuel tarih dönüşümü sağlar. Ben jQuery $.parseJSON()biraz uzattım, bu yüzden size talimat zaman tarihleri ​​otomatik olarak ayrıştırmak mümkün. Tarayıcılarda (ve json2.js gibi kütüphanelerde) yerel JSON işlevleri tarafından desteklenen ASP.NET biçimli tarihleri ​​( /Date(12348721342)/) ve ISO biçimli tarihleri ​​( 2010-01-01T12.34.56.789Z) işler.

Neyse. Tarih dönüşüm kodunuzu tekrar tekrar tekrarlamak istemiyorsanız, bu blog gönderisini okumanızı ve hayatınızı biraz daha kolaylaştıracak kodu almanızı öneririm .


61

JavaScript ile derseniz,

var thedate = new Date(1224043200000);
alert(thedate);

bunun doğru tarih olduğunu görürsünüz ve bunu JavaScript kodunda herhangi bir çerçevede herhangi bir çerçeveyle kullanabilirsiniz.


3
Ben de biter dışında ben de düşünecektim: var thedate = / Tarih (1224043200000) /; en azından benim için ...
rball

2
Tarih () ve Tarih (1224043200000), Chrome ve Firefox'ta aynı sonucu verir. Bunun eski tarayıcılarda çalışıp çalışmadığından emin değilim, ancak bu cevap şimdi tarayıcılarda çalışmıyor.
James

@James, Evet tarayıcıya güncel tarih veriyor. :(
vissu

9
"Yeni Tarih (1224043200000)" olarak yazmanız gerekir.
BrainSlugs83

60

Demoyu kontrol etmek için buraya tıklayın

JavaScript / jQuery

var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
            (
                 parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
            );
var dat = value.getMonth() +
                         1 +
                       "/" +
           value.getDate() +
                       "/" +
       value.getFullYear();

Sonuç - "10/15/2008"


Yukarıdaki yöntem için sadece bir gelişme. fonksiyon formatearFecha (fec) {var value = yeni Tarih (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, ''))); var mes = value.getMonth (); var dia = değer.getDate (); var tarih = dia + "/" + mes + "/" + değer.getFullYear (); eğer (dia <10) tarih = tarih.substr (0, 0) + '0' + dia + date.substr (1); eğer (mes <10) tarih = tarih.substr (0, 3) + '0' + mes + date.substr (4); dönüş tarihi;} ddMMyyyy Şerefe!
Matias

38

Güncellenmiş

Hem Microsoft'un ASP.NET yerleşik JSON formatı ile başa çıkmak zorunda olan /Date(msecs)/, orijinal olarak burada sorulduğu gibi , JSON.NET'ler de dahil olmak üzere çoğu JSON'un tarih formatıyla başa çıkmak zorunda olan dahili bir UI kütüphanemiz var 2014-06-22T00:00:00.0. Ek olarak, oldIE'nin 3 ondalık basamaktan başka bir şeyle başa çıkamamasıyla başa çıkmalıyız .

Önce ne tür bir tarih kullandığımızı tespit eder, normal bir JavaScript Datenesnesine ayrıştırırız , sonra biçimlendiririz.

1) Microsoft Tarih biçimini algıla

// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
    return /^\/Date\(/.test(s);
}

2) ISO tarih biçimini algıla

var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;

function looksLikeIsoDate(s) {
    return isoDateRegex.test(s);
}

3) MS tarih biçimini ayrıştırın:

function parseMSDate(s) {
    // Jump forward past the /Date(, parseInt handles the rest
    return new Date(parseInt(s.substr(6)));
}

4) ISO tarih biçimini ayrıştırın.

En azından standart ISO tarihleriyle veya her zaman üç milisaniyelik yere sahip olacak şekilde değiştirilmiş ISO tarihleriyle ( yukarıya bakın ) emin olduğumuzdan emin olmak için bir yolumuz var , bu nedenle kod ortama bağlı olarak farklı.

4a) Standart ISO Tarih biçimini ayrıştırın, eskiIE'nin sorunları ile başa çıkın:

function parseIsoDate(s) {
    var m = isoDateRegex.exec(s);

    // Is this UTC, offset, or undefined? Treat undefined as UTC.
    if (m.length == 7 ||                // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
        (m.length > 7 && (
            !m[7] ||                    // Array came back length 9 with undefined for 7 and 8
            m[7].charAt(0) != '.' ||    // ms portion, no tz offset, or no ms portion, Z
            !m[8] ||                    // ms portion, no tz offset
            m[8] == 'Z'))) {            // ms portion and Z
        // JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
        var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
    } else {
        // local
        var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
    }

    return d;
}

4b) ISO formatını üç milisaniyelik sabit ondalık basamaklarla ayrıştırın - çok daha kolay:

function parseIsoDate(s) {
    return new Date(s);
}

5) Biçimlendir:

function hasTime(d) {
    return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}

function zeroFill(n) {
    if ((n + '').length == 1)
        return '0' + n;

    return n;
}

function formatDate(d) {
    if (hasTime(d)) {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
        s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
    } else {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
    }

    return s;
}

6) Hepsini bağlayın:

function parseDate(s) {
    var d;
    if (looksLikeMSDate(s))
        d = parseMSDate(s);
    else if (looksLikeIsoDate(s))
        d = parseIsoDate(s);
    else
        return null;

    return formatDate(d);
}

Aşağıdaki eski yanıt, bu tarih biçimlendirmesini jQuery'nin kendi JSON ayrıştırma işlemine bağlamak için yararlıdır, böylece dize yerine Date nesneleri alırsınız veya hala bir şekilde jQuery <1.5'de kalıyorsanız.

Eski Cevap

ASP.NET MVC ile jQuery 1.4'ün Ajax işlevini kullanıyorsanız, tüm DateTime özelliklerini aşağıdakilerle Date nesnelerine dönüştürebilirsiniz:

// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};

$.ajax({
    ...
    dataFilter: function(d) {
        return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
    },
    ...
});

JQuery 1.5'te parseJSON, Ajax çağrısındaki dönüştürücüler seçeneğini kullanarak yöntemi global olarak geçersiz kılmaktan kaçınabilirsiniz .

http://api.jquery.com/jQuery.ajax/

Maalesef, Tarihlerin küresel olarak yerinde ayrıştırılması için eski değerlendirme yoluna geçmeniz gerekir - aksi takdirde bunları ayrıştırmadan sonra daha vaka bazında dönüştürmeniz gerekir.


27

JSON'da yerleşik bir tarih türü yok . Bu, bazı çağlardan saniye / milisaniye sayısına benziyor. Dönemi biliyorsanız, doğru zamanı ekleyerek tarihi oluşturabilirsiniz.


Bu yanlış, JSON eklenmiş saat dilimi bilgileriyle Javascript tarihlerini kullanıyor - çağ, javascript Date sınıfının çağıyla aynıdır (bariz nedenlerle).
BrainSlugs83

3
@ BrainSlug83 - bu cevap, JSON'un yerleşik bir tarih türüne sahip olmadığı iddiası için bir referans sağlar. Kabul etmiyorsanız, lütfen alternatif bir referans sağlayın. (Tarihleri ​​temsil etmek için bir dize biçimine karar veren belirli bir çerçeve düşünmüyorsunuz, değil mi? Bu JSON standardının bir parçası değil, aslında olamaz çünkü tarih olarak alınması gerekiyordu, ancak bu tarih deseniyle eşleşen bir dizi karaktere sahip.)
nnnnnn

25

Ayrıca bu soruna bir çözüm aramak zorunda kaldım ve sonunda bu tarih biçimini ve daha fazlasını ayrıştırabilen güzel bir kütüphane olan moment.js ile karşılaştım.

var d = moment(yourdatestring)

Benim için başım ağrıyor, bu yüzden seninle paylaşacağımı düşündüm. :)
Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz: http://momentjs.com/


24

Nesneleri satır içi bir komut dosyasına yazarken Microsoft serileştiricisi tarafından oluşturulan karakterlerden kurtulmak için "karakterleri Panos'un normal ifadesine ekleyerek sonlandırdım:

Yani C # kod arkasında bir özellik varsa bu gibi bir şey

protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}

Ve aspx'inizde

<script type="text/javascript">
    var myObject = '<%= JsonObject %>';
</script>

Gibi bir şey alırsın

var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';

Çift tırnaklara dikkat edin.

Bunu eval'in doğru şekilde serileştireceği bir forma sokmak için kullandım:

myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');

Kullandığım Prototype ve kullanmak ekledim için

String.prototype.evalJSONWithDates = function() {
    var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
    return jsonWithDates.evalJSON(true);
}

22

JQuery 1.5 sürümünde , eski tarayıcıları kapsayacak şekilde json2.js'ye sahip olduğunuz sürece Ajax'tan gelen tüm tarihlerin serisini aşağıdaki gibi kaldırabilirsiniz:

(function () {
    var DATE_START = "/Date(";
    var DATE_START_LENGTH = DATE_START.length;

    function isDateString(x) {
        return typeof x === "string" && x.startsWith(DATE_START);
    }

    function deserializeDateString(dateString) {
        var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
        var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
        return utcDate;
    }

    function convertJSONDates(key, value) {
      if (isDateString(value)) {
        return deserializeDateString(value);
      }
      return value;
    }

    window.jQuery.ajaxSetup({
      converters: {
        "text json": function(data) {
          return window.JSON.parse(data, convertJSONDates);
        }
      }
    });
}());

Sunucudan tüm tarihleri ​​UTC (sizin yapmanız gerekir) gönderdiğiniz varsayılır mantık dahil; tüketici daha sonra Datebunu yansıtacak uygun keneler değerine sahip bir JavaScript nesnesi alır . Yani, getUTCHours()tarihte arama yapmak vb., Sunucuda yaptığı değerle aynı değer getHours()döndürür ve arama , kullanıcının tarayıcısı tarafından belirlenen yerel saat dilimindeki değeri döndürür.

Bu, saat dilimi ofsetleri ile WCF formatını hesaba katmaz , ancak eklemek nispeten kolaydır.


Bir not olarak: kodun çalışması için dize türünün startsWith yöntemini oluşturmanız gerekir
Hugo Zapata

21

JQuery UI tarih seçiciyi kullanmak - gerçekten sadece zaten jQuery UI ekliyorsanız mantıklıdır:

$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6)))); 

çıktı:

15 Ekim 2008



18

Bu cevapların herkesin ortak bir yanı vardır: hepsi tarihleri ​​tek bir değer (genellikle bir dize) olarak depolar.

Başka bir seçenek JSON'un doğal yapısından yararlanmak ve bir tarihi sayı listesi olarak temsil etmektir:

{ "name":"Nick",
  "birthdate":[1968,6,9] }

Tabii ki, konuşmanın her iki ucunun da format (yıl, ay, gün) ve hangi alanların tarih olması gerektiği konusunda hemfikir olduğundan emin olmanız gerekir, ancak tarih meselesinden tamamen kaçınmanın avantajı vardır. -dize dönüştürme. Tüm rakamlar - hiçbir dize yok. Ayrıca, sipariş kullanarak: yıl, ay, gün de tarihe göre doğru sıralama sağlar.

Burada kutunun dışında düşünmek - JSON tarihinin dize olarak saklanması gerekmez.

Bunu bu şekilde yapmanın bir başka avantajı da, CouchDB'nin dizi değerleri üzerindeki sorguları işleme biçimini kullanarak belirli bir yıl veya ay için tüm kayıtları kolayca (ve verimli bir şekilde) seçebilmenizdir .


Orada olan RFC 3339 biçimidir JSON'dan tarihlere yönelik standart bir biçim.
gnasher729

@gnasher, bu iyi olurdu, ama durum böyle değil. RFC 7159'dan 3339'a veya tam tersi referans yoktur. Hiçbir yoktur hukuki standart JSON tarih biçimi. Geriye kalanlar fiili standartlardır, her birinin artıları / eksileri vardır. Standartlarla ilgili güzel bir şey bu.
Marc L.

17

Müthiş iş parçacığında yayınlama:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));

1
Güzel fikir, ama ya bir saat dilimi ofseti dahil edilirse? Bu durumda dilim (6, -2) yerine substr (6) kullanmak daha iyidir - aşağıdaki cevabıma bakın.
Roy Tinker

17

Buraya başka bir yaklaşım eklemek için, burada ve başka yerlerde anlatıldığı gibi son derece dikkatli değilseniz , WCF'nin aldığı "keneler yaklaşımı" zaman dilimleri ile ilgili sorunlara yatkındır . Şimdi, hem .NET hem de JavaScript'in saat dilimi ofsetleri içeren gerektiği gibi desteklediği ISO 8601 biçimini kullanıyorum. Ayrıntılar aşağıdadır:

WCF / .NET'te:

CreationDate bir System.DateTime olduğunda; ToString ("o"), .NET'in ISO 8601 uyumlu bir tarih dizesi oluşturan Gidiş-dönüş formatı belirtecini kullanıyor

new MyInfo {
    CreationDate = r.CreationDate.ToString("o"),
};

JavaScript'te

JSON'u aldıktan hemen sonra, ISO 8601 tarih dizesini kabul eden Date yapıcısını kullanarak tarihleri ​​JavaSript Date nesneleri olarak düzeltmeye giderim ...

$.getJSON(
    "MyRestService.svc/myinfo",
    function (data) {
        $.each(data.myinfos, function (r) {
            this.CreatedOn = new Date(this.CreationDate);
        });
        // Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
       alert(data.myinfos[0].CreationDate.toLocaleString());
    }
)

JavaScript tarihine sahip olduğunuzda, toDateString , toLocaleString vb.Gibi tüm kullanışlı ve güvenilir Tarih yöntemlerini kullanabilirsiniz .


16
var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

JQuery kütüphanesini kullanmadan başka bir seçenek var mı?


Bu yeni bir sorudur ve kendi sorusu olarak sorulmalı ve buraya gömülmemelidir.
Spencer Sullivan

11

Bu da size yardımcı olabilir.

 function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
        var pattern = /Date\(([^)]+)\)/;
        var results = pattern.exec(value);
        var dt = new Date(parseFloat(results[1]));
        return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
    }

10

Aşağıda JSON tarihlerini ayrıştırmak için oldukça basit bir çözüm var. İhtiyacınıza göre aşağıdaki işlevleri kullanın. Sadece aşağıdaki işlevlere parametre olarak getirilen JSON biçimini aktarmanız gerekir:

function JSONDate(dateStr) {
    var m, day;
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    return (m + '/' + day + '/' + d.getFullYear())
}

function JSONDateWithTime(dateStr) {
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    var m, day;
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    var formattedDate = m + "/" + day + "/" + d.getFullYear();
    var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
    var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
    var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
    formattedDate = formattedDate + " " + formattedTime;
    return formattedDate;
}

10

Farklı yerelleştirilmiş biçimlerle ilgilenmeyi ve tarih değerleri ile diğer işlemleri gerçekleştirmeyi planladığınızda kullanışlı olan JavaScript kütüphanesi moment.js'yi de kullanabilirsiniz :

function getMismatch(id) {
    $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
        $("#AuthMerchId").text(result.AuthorizationMerchantId);
        $("#SttlMerchId").text(result.SettlementMerchantId);
        $("#CreateDate").text(moment(result.AppendDts).format("L"));
        $("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
        $("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
        $("#LastUpdatedBy").text(result.LastUpdateNt);
        $("#ProcessIn").text(result.ProcessIn);
    }
    );
    return false;
}

Yerelleştirmeyi ayarlamak, projenize yapılandırma dosyaları (momentjs.com adresinden alırsınız) eklemek ve dili yapılandırmak kadar kolaydır:

moment.lang('de');

9

Tarihi böyle alıyorum:

"/Date(1276290000000+0300)/"

Bazı örneklerde tarih biraz farklı formatlardadır:

"/Date(12762900000000300)/"
"Date(1276290000000-0300)"

vb.

Bu yüzden aşağıdaki RegExp ile geldim:

/\/+Date\(([\d+]+)\)\/+/

ve son kod:

var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));

Umarım yardımcı olur.

Güncelleştirme: Bu bağlantıyı Microsoft'tan buldum: JSON ile Tarihleri ​​Nasıl Seri Hale Getiririm?

Bu hepimizin aradığı gibi görünüyor.


1
Normal ifade değiştirmeleri yavaş ... Substr (6) kullanarak tamsayı kısmını yakalamak ve parseInt () öğesine aktarmak çok daha hızlı - aşağıdaki cevabımı görün.
Roy Tinker


9

Tarih ISO standardını kontrol edin; bunun gibi:

yyyy.MM.ddThh:mm

Olur 2008.11.20T22:18.


JSON Şemasına göre, "tarih-saat" biçimi RFC 3339, bölüm 5.6'ya karşılık gelir. Bu nedenle, GMT'deki tarihler için "yyyy-AA-ggTHH: mm: ssZ" yazmalı veya Z, + ss: dd gibi bir saat dilimi ile değiştirilmelidir.
gnasher729

Sorun, WCF ve diğer "eski" MS JSON serileştirmenin bu biçimi kullanmaması ve bunun hesaba katılması gerektiğidir.
Marc

9

Bu sinir bozucu. Benim çözüm "/ ve /" ASP.NET JavaScriptSerializer tarafından oluşturulan değerden ayrıştırmak oldu, böylece JSON bir tarih değişmezi olabilir, ancak yine de tarayıcı tarafından bir tarih olarak yorumlanır, bu tüm gerçekten istemek:{"myDate":Date(123456789)}

DateTime için özel JavaScriptConverter?

Roy Tinker'in yorumunun doğruluğunu vurgulamalıyım. Bu yasal JSON değil. JavaScript için bir sorun haline gelmeden önce sorunu kaldırmak sunucudaki kirli, kirli bir saldırıdır. Bir JSON ayrıştırıcısını boğacaktır. Onu yerden çıkmak için kullandım, ama artık kullanmıyorum. Ancak, yine de en iyi cevabın, sunucunun tarihi nasıl biçimlendirdiğini, örneğin başka bir yerde belirtildiği gibi ISO'yu değiştirmekten kaynaklandığını hissediyorum.


2
Bu yasal JSON değil. Yalnızca bir Javascript yorumlayıcısıyla değerlendirme yaparken çalışır. Ancak bir JSON dekoderi kullanıyorsanız, boğulur.
Roy Tinker

1
Kabul. Ve eğer sadece bu tek parça veri ile uğraşıyor olsaydım, bunu düşünmezdim. Ancak birkaç tarih ve diğer özelliklerin bir nesnesiyle uğraşıyorsam, her şeyi değerlendirmek () her seferinde özellikleri seçmekten daha kolaydır. Sonunda, temel sorun (yasal) bir JSON tarihinin olmamasıdır. O zamana kadar, yaratıcı saldırılarımıza bırakıldık.
StarTrekRedneck

8

Geç bir gönderi, ancak bu gönderiyi arayanlar için.

Şunu hayal edin:

    [Authorize(Roles = "Administrator")]
    [Authorize(Roles = "Director")]
    [Authorize(Roles = "Human Resources")]
    [HttpGet]
    public ActionResult GetUserData(string UserIdGuidKey)
    {
        if (UserIdGuidKey!= null)
        {
            var guidUserId = new Guid(UserIdGuidKey);
            var memuser = Membership.GetUser(guidUserId);
            var profileuser = Profile.GetUserProfile(memuser.UserName);
            var list = new {
                              UserName = memuser.UserName,
                              Email = memuser.Email ,
                              IsApproved = memuser.IsApproved.ToString() ,
                              IsLockedOut = memuser.IsLockedOut.ToString() ,
                              LastLockoutDate = memuser.LastLockoutDate.ToString() ,
                              CreationDate = memuser.CreationDate.ToString() ,
                              LastLoginDate = memuser.LastLoginDate.ToString() ,
                              LastActivityDate = memuser.LastActivityDate.ToString() ,
                              LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
                              IsOnline = memuser.IsOnline.ToString() ,
                              FirstName = profileuser.FirstName ,
                              LastName = profileuser.LastName ,
                              NickName = profileuser.NickName ,
                              BirthDate = profileuser.BirthDate.ToString() ,
            };
            return Json(list, JsonRequestBehavior.AllowGet);
        }
        return Redirect("Index");
    }

Gördüğünüz gibi, "Otomatik" Jenerikler oluşturmak için C # 3.0 özelliğini kullanıyorum. Biraz tembel, ama hoşuma gidiyor ve işe yarıyor. Sadece bir not: Profil, web uygulaması projem için oluşturduğum özel bir sınıftır.


her yeni rol eklediğinizde [Yetkilendir (Roles = "İnsan Kaynakları")], derlemeniz ve dağıtmanız mı gerekiyor? vay .... :)
Alex Nolasco

1
Bu bir JSON hizmetiyse, yönlendirme yanlış görünüyor. Giriş anahtarı çok geçersizse, bulunamayan bir 404 bulunamadı bulundu (ve gerçekten bulunamazsa da 404). Kullanıcılarım oturum açmadığında 403 Yasak dönüyorum.
Richard Corfield

Bu "yeniden kullanılabilir" bir yöntemdir. Örneğin, başka bir Görünümden kullanıcı verileri almak istersem, kimliği sağladığım sürece alabilirim. Bununla birlikte, Kimlik sağlanmazsa, sayfa bir kullanıcı seçmek için bir kullanıcı listesine (Dizin) yönlendirir. Uygulama için gereken basit bir çözüm, beynimin o sırada pişirdiği şekilde.
Ray Linder

8

FYI, sunucu tarafında Python kullanan herkes için: datetime.datetime (). Ctime (), "new Date ()" tarafından yerel olarak ayrıştırılabilen bir dize döndürür. Yani, yeni bir datetime.datetime örneği oluşturursanız (datetime.datetime.now gibi), dize JSON dizesine eklenebilir ve bu dize Date yapıcısına ilk bağımsız değişken olarak geçirilebilir. Henüz bir istisna bulamadım, ama çok da test etmedim.


8

Mootools çözeltisi:

new Date(Date(result.AppendDts)).format('%x')

Mootools-daha fazlasını gerektirir. Firefox 3.6.3 ve IE 7.0.5730.13 üzerinde mootools-1.2.3.1-more kullanılarak test edilmiştir


8
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];

8

Ekle jQuery UI sayfanıza eklentisi:

function DateFormate(dateConvert) {
    return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};

8

Ne olursa .NET döner ...

return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"

Ve sonra JavaScript'te ...

var x = new Date("2013-09-17 15:18:53Z");
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.