Soru Javascript'te tarih ayrıştırma, safari ve krom arasında farklıdır


Takip koduna sahibim

var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);

Chrome'da, konsoldaki tarihi doğru şekilde yazdırır. Safari'de başarısız. Kim doğru ve en önemlisi en iyi yol nedir? Bunu halletmek için?


44
2018-06-21 14:44


Menşei


İkisi de bana veriyor Tue Jun 21 2011 10:27:28 GMT-0400 (Eastern Daylight Time) - Robert
Emin misin. jsfiddle.net/A26Gu safari üzerinde çalıştırmak Sürüm 5.0.4 (6533.20.27) bana "geçersiz tarih" konsolu bir çıkış verir - bradgonesurfing
Neden bir Date nesnesini iki kez oluşturuyorsunuz? Doğru tanımınız nedir? 'Date.toISOString ()' yöntemini kullanabilirsiniz. Ancak farkında olun: Eski tarayıcılar tarafından desteklenmez. - Wolfgang Kuehn
Hmm, garip ... Sadece konsolda koştum, bunun için bir sayfa yapmamaya çalıştım. Bir şey yapmadan JSFiddle'ı çektiğimde konsolda çalıştı, ancak başka bir sayfa NaN döndürür. Ayrıca 5.0.5 (7533.21.1) çalıştırıyorum. - Robert
Javascript Date, 2 saat dilimini, UTC'yi ve işletim sisteminden yerel olanı destekler. Yerel saat diliminin doğru ayarlandığından emin olamazsınız. Ve Javascript'in müşteri tarafında olduğu gibi, doğru bir şey yapmıyorsa güvende olursunuz - hatta ayrıştırma tarihleri ​​bile yok. Herhangi bir uygulama kritik hesaplamalar sunucu tarafı yapılmalıdır. - Erik


Cevaplar:


Date.parse'yi gerçekten kullanamazsınız. Kullanmanızı öneririm: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )

Dize bölmek için deneyebilirsiniz

var s = '2011-06-21T14:27:28.593Z';
var a = s.split(/[^0-9]/);
//for (i=0;i<a.length;i++) { alert(a[i]); }
var d=new Date (a[0],a[1]-1,a[2],a[3],a[4],a[5] );
alert(s+ " "+d);

81
2018-06-21 14:52



Bu tarih dizeleri sunucudan geliyor. Onları ayrı bileşenlere ayırmanın bir yolu varsa, duymaktan mutluluk duyarım. - bradgonesurfing
Bölünme eğlencesini kullanırdım: javascript.about.com/od/hintsandtips/a/javascriptsplit.htm - Erik
bölme kullanımı yanıtlamak için eklendi - Erik
Bu sadece tarihler yerel saatlerde verilirse çalışır. Saat dilimini çevirir ve yerel olarak uygulanır. Örnek: -0500 saat diliminde, 11 am utc gönderiyorsunuz, 6 am yerel geri dönmelisiniz, ancak bunun yerine 11 yerel postayı almalısınız. - dlsso
Disso'nun söylediği gibi, bu cevap saat dilimini yok sayar. 00:00 ("Z") ofset ile bir dizge alır ve yerelmiş gibi ayrıştırır. Date.UTC kullanılmalıydı. - RobG


Kaçınmak eğilimindedir Date.parseBu soruya verilen diğer cevaplara göre. Tarihlerle güvenilir bir şekilde ilgilenmek için taşınabilir bir yol gibi görünmüyor.

Bunun yerine, aşağıdaki işlev gibi bir şey kullandım. Bu, dize dizisini bir dizi dizisine eşlemek için jQuery'yi kullanır, ancak bu, kaldırmaya / değiştirmeye oldukça kolay bir bağımlılıktır. Ayrıştırmanızı sağlamak için mantıklı varsayılanları düşündüğüm şeyi de dahil ediyorum 2007-01-09 ve 2007-01-09T09:42:00 aynı işlevi kullanarak.

function dateFromString(str) {
  var a = $.map(str.split(/[^0-9]/), function(s) { return parseInt(s, 10) });
  return new Date(a[0], a[1]-1 || 0, a[2] || 1, a[3] || 0, a[4] || 0, a[5] || 0, a[6] || 0);
}

13
2018-02-23 12:38



Çok güzel bir Hack Jabley. - Bingy


Birkaç tarayıcıda kontrol ettim ve evet, safari geri döndü invalid date. Bu arada, kullanmak zorunda değilsin Date.parse burada, sadece new Date([datestring]) çok çalışacak. Safari, sağladığınız veri setinin daha fazla biçimlendirilmesini gerektirir. '-' ile '/' değiştirirseniz, T'yi ve noktadan (.593Z) sonra her şeyi kaldırın, size geçerli bir tarih verecektir. Bu kod test edildi ve Safari'de çalışıyor

