Bagaimana cara memformat tanggal Microsoft JSON?

2000

Saya mengambil celah pertama saya di Ajax dengan jQuery. Saya mendapatkan data saya ke halaman saya, tetapi saya mengalami beberapa masalah dengan data JSON yang dikembalikan untuk tipe data Date. Pada dasarnya, saya mendapatkan string kembali yang terlihat seperti ini:

/Date(1224043200000)/

Dari seseorang yang sama sekali baru ke JSON - Bagaimana cara memformat ini ke format tanggal pendek? Haruskah ini ditangani di suatu tempat dalam kode jQuery? Saya sudah mencoba jQuery.UI.datepickermenggunakan plugin $.datepicker.formatDate()tanpa hasil.

FYI: Inilah solusi yang saya gunakan dengan menggunakan kombinasi jawaban di sini:

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;
}

Solusi ini mendapatkan objek saya dari metode panggilan balik dan menampilkan tanggal pada halaman dengan benar menggunakan perpustakaan format tanggal.

Peter Mortensen
sumber
26
Ini mungkin menarik: hanselman.com/blog/…
citronas
6
Format / Tanggal (... )/ adalah khusus untuk format JSON Date bawaan Microsoft - ini bukan bagian dari standar apa pun, dan JSON, yang berasal dari Javascript, memiliki standar: Format ISO yang ditentukan Javascript: stackoverflow.com/a / 15952652/176877 Jadi, pertanyaan ini khusus untuk format Tanggal JSON Microsoft. Saya memodifikasi judul untuk memperjelas ini.
Chris Moschini
15
Kamu bercanda! Microsoft telah mencap putaran mereka sendiri di JSON! dan pada tanggal !! Kapan mereka akan belajar!
Nick.McDermaid
Gunakan Newtonsoft JSON di sisi .NET dan untuk memiliki nilai yang diketik bagus di sisi JS, cukup gunakan: github.com/RickStrahl/json.date-extensions
baHI
Anda bisa menggunakan JSON ++ bukan JSON. JSON ++ sama dengan JSON tetapi dengan dukungan untuk tipe JavaScript seperti Date.
brillout

Jawaban:

1688

eval()tidak perlu. Ini akan bekerja dengan baik:

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

The substr()Fungsi mengambil keluar /Date(bagian, dan parseInt()fungsi mendapat integer dan mengabaikan )/di akhir. Angka yang dihasilkan dilewatkan ke Datekonstruktor.


Saya sengaja mengabaikan radix (argumen ke-2 parseInt); lihat komentar saya di bawah ini .

Juga, saya sepenuhnya setuju dengan komentar Rory : Tanggal ISO-8601 lebih disukai daripada format lama ini - jadi format ini umumnya tidak boleh digunakan untuk pengembangan baru. Lihat perpustakaan Json.NET yang sangat baik untuk alternatif hebat yang membuat serialisasi tanggal menggunakan format ISO-8601.

Untuk tanggal JSON yang diformat ISO-8601, cukup masukkan string ke Datekonstruktor:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Roy Tinker
sumber
4
@ Buram: Kedua metode (fungsi ganti dan jawaban ini) harus berubah jika MS mengubah format.
Roy Tinker
23
Bisakah Anda memperbaruinya dengan radix var date = Date baru (parseInt (jsonDate.substr (6), 10));
James Kyburz
6
@JamesKyburz: Setiap aturan memiliki pengecualian, dan saya pikir ini adalah saat pengecualian berlaku. Nomor tanggal JSON dari .NET tidak pernah memiliki "0" yang memimpin, sehingga kita dapat dengan aman meninggalkan radix.
Roy Tinker
22
Perlu dicatat bahwa format tanggal ini sangat buruk dan langkah umumnya adalah tanggal berformat ISO-8601 di JSON. Lihat hanselman.com/blog/...
Rory
4
Pendekatan ini gagal mempertimbangkan zona waktu sehingga dapat menyebabkan masalah serius ketika server dan pengguna Anda berada di zona waktu yang berbeda. Saya memposting jawaban di bawah ini yang menjelaskan cara yang sangat cepat dan mudah untuk menghadapinya di sisi WCF dan Javascript: stackoverflow.com/a/10743718/51061
Scott Willeke
135

