Safari'de geçersiz tarih


155
 alert(new Date('2010-11-29'));

chrome, ff'nin bu konuda bir sorunu yok, ancak safari "geçersiz tarih" ağlıyor. Neden ?

edit: ok, aşağıdaki yorumlara göre, dize ayrıştırma kullanılır ve bunu denedim:

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

edit 22 22 2018 : İnsanlar hala buraya iniyor gibi görünüyor - Bugün, ben kullanmak momentveya date-fnsonunla yapılır. Date-fns aynı zamanda ağrısız ve hafiftir.


Sadece aynı soruna bakmak için: DateJS kullandım, bu da genel olarak sorunumu çözdü .. Ayrıntılar için kabul edilen cevaba bakınız.
Shrinath

2
kullanmak moment.js damgası ayrıştırmak. Özellikle çapraz platform ağı ile uğraşırken
Ming Yuen

1
Bu eski bir soru. ECMAScript 2015 itibarıyla, ISO 8601 yalnızca tarih dizeleri UTC olarak ayrıştırılır. Bununla birlikte, etrafta hala ayrıştırmayacak veya yerel olarak davranmayacak daha eski tarayıcılar olabilir.
RobG

Yanıtlar:


167

Desen yyyy-MM-dd, Datekurucu için resmi olarak desteklenen bir biçim değildir . Firefox destekliyor gibi görünüyor, ancak aynı şeyi yapan diğer tarayıcılara güvenmeyin.

Desteklenen bazı dizeler şunlardır:

  • AA-gg-yıl
  • yyyy / AA / gg
  • AA / gg / yyyy
  • AAAA gg, yyyy
  • Ggm gg, yyyy

DateJS, standart olmayan tarih biçimlerini ayrıştırmak için iyi bir kütüphane gibi görünüyor.

Düzenleme : ECMA-262 standardını kontrol ettiniz . Bölüm 15.9.1.15'ten alıntı:

Tarih Saat Dize Biçimi

ECMAScript, ISO 8601 Genişletilmiş Biçiminin basitleştirilmesine dayalı olarak tarih saatleri için bir dize değişim biçimi tanımlar. Biçim aşağıdaki gibidir: YYYY-AA-GGTHY: aa: ss.sssZ Alanlar aşağıdaki gibidir:

  • YYYY, Gregoryen takvimindeki yılın ondalık basamağıdır.
  • Dizede "-" (hipon) tam anlamıyla iki kez görünür.
  • MM, 01 (Ocak) ile 12 (Aralık) arasında yılın ayıdır.
  • DD, 01'den 31'e kadar ayın günüdür.
  • Zaman öğesinin başlangıcını belirtmek için dizede "T" harfi görüntülenir.
  • SS, gece yarısından bu yana iki ondalık basamak olarak geçen tam saatlerin sayısıdır.
  • ":" (iki nokta üst üste), dizede tam anlamıyla iki kez görünür.
  • mm, saat başlangıcından bu yana iki ondalık basamak olarak geçen dakikaların toplam sayısıdır.
  • ss, dakika başlangıcından bu yana geçen tam ondalık basamak sayısıdır.
  • "" (nokta) tam olarak dizede görünür.
  • sss, saniyenin üç ondalık hane olarak başlamasından bu yana geçen tam milisaniye sayısıdır. İkisi de "." ve milisaniye alanı atlanabilir.
  • Z, "Z" (UTC için) veya "+" veya "-" olarak belirtilen saat dilimi ofsetidir, ardından saat ifadesi ss: dd

Bu biçim yalnızca tarih içeren formları içerir:

  • YYYY
  • YYYY-AA
  • YYYY-AA-GG

Ayrıca, isteğe bağlı bir saat dilimi uzaklığı eklenmiş yalnızca zaman içeren formlar içerir:

  • THH: dd
  • THH: dd: ss
  • THH: dd: dd.sss

Ayrıca, yukarıdakilerin herhangi bir kombinasyonu olabilen "tarih saatleri" de dahildir.

Yani, YYYY-AA-DD standartta yer alıyor gibi görünüyor, ancak bir nedenden dolayı Safari bunu desteklemiyor.

Güncelleme : datejs belgelerine baktıktan sonra , sorununuz aşağıdaki gibi bir kod kullanılarak çözülmelidir:

var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");

4
ISO8601 formatı, ECMAScript standardının 5. sürümünde kullanılmaktadır ve IMO'ya gitmenin en güvenli yolu olan tarihi henüz desteklememektedir :(
CMS