var datestr = '2011-06-21T14:27:28.593Z'.split(/[-T.]/);
var safdat = new Date( datestr.slice(0,3).join('/')+' '+datestr[3] );

Veya kullanarak String.replace(...):

new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/(\..*|\+.*/,""))

8
2018-06-21 15:48



Bu, saat dilimini ve sonuçta meydana gelen Date nesnesinin kesirlerini kaybetmenize neden olur. Bu bileşenleri yeniden eklemek için sonunda ek bir kod ekleyebileceğinizi tahmin ediyorum. - Tim Tisdall
Teşekkürler, bu yeterince iyi ve çalıştı. - Daniel Sokolowski
3. regex'te parantez gerekli değildir: new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/\..*|\+.*/,"")) - steevee


Bunu telafi etmek için kütüphane kullanıyorum:

http://zetafleet.com/blog/javascript-dateparse-for-iso-8601

Bu kitaplık eklendikten sonra, yeni tarihi oluşturmak için bu kodu kullanırsınız:

var date = new Date(Date.parse(datestring));

Projemiz milisaniye belirleyicileri kullanmıyordu, ancak bunun sizin için bir sorun yaratacağına inanmıyorum.


5
2017-09-13 21:18





Benzer sorunma, bir RFC 822 saat dilimi biçimindeki saat dilimini nasıl okuyacağımı bilmeden Safari'den kaynaklandı. Bunu ISO 8601 formatını kullanarak düzeltebiliyordum. Eğer tarih formatını kontrol ederseniz, bu benim için üreten java'nın SimpleDateFormat "yyyy-MM-dd'T'HH: mm: ss.sssXXX" ile çalışıyorum. "2018-02-06T20: 00: 00.000 + 04: 00". Safari her ne sebeple olursa olsun "2018-02-06T20: 00: 00.000 + 0400" mesajını okuyamaz, saat dilimi biçiminde iki nokta üst üste gelmediğine dikkat edin.

// Works
var c = new Date("2018-02-06T20:00:00.000+04:00"));
console.log(c);

// Doesn't work
var c = new Date("2018-02-06T20:00:00.000+0400"));
console.log(c);

4
2018-03-06 19:21





Saat dilimi ile tarih ayrıştırmak için aşağıdaki işlevi kullanıyorum. Hem Chrome hem de Safari’de iyi çalışıyor:

function parseDate(date) {
  const parsed = Date.parse(date);
  if (!isNaN(parsed)) {
    return parsed;
  }

  return Date.parse(date.replace(/-/g, '/').replace(/[a-z]+/gi, ' '));
}

console.log(parseDate('2017-02-09T13:22:18+0300'));  // 1486635738000 time in ms


2
2018-02-10 03:47



Bunu yapmanın en güvenli yolu budur. Sanırım son değiştirmeyi bir şey gibi değiştirmelisin /[a-z]+/gi, yalnızca T yerine UTC ile tarihler gibi daha geniş bir kitleyi eşleştirmek için - Narayon
@Narayon Yorumunuz için teşekkürler, cevabı değiştirdim. - Londeren


dönüştürülmüş tarihi, onu keserek ve bunun gibi ayrıştırmayı denedim, safari ve ios ile çalışıyor.

var dateString = "2016-01-22T08:18:10.000+0000";
 var hours = parseInt(dateString.split("+")[1].substr("0","2"));
 var mins = parseInt(dateString.split("+")[1].substr("2"));
 var date = new Date(dateString.split("+")[0]);
 date.setHours(date.getHours()-hours);
 date.setMinutes(date.getMinutes()-mins);

1
2018-01-27 05:07





Tarih dizesinin sonunda 'Z' kullanmak yerine, yerel istemci saat dilimi ofseti ekleyebilirsiniz. Muhtemelen sizin için bunu üretmek için bir yöntem isteyeceksiniz:

let timezoneOffset = () => {
    let date = new Date(),
        timezoneOffset = date.getTimezoneOffset(),
        hours = ('00' + Math.floor(Math.abs(timezoneOffset/60))).slice(-2),
        minutes = ('00' + Math.abs(timezoneOffset%60)).slice(-2),
        string = (timezoneOffset >= 0 ? '-' : '+') + hours + ':' + minutes;
    return string;
}

Yani sonuç şöyle olur:

var c = new Date("2011-06-21T14:27:28.593" + timezoneOffset());


0
2018-04-27 19:55



Safari'de Geçersiz Tarih ... - Mirko