Anda dapat menggunakan ini untuk mendapatkan tanggal dari JSON:

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

Dan kemudian Anda dapat menggunakan skrip Format Tanggal JavaScript (1,2 KB saat diperkecil dan di-gzip) untuk menampilkannya sesuai keinginan.

Panos
sumber
7
Tidak ada yang salah dengan garis, urutannya adalah \ //. Slash pertama lolos sehingga tidak dihitung seperti komentar. Itu editor Anda yang menipu Anda, salurannya akan berfungsi dengan baik.
andreialecu
152
@rball, omong kosong:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
kelopak mata
39
pst itu benar, adalah mungkin untuk melakukan ini dalam berbagai cara tanpa 'eval'. Crockford mengatakan bahwa 'eval Is Evil' karena kurang dapat dibaca dan kurang aman, lebih jauh lagi ia mungkin menyiratkan bahwa itu kurang efisien dan lebih berbahaya karena hits kompiler javascript.
Mark Rogers
13
@Edy: new Functionhampir sama buruknya dengan eval: dev.opera.com/articles/view/efisien-javascript/...
Marcel Korpel
5
@ Eddy: Itu adalah bentuk lain dari eval, dan sama jahatnya. Alih-alih mengurai string (lihat jawaban saya di bawah)
Roy Tinker
98

Bagi mereka yang menggunakan Newtonsoft Json.NET , baca tentang cara melakukannya melalui Native JSON di IE8, Firefox 3.5 plus Json.NET .

Juga dokumentasi tentang mengubah format tanggal yang ditulis oleh Json.NET berguna: Membuat Tanggal dengan Json.NET

Bagi mereka yang terlalu malas, berikut adalah langkah-langkah cepatnya. Karena JSON memiliki implementasi DateTime yang longgar, Anda perlu menggunakan IsoDateTimeConverter(). Perhatikan bahwa sejak Json.NET 4.5 format tanggal default adalah ISO sehingga kode di bawah ini tidak diperlukan.

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

JSON akan muncul sebagai

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

Akhirnya, beberapa JavaScript untuk mengonversi tanggal ISO menjadi tanggal JavaScript:

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;
}