1
Bu çok yardımcı oldu dostum .. Teşekkür ederim .. :) Sonunda biçimlendirme için datejs kullanarak sona erdi.
Shrinath

Gelecekte olanlar için, datejs çoğu bakımdan harika olsa da, tüm tarih biçimlendirme sorunlarını, özellikle safari ile çözmediğini lütfen unutmayın. bir PITA ama yine de sorunlarınız varsa elle yapmak en iyisidir.
totallyNotLizards

@darioo Cevabınızı aşağıdaki gibi denedim: "var start = Date.parseExact (zaman damgası," YYYY-GG-AA SS: dd: SS ");" zaman damgası "2016-01-28 00:00:00" şeklindedir. Ancak şimdi "Date.parseExact bir işlev değil" hatası alıyorum. Burada ne oluyor biliyor musun?
threxx

5
Benzer sorunum Safari'nin saat dilimini bir RFC 822 saat dilimi biçiminde nasıl okuyacağını bilmemesinden kaynaklandı. Bunu ISO 8601 biçimini kullanarak çözebildim. Tarih biçiminin kontrolünü elinizde varsa, yani "yyyy-AA-gg'T'HH: mm: ss.sssXXX" ile çalışıyorum. "2018-02-06T20: 00: 00.000 + 00: 00". Herhangi bir nedenle Safari "2018-02-06T20: 00: 00.000 + 0000" 'ı okuyamıyorsa, saat dilimi biçiminde kolon eksikliğine dikkat edin.
Olmstov

224

Safari'nin doğru bir şekilde yapamaması nedeniyle yeni bir kütüphane uygulamak benim için çok fazla ve bir regex aşırı derecede dolu. İşte oneliner :

console.log (new Date('2011-04-12'.replace(/-/g, "/")));

Eğer bir eğik çizgi almak benim sorunum olsaydı, o zaman cevabını 'kabul etmeliydim (bu soruyu sorduğumda tek amacım buydu). DateJS'yi bulduğumdan, daha kullanıcı dostu bir deneyim için MMM DD, YYYY formatını uyguladım !!!
Shrinath

13
Bu tek hat yardımı ihtiyacım için mükemmel oldu! Teşekkürler!
Cyril

4
Bu benim için de yeterince basitti. Safari'nin - 'dan hoşlanmadığına inanamıyorum ama \\ ile aynı formatta çalışıyor. Teşekkürler @Elzo ve Shrinath soruyu gönderdiği için teşekkürler
Pete

1
Yerine / g - Bu G / unutma eğiliminde en iyi yanıt olduğunu düşünüyorum '-'
Jacek Pietal

12
kütüphane uygulamadığı için alkışlar .
lharby

57

Benzer bir sorunla karşı karşıyaydım. Date.Parse("DATESTRING")Chrome üzerinde çalışıyordu (Sürüm 59.0.3071.115), ancak Safari üzerinde çalışmıyordu (Sürüm 10.1.1 (11603.2.5))

Safari:

Date.parse("2017-01-22 11:57:00")
NaN

Krom:

Date.parse("2017-01-22 11:57:00")
1485115020000

Benim için işe yarayan çözüm dateString içindeki boşluğun yerini almaktı "T". (Örnek: dateString.replace(/ /g,"T"))

Safari:

Date.parse("2017-01-22T11:57:00")
1485086220000

Krom:

Date.parse("2017-01-22T11:57:00")
1485115020000

Safari tarayıcıdan gelen yanıtın Chrome tarayıcıda görülen yanıttan 8 saat (28800000ms) daha az olduğunu unutmayın, çünkü Safari yerel TZ'de yanıt verdi (UTC'nin 8 saat gerisinde)

Aynı TZ'de iki kere almak için

Safari:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

Krom:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

Veya Safari ve Chrome'da her iki tarihin de aynı olmasını istemiyorsanız yapıcıyı kullanabilirsiniz new Date(year, month, date, hours, minutes, seconds, milliseconds). Yapıcıda bu bileşenleri kullanmak için dize tarihini bileşenlerinin bir dizisine ayrıştırın. @nizantz Cevabınıza böyle bir örnek eklenebileceğini düşünürseniz harika olur.
h3dkandi

Tarihi UTC olarak aldığınızdan ve yerel saat değil, özellikle yararlı değildir.
Jonas Äppelgran

1
Bu dateString.replace(/ /g,"T")sihirli kod satırı benim için çalıştı. :)
Mazdak Shojaie