Saya menggunakannya seperti ini

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
Jason Jong
sumber
6
Konstruktor JavaScript Date dapat menguraikan string untuk Anda:new Date("2009-04-12T20:44:55")
David Hogue
5
Peringatan - Date () Format konstruktor dan parsing adalah non-standar sebelum ECMAScript 6. Sebagai contoh, IE 9 memperlakukan tanggal yang Anda berikan konstruktor sebagai waktu lokal bahkan jika dalam IS0-8601 yang tersirat sebagai UCT di mana pun. Jangan mengandalkan konstruktor tanggal jika Anda mendukung browser lama. codeofmatt.com/2013/06/07/...
DanO
Mengirim tanggal yang bukan UTC akan cepat atau lambat akan membawa Anda ke masalah.
tymtam
Sedikit terlambat ke pesta di sini, tapi apa yang akan (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; mewakili dalam konteks ini?
yanant
@yanant - +a[1]dll merupakan potongan array dari regex dan +akan dilemparkan ke angka, jadi +a[1]sama dengan 2009dll. Berikut adalah rincian array: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong
67

Contoh asli:

/Date(1224043200000)/  

tidak mencerminkan pemformatan yang digunakan oleh WCF saat mengirim tanggal melalui WCF REST menggunakan serialisasi JSON bawaan. (setidaknya pada. NET 3.5, SP1)

Saya menemukan jawabannya di sini bermanfaat, tetapi sedikit pengeditan pada regex diperlukan, karena tampaknya zona waktu GMT offset sedang ditambahkan ke nomor yang dikembalikan (sejak 1970) di WCF JSON.

Dalam layanan WCF saya punya:

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

ApptVisitLinkInfo didefinisikan secara sederhana:

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

Ketika "Field2" dikembalikan sebagai Json dari layanan, nilainya adalah:

/Date(1224043200000-0600)/

Perhatikan offset zona waktu termasuk sebagai bagian dari nilai.

Regex yang dimodifikasi:

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

Ini sedikit lebih bersemangat dan meraih segalanya di antara parens, bukan hanya nomor pertama. Waktu yang dihasilkan sinze 1970, ditambah offset zona waktu semua dapat dimasukkan ke dalam eval untuk mendapatkan objek tanggal.

Garis yang dihasilkan dari JavaScript untuk penggantian adalah:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Harun
sumber
10
ini salah, Date baru (1224043200000-0600) hanya akan mengurangi 600 dari tanggal, dalam hal ini 600 milidetik, bukan 6 jam sebagaimana mestinya.
ariel
Saya pikir offset zona waktu hanya disertakan jika Anda memiliki zona waktu pada objek DateTime di .NET (yang merupakan perilaku default). Jika tanggal Anda berada di UTC, gunakan DateTime.SpecifyKind (date, DateTimeKind.UTC) dan Anda akan mendapatkan nilai UTC yang tepat saat keluar bersambung, tanpa offset, yang kemudian dapat dikonversi kembali ke zona waktu pengguna sesuai kebutuhan. Jika waktu lokal, gunakan .ToUniversalTime () dan akan dikonversi ke UTC, dan "Jenis" sudah ditentukan untuk Anda.
jvenema
di javascript -0100 akan menjadi string biner jadi hati-hati!
verbedr
setelah tanggal dikonversi dari WCF ke JS, bagaimana kalau terbalik. Anda harus berkencan sebagai integer (menggunakan date.getTime ()) yang ingin Anda sampaikan ke WCF yang sama?
NitinSingh
65

Jangan ulangi diri Anda sendiri - secara otomatis konversi tanggal menggunakan $.parseJSON()

Jawaban untuk posting Anda memberikan konversi tanggal manual ke tanggal JavaScript. Saya telah memperpanjang jQuery $.parseJSON()hanya sedikit, sehingga dapat secara otomatis mengurai tanggal ketika Anda menginstruksikannya. Ini memproses tanggal ASP.NET diformat tanggal ( /Date(12348721342)/) serta tanggal diformat ISO ( 2010-01-01T12.34.56.789Z) yang didukung oleh fungsi JSON asli di browser (dan perpustakaan seperti json2.js).

Bagaimanapun. Jika Anda tidak ingin mengulangi kode konversi tanggal Anda berulang-ulang, saya sarankan Anda membaca posting blog ini dan mendapatkan kode yang akan membuat hidup Anda sedikit lebih mudah.

Robert Koritnik
sumber
61

Jika Anda mengatakan dalam JavaScript,

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

Anda akan melihat bahwa itu adalah tanggal yang benar, dan Anda dapat menggunakannya di mana saja dalam kode JavaScript dengan kerangka kerja apa pun.

John Boker
sumber
3
Itulah yang akan saya pikirkan juga kecuali pada akhirnya adalah: var thedate = / Date (1224043200000) /; setidaknya untuk saya ...
rball
2
Date () dan Date (1224043200000) keduanya memberikan hasil yang sama di Chrome dan Firefox. Tidak yakin apakah ini berfungsi di browser lama, tetapi jawaban ini tidak berfungsi di browser sekarang.
James
@ James, Ya itu memberikan tanggal browser saat ini. :(
vissu
9
Anda harus menuliskannya sebagai "Tanggal baru (1224043200000)".
BrainSlugs83
60

Klik di sini untuk memeriksa Demo

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();

Hasil - "10/15/2008"

pengguna2007801
sumber
Hanya peningkatan untuk metode di atas. function formatearFecha (fec) {var value = Date baru (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, ''))); var mes = value.getMonth (); var dia = value.getDate (); var date = dia + "/" + mes + "/" + value.getFullYear (); jika (dia <10) date = date.substr (0, 0) + '0' + dia + date.substr (1); if (mes <10) date = date.substr (0, 3) + '0' + mes + date.substr (4); tanggal kembali;} tanggal diformat ke ddMMyyyy.Ceria!
Matias
38

Diperbarui

Kami memiliki pustaka UI internal yang harus mengatasi kedua format JSON /Date(msecs)/bawaan ASP.NET Microsoft, seperti , yang awalnya ditanyakan di sini, dan sebagian besar format tanggal JSON termasuk JSON.NET, seperti 2014-06-22T00:00:00.0. Selain itu, kita perlu mengatasi ketidakmampuan oldIE untuk mengatasi apa pun kecuali 3 tempat desimal .

Kami pertama-tama mendeteksi jenis tanggal yang kami konsumsi, menguraikannya menjadi Dateobjek JavaScript normal , lalu memformatnya.

1) Mendeteksi format Microsoft Date

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

2) Mendeteksi format tanggal ISO

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) Format tanggal Parse MS:

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

4) Memformat format tanggal ISO.

Kami setidaknya memiliki cara untuk memastikan bahwa kami berurusan dengan tanggal ISO standar atau tanggal ISO yang dimodifikasi untuk selalu memiliki tiga tempat milidetik ( lihat di atas ), sehingga kode ini berbeda tergantung pada lingkungan.

4a) Memformat format Tanggal ISO standar, mengatasi masalah oldIE:

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) Format Parse ISO dengan desimal tiga milidetik tetap - jauh lebih mudah:

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

5) Format itu:

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) Ikat semuanya:

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

    return formatDate(d);
}

Jawaban lama di bawah ini berguna untuk mengikat pemformatan tanggal ini ke parsing JSON jQuery sendiri sehingga Anda mendapatkan objek Date daripada string, atau jika Anda masih terjebak di jQuery <1,5 entah bagaimana.

Jawaban Lama

Jika Anda menggunakan fungsi Ajax jQuery 1.4 dengan ASP.NET MVC, Anda bisa mengubah semua properti DateTime menjadi objek Date dengan:

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

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

Di jQuery 1.5 Anda dapat menghindari mengganti parseJSONmetode secara global dengan menggunakan opsi konverter dalam panggilan Ajax.

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

Sayangnya Anda harus beralih ke rute eval yang lebih lama untuk mendapatkan Tanggal untuk menguraikan secara global di tempat - jika tidak, Anda perlu mengonversinya berdasarkan basis kasus per kasus.

Chris Moschini
sumber
27

Tidak ada tipe tanggal bawaan di JSON . Ini terlihat seperti jumlah detik / milidetik dari beberapa zaman. Jika Anda tahu zamannya, Anda dapat membuat tanggal dengan menambahkan jumlah waktu yang tepat.

Johnstok
sumber
Itu tidak benar, JSON menggunakan tanggal Javascript, dengan informasi zona waktu tambahan - zamannya sama dengan zaman kelas Tanggal javascript (untuk alasan yang jelas).
BrainSlugs83
3
@ BrainSlug83 - jawaban ini memberikan referensi untuk pernyataan bahwa JSON tidak memiliki tipe tanggal bawaan. Jika Anda tidak setuju, berikan referensi alternatif. (Anda tidak memikirkan kerangka kerja tertentu yang telah memutuskan format string untuk mewakili tanggal, bukan? Itu bukan bagian dari standar JSON, memang tidak mungkin karena tidak memungkinkan untuk memasukkan string yang tidak seharusnya diambil sebagai tanggal tetapi itu kebetulan memiliki serangkaian karakter yang cocok dengan pola tanggal.)
nnnnnn
25

Saya juga harus mencari solusi untuk masalah ini dan akhirnya saya menemukan moment.js yang merupakan pustaka bagus yang dapat menguraikan format tanggal ini dan banyak lagi.

var d = moment(yourdatestring)

Ini menyelamatkan beberapa sakit kepala untuk saya, jadi saya pikir saya akan membagikannya kepada Anda. :)
Anda dapat menemukan lebih banyak info tentang itu di sini: http://momentjs.com/

Venemo
sumber
24