değiştir (/ - / g, '/')
Jack Hu

11

Sorunu çözmek için anı kullanıyorum. Örneğin

var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();

10

Çoğu tarayıcıda çalışan bir çözüm elde etmek için, tarih nesnenizi bu biçimde oluşturmalısınız

(year, month, date, hours, minutes, seconds, ms)

Örneğin:

dateObj = new Date(2014, 6, 25); //UTC time / Months are mapped from 0 to 11
alert(dateObj.getTime()); //gives back timestamp in ms

IE, FF, Chrome ve Safari ile iyi çalışır. Daha eski sürümler bile.

IE Geliştirici Merkezi: Tarih Nesnesi (JavaScript)

Mozilla Dev Ağı: Tarih


6

string'i Date fromat'a dönüştürün (sunucu saat dilimini bilmeniz gerekir)

new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()  

burada +08: 00 = sunucudan timeZone


Bu DST'yi dikkate almaz. TZ ofseti dalgalanabilir ve tarihin kendisine (ve saate) bağlıdır.
costa

5

Aynı sorunu yaşadım, sonra anı kullandım.Js .Problem kayboldu.

Bir dizeden bir an oluştururken, önce dizenin bilinen ISO 8601 biçimleriyle eşleşip eşleşmediğini kontrol ederiz, sonra bilinen bir biçim bulunmazsa yeni Tarih'e (dize) geri döneriz.

Uyarı: Dizeleri ayrıştırma için tarayıcı desteği tutarsız. Hangi biçimlerin desteklenmesi gerektiği konusunda herhangi bir belirti olmadığından, bazı tarayıcılarda işe yarayan diğer tarayıcılarda çalışmaz.

ISO 8601 dizeleri dışında herhangi bir şeyi ayrıştıran tutarlı sonuçlar için String + Format kullanmalısınız.

Örneğin

var date= moment(String);

3

Tarayıcıların ISO 8601'i (veya yalnızca tarih alt kümelerini) desteklemesini umabilirsiniz , ancak durum böyle değildir. Bildiğim tüm tarayıcılar (en azından kullandığım ABD / İngilizce yerel ayarlarında) korkunç ABD MM/DD/YYYYbiçimini ayrıştırabilir .

Tarihin bölümlerine zaten sahipseniz, bunun yerine Date.UTC () öğesini kullanmayı denemek isteyebilirsiniz . Bunu yapmazsanız, ancak YYYY-MM-DDbiçimi kullanmanız gerekiyorsa, tanıdığınız parçaları ayrıştırmak ve sonra bunları aktarmak için normal bir ifade kullanmanızı öneririm Date.UTC().


Sanırım dize ayrıştırma gitmek için yol :(
Shrinath

1

Aşağıdaki biçimi kullanın, tüm tarayıcılarda çalışır

var year = 2016;
var month = 02;           // month varies from 0-11 (Jan-Dec)
var day = 23;

month = month<10?"0"+month:month;        // to ensure YYYY-MM-DD format
day = day<10?"0"+day:day;

dateObj = new Date(year+"-"+month+"-"+day);

alert(dateObj); 

// Çıktınız şu şekilde görünecektir "23 Mart 2016 Çrş 00:00:00 GMT + 0530 (IST)"

// Bunun IST tarafından belirtilen geçerli saat diliminde olacağını, UTC saat dilimine dönüştürmek için

alert(dateObj.toUTCSting);

// Çıktınız şimdi bunu istiyor "Sal, 22 Mar 2016 18:30:00 GMT"

DateObj'nin saati GMT formatında gösterdiğini, tarih ve saatin de buna göre değiştirildiğini unutmayın.

"ToUTCSting" işlevi Greenwich meridyenindeki ilgili zamanı alır. Bu, geçerli saat diliminiz ile Greenwich Meridyen saat dilimi arasındaki zaman farkını belirleyerek başarır.

Yukarıdaki durumda, dönüşümden önceki süre 2016 yılında 23 Mart'ta 00:00 saat ve dakika idi. Ve GMT + 0530 (IST) saatinden GMT'ye dönüşümden sonra (temel olarak bu vaka) zaman, 2016 yılında 22 Mart'ta 18.30 saati yansıtmaktadır (ilk kez tam olarak 5.30 saat geridedir).

Ayrıca herhangi bir tarih nesnesini zaman damgasına dönüştürmek için kullanabilirsiniz

alert(dateObj.getTime());

// çıktı bu "1458671400000" e benzer bir şey olurdu

Bu size zamanın eşsiz zaman damgasını verir



1

Bunu yapmanın en iyi yolu aşağıdaki biçimi kullanmaktır:

new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);