Saya akhirnya menambahkan "karakter ke dalam ekspresi reguler Panos untuk menghilangkan yang dihasilkan oleh serializer Microsoft ketika menulis objek ke dalam skrip inline:

Jadi, jika Anda memiliki properti di kode C # Anda -belakang itu seperti itu

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

Dan dalam aspx Anda, Anda miliki

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

Anda akan mendapatkan sesuatu seperti

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

Perhatikan tanda kutip ganda.

Untuk mendapatkan ini ke bentuk yang eval akan deserialize dengan benar, saya menggunakan:

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

Saya menggunakan Prototipe dan untuk menggunakannya saya menambahkan

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

Di jQuery 1.5, selama Anda memiliki json2.js untuk menutupi peramban yang lebih lama, Anda dapat membatalkan deserialisasi semua tanggal yang datang dari Ajax sebagai berikut:

(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);
        }
      }
    });
}());

Saya menyertakan logika yang mengasumsikan Anda mengirim semua tanggal dari server sebagai UTC (yang seharusnya); konsumen kemudian mendapatkan Dateobjek JavaScript yang memiliki nilai kutu yang tepat untuk mencerminkan hal ini. Yaitu, panggilan getUTCHours(), dll. Pada tanggal tersebut akan mengembalikan nilai yang sama seperti di server, dan panggilan getHours()akan mengembalikan nilai dalam zona waktu lokal pengguna sebagaimana ditentukan oleh browser mereka.

Ini tidak memperhitungkan format WCF dengan offset zona waktu, meskipun itu relatif mudah untuk ditambahkan.

Domenic
sumber
Sama seperti catatan: agar kode berfungsi, Anda harus membuat metode beginWith dengan tipe string
Hugo Zapata
21

Menggunakan datepicker jQuery UI - benar-benar masuk akal jika Anda sudah memasukkan jQuery UI:

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

keluaran:

15 Oktober 2008

dominan
sumber
20

Jangan terlalu memikirkan ini. Seperti yang telah kami lakukan selama beberapa dekade, berikan offset numerik dari zaman standar de-facto 1 Januari 1970 tengah malam GMT / UTC / & c dalam beberapa detik (atau milidetik) sejak zaman ini. JavaScript menyukainya, Java menyukainya, C menyukainya, dan Internet menyukainya.

Xepoch
sumber
2
Dan sayangnya ada lebih dari 20 zaman untuk dipilih. en.wikipedia.org/wiki/Epoch_(reference_date)
Jerther
18

Setiap orang dari jawaban ini memiliki satu kesamaan: semuanya menyimpan tanggal sebagai nilai tunggal (biasanya string).

Opsi lain adalah untuk mengambil keuntungan dari struktur yang melekat dari JSON, dan mewakili tanggal sebagai daftar angka:

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

Tentu saja, Anda harus memastikan kedua ujung percakapan menyetujui format (tahun, bulan, hari), dan bidang mana yang dimaksudkan sebagai tanggal, ... tetapi memiliki keuntungan untuk sepenuhnya menghindari masalah tanggal konversi ke string. Itu semua angka - tidak ada string sama sekali. Selain itu, menggunakan pesanan: tahun, bulan, hari juga memungkinkan penyortiran yang tepat berdasarkan tanggal.

Hanya berpikir di luar kotak di sini - tanggal JSON tidak harus disimpan sebagai string.

Bonus lain untuk melakukannya dengan cara ini adalah bahwa Anda dapat dengan mudah (dan efisien) memilih semua catatan untuk tahun atau bulan tertentu dengan memanfaatkan cara CouchDB menangani kueri pada nilai array.

Nick Perkins
sumber
Ada adalah format standar untuk tanggal di JSON, yang merupakan format RFC 3339.
gnasher729
@gnasher, itu akan menyenangkan, tetapi tidak demikian halnya. Tidak ada referensi dari RFC 7159 hingga 3339 atau sebaliknya. Tidak ada format tanggal JSON standar de jure . Yang tersisa hanyalah standar de facto , yang masing-masing memiliki pro / kontra. Itu hal yang menyenangkan tentang standar.
Marc L.
17

Posting di utas luar biasa:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Dan Beam
sumber
1
Gagasan bagus, tetapi bagaimana jika offset zona waktu disertakan? Lebih baik menggunakan substr (6) dalam kasus itu daripada slice (6, -2) - lihat jawaban saya di bawah ini.
Roy Tinker
17

Hanya untuk menambahkan pendekatan lain di sini, "pendekatan kutu" yang diambil WCF rentan terhadap masalah dengan zona waktu jika Anda tidak terlalu berhati-hati seperti yang dijelaskan di sini dan di tempat lain. Jadi saya sekarang menggunakan format ISO 8601 yang didukung .NET & JavaScript sebagaimana mestinya termasuk zona waktu. Berikut ini rinciannya:

Di WCF / .NET:

Di mana CreationDate adalah System.DateTime; ToString ("o") menggunakan specifier format Round-trip .NET yang menghasilkan string tanggal yang sesuai dengan ISO 8601

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

Dalam JavaScript

Hanya setelah mengambil JSON saya pergi fixup tanggal menjadi objek JavaSript Date menggunakan konstruktor Tanggal yang menerima string tanggal 8601 ISO ...

$.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());
    }
)

Setelah Anda memiliki tanggal JavaScript, Anda dapat menggunakan semua metode Tanggal yang nyaman dan andal seperti toDateString , toLocaleString , dll.

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

Apakah ada opsi lain tanpa menggunakan perpustakaan jQuery?

blgnklc
sumber
Ini adalah pertanyaan baru dan harus ditanyakan sebagai pertanyaan sendiri dan tidak tertanam di sini.
Spencer Sullivan
11

Ini juga dapat membantu Anda.

 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();
    }
Ravi Mehta
sumber
10

Di bawah ini adalah solusi yang cukup sederhana untuk mem-parsing tanggal JSON. Gunakan fungsi di bawah ini sesuai kebutuhan Anda. Anda hanya perlu meneruskan format JSON Tanggal yang diambil sebagai parameter ke fungsi di bawah ini:

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;
}
Umar Malik
sumber
10

Anda juga dapat menggunakan library JavaScript moment.js , yang berguna ketika Anda berencana menangani berbagai format lokal dan melakukan operasi lain dengan nilai tanggal:

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;
}

Menyiapkan pelokalan semudah menambahkan file konfigurasi (Anda mendapatkannya di momentjs.com) ke proyek Anda dan mengonfigurasi bahasa:

moment.lang('de');
martinoss
sumber
9

Saya mendapatkan tanggal seperti ini:

"/Date(1276290000000+0300)/"

Dalam beberapa contoh, tanggal dalam format yang sedikit berbeda:

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

dll.

Jadi saya datang dengan RegExp berikut:

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

dan kode terakhir adalah:

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

Semoga ini bisa membantu.

Pembaruan: Saya menemukan tautan ini dari Microsoft: Bagaimana cara saya Serialize Tanggal dengan JSON?

Ini sepertinya yang kita semua cari.

Michael Vashchinsky
sumber
1
Pengganti regexp lambat ... Jauh lebih cepat untuk mengambil bagian integer menggunakan substr (6) dan meneruskannya ke parseInt () - lihat jawaban saya di bawah ini.
Roy Tinker
9

Periksa tanggal standar ISO; jenis seperti ini:

yyyy.MM.ddThh:mm

Menjadi 2008.11.20T22:18.

Thomas Hansen
sumber
Menurut Skema JSON, format "tanggal-waktu" sesuai dengan RFC 3339, bagian 5.6. Jadi Anda harus menulis "yyyy-MM-ddTHH: mm: ssZ" untuk tanggal dalam GMT, atau Z diganti dengan zona waktu seperti + hh: mm.
gnasher729
Masalahnya adalah bahwa WCF dan serialisasi MS JSON "lama" lainnya tidak menggunakan format ini, dan itu harus dipertanggungjawabkan.
Marc L.
9