Bu, tüm tarayıcılarda desteklenir ve size herhangi bir sorun oluşturmaz. Ayların 0 ile 11 arasında olduğunu lütfen unutmayın.


Safari ve Chrome'da iyi çalışır, ancak Firefox'ta hala sorunları vardır. Safari: var tarih = yeni Tarih (2018,06,08,19,17) Paz 08 Temmuz 2018 19:17:00 GMT + 0800 (+08) Krom: var tarih = yeni Tarih (2018,06,08,19, 17) Paz 08 Temmuz 2018 19:17:00 GMT + 0800 (Malezya Saati) Firefox: var tarih = yeni Tarih (2018,06,08,19,17) Tarih 2018-07-08T11: 17: 00.000Z
Biranchi

0

Safari'de karşılaşılan aynı sorun ve bunu web sayfasına ekleyerek çözüldü

 <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script> 

Umarım da sizin durumunuzda çalışır

Teşekkürler


Sizce bu neden işe yarar? Betiğe baktım ve Date nesnesindeki yöntemleri geçersiz kılıyor gibi görünmüyor. Buraya gittim: polyfill.io/v3/url-builder ve tarihleri ​​ayrıştırma konusunda hiçbir şey yok gibi görünüyor.
Kosta

0

@Nizantz'ın daha önce de belirttiği gibi, Date.parse () kullanmak Safari'de benim için çalışmadı. Biraz araştırma yaptıktan sonra, File nesnesi için lastDateModified özelliğinin kullanımdan kaldırıldığını ve artık Safari tarafından desteklenmediğini öğrendim. File nesnesinin lastModified özelliğini kullanmak sorunlarımı çözdü. Çevrimiçi kötü bilgi bulunduğunda sevmediğinizden emin olun.

Bu gönderiye katkıda bulunan herkese teşekkürler, sorunum hakkında bilgi edinmem gerekiyordu. Bu bilgi olmasaydı, muhtemelen kök sorunumu çözemezdim. Belki bu benim benzer durumumda başka birine yardımcı olacaktır.


0

Safari Tarayıcı'da da aynı sorunla karşılaşıyorum

var date = new Date("2011-02-07");
console.log(date) // IE you get ‘NaN’ returned and in Safari you get ‘Invalid Date’

İşte çözüm:

var d = new Date(2011, 01, 07); // yyyy, mm-1, dd  
var d = new Date(2011, 01, 07, 11, 05, 00); // yyyy, mm-1, dd, hh, mm, ss  
var d = new Date("02/07/2011"); // "mm/dd/yyyy"  
var d = new Date("02/07/2011 11:05:00"); // "mm/dd/yyyy hh:mm:ss"  
var d = new Date(1297076700000); // milliseconds  
var d = new Date("Mon Feb 07 2011 11:05:00 GMT"); // ""Day Mon dd yyyy hh:mm:ss GMT/UTC 

0

Hatayı yakalayıp güncel tarihi geri göndermeme rağmen bu en iyi çözüm değil. Şahsen ben Safari sorunlarını çözmüyor gibi hissediyorum, eğer kullanıcılar standartlara uygun olmayan bir tarayıcı kullanmak istiyorlarsa - tuhaflıklarla yaşamak zorundalar.

function safeDate(dateString = "") {
  let date = new Date();
  try {
    if (Date.parse(dateString)) {
      date = new Date(Date.parse(dateString))
    }
  } catch (error) {
    // do nothing.
  }
  return date;
}

Arka ucunuzun ISO tarihleri ​​göndermesini öneririm.


Saygılarımla, kullanıcıların kod yazdığınız tarayıcıyı kullanması gerektiği anlamına gelirse , bu genel anlamda kötü görünüyor. Aynı zamanda kullanım durumlarımıza ve hedef kitleye de bağlıdır - kitle pazarının tüketimi için bir web sitesi oluşturuluyorsa, en azından IE10'u da destekliyoruz. Internet Explorer için tasarım / kodlama yaparken MS'de aynı şeyi düşündüğünden eminim. Şimdi bunun nasıl konuşulduğunu hepimiz biliyoruz.
Shrinath

-1

'aa / gg / yyyy' biçimini kullanın. Örneğin: - yeni Tarih ('02 / 28/2015 '). Tüm tarayıcılarda iyi çalışır.

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.