Ini membuat frustrasi. Solusi saya adalah mem-parsing keluar "/ dan /" dari nilai yang dihasilkan oleh JavaScriptSerializer ASP.NET sehingga, meskipun JSON mungkin tidak memiliki tanggal literal, itu masih akan ditafsirkan oleh browser sebagai tanggal, itulah yang saya benar-benar ingin:{"myDate":Date(123456789)}

Custom JavaScriptConverter untuk DateTime?

Saya harus menekankan keakuratan komentar Roy Tinker. Ini bukan JSON legal. Ini adalah hack kotor di server untuk menghapus masalah sebelum menjadi masalah bagi JavaScript. Ini akan mencekik parser JSON. Saya menggunakannya untuk turun dari tanah, tapi saya tidak menggunakannya lagi. Namun, saya masih merasakan jawaban terbaik terletak dengan mengubah cara format server tanggal, misalnya, ISO seperti yang disebutkan di tempat lain.

StarTrekRedneck
sumber
2
Itu bukan JSON legal. Ini hanya akan berfungsi ketika mengevaluasi dengan penerjemah Javascript. Tetapi jika Anda menggunakan dekoder JSON, itu akan tersedak.
Roy Tinker
1
Sepakat. Dan jika saya hanya berurusan dengan sepotong data ini, saya tidak akan mempertimbangkannya. Tetapi jika saya berurusan dengan objek beberapa tanggal dan properti lainnya, lebih mudah untuk mengevaluasi () semuanya daripada memilih properti satu per satu. Pada akhirnya, masalah utama adalah tidak adanya tanggal JSON (legal). Sampai itu ada, kita dibiarkan meretas kreatif kita.
StarTrekRedneck
8

Posting yang terlambat, tetapi untuk mereka yang mencari posting ini.

Bayangkan ini:

    [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");
    }

Seperti yang Anda lihat, saya menggunakan fitur C # 3.0 untuk membuat Generik "Otomatis". Agak malas, tapi saya suka dan berhasil. Sekedar catatan: Profil adalah kelas khusus yang saya buat untuk proyek aplikasi web saya.

Ray Linder
sumber
jadi setiap kali Anda menambahkan peran baru [Otorisasi (Peran = "Sumber Daya Manusia")], Anda harus menyusun dan menggunakan? wow .... :)
Alex Nolasco
1
Jika ini adalah layanan JSON maka pengalihan tampaknya salah. Saya akan mengembalikan 404 Tidak Ditemukan jika kunci input sangat tidak valid sehingga tidak dapat ditemukan, (dan juga 404 jika benar-benar tidak ditemukan). Ketika pengguna saya tidak masuk saya mengembalikan 403 Forbidden.
Richard Corfield
Ini metode "dapat digunakan kembali". Misalnya, jika saya ingin mendapatkan data pengguna dari Tampilan lain, saya bisa mendapatkannya selama saya memberikan ID. Namun, jika Id tidak disediakan, halaman akan diarahkan ke daftar pengguna (Indeks) untuk memilih pengguna. Solusi sederhana diperlukan untuk aplikasi, persis seperti otak saya yang memasaknya saat itu.
Ray Linder
8

FYI, bagi siapa saja yang menggunakan Python di sisi server: datetime.datetime (). Ctime () mengembalikan string yang dapat diurai secara alami oleh "new Date ()". Yaitu, jika Anda membuat contoh datetime.datetime baru (seperti dengan datetime.datetime.now), string dapat dimasukkan dalam string JSON, dan kemudian string itu dapat diteruskan sebagai argumen pertama ke konstruktor Tanggal. Saya belum menemukan pengecualian, tetapi saya juga belum mengujinya dengan ketat.

Kyle Alan Hale
sumber
8

Solusi Mootools:

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

Membutuhkan lebih banyak mootool. Diuji menggunakan mootools-1.2.3.1-lebih pada Firefox 3.6.3 dan IE 7.0.5730.13

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

Tambahkan plugin jQuery UI di halaman Anda:

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

Bagaimana jika .NET mengembalikan ...

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

Dan kemudian di JavaScript ...

var x = new Date("2013-09-17 15:18:53Z");
Juan Carlos Puerto
sumber