JavaScript'in Date yapıcısında ay bağımsız değişkeni neden 0 ile 11 arasında değişiyor?


128

DateAşağıdaki çağrıyı kullanarak JavaScript'te yeni bir nesneyi başlatırken , ay bağımsız değişkeninin sıfırdan başlayarak sayıldığını öğrendim.

new Date(2010, 3, 1);  // that's the 1st April 2010!

Ay bağımsız değişkeni neden 0'dan başlıyor? Öte yandan, ayın günü bağımsız değişkeni (sonuncusu) 1'den 31'e kadar bir sayıdır. Bunun için iyi nedenler var mı?


96
Sadece seni ayakta tutmak için.
SeanJA

4
Ayrıca sıfır endeksli olan the Day of the week (integer)0-6 arası
SeanJA

Çünkü insanlar için değil, makineler için kodlanmıştı. Ama yine de büyük bir hata kaynağıdır çünkü birçok kod (hala) insanlar tarafından yazılmıştır :)
Christophe Roussy

4
@Christophe aynı argüman gün ve yıl için de geçerli olmalıdır.
Agnel Kurian

2
@ChristopheRoussy evet, makineler için kodlanmışsa, neden 1'den itibaren indeks günleri?
user151496

Yanıtlar:


55

Bu, programlama dünyasında eski (muhtemelen talihsiz, muhtemelen ölmekte olan) bir gelenektir, eski standart (POSIX) yerel zaman C işlevine bakın http://linux.die.net/man/3/localtime


14
JS Datenesnesi Java 1.0'dan taşındı, bu yüzden. Tüm kusurlarını miras alıyor ... stackoverflow.com/questions/344380/…
c69

1
Haklısın, gelenekler genellikle tamamen tutarsızdır ve çoğu zaman mantıksızdır ve bu tür "kötü" geleneklerin gerçekten ölmekte olduğunu umuyorum ...
henon

1
2019 ve bu davranışla ilgili bir sorunu düzeltirim, bu nedenle açısal çerçeveler ve javascript gibi diller bunu reddetmediği sürece bu yine de olacaktır - 2025 ve sonrasında ;-)
Mauricio Gracia Gutierrez

Bu, beni her zaman tarihlerle ilgili sorunları ayıklamak için harcayan bir gelenek ... Bu geleneğin ne kadar boşa giden çalışma saatlerine neden olduğunu merak ediyorum.
Vedmant

102

Bu sorunun gerçek cevabı java.util.Date, bu tuhaflığı da içeren , kopyalanmış olmasıdır . Kanıt, Twitter'da, başlangıçta JavaScript'i uygulayan ( Datenesne dahil ) olan Brendan Eich'ten bulunabilir :

https://twitter.com/BrendanEich/status/481939099138654209

ilk tweet

https://twitter.com/BrendanEich/status/771006397886533632

ikinci tweet

Bu 1995'te oldu ve JDK 1.0 beta sürümündeydi. Bu 1997 yılında 1996 yılında başlatılan, JDK 1.1 üzerinde fonksiyonların büyük çoğunluğunu kaldırılmış hangi çıktı java.util.Dateonları üzerinde hareket, java.util.Calendarama yine de sıfır tabanlı ay vardı bile. Bundan bıkmış geliştiriciler Joda-Time kitaplığını oluşturdu ve sonuçta java.timeJava 8'e (2014) eklenen bir pakete yol açtı .

Kısacası, Java'nın doğru tasarlanmış bir tarih / saat API'sini yerleşik olarak alması 18 yıl sürdü, ancak JavaScript hala karanlık çağlarda geride kaldı. Gerçekten de Moment.js , date-fns ve js-joda gibi mükemmel kitaplıklarımız var . Ancak şu an itibariyle Date, dilde yerleşik olmaktan başka bir şey yok . Umarım bu yakın gelecekte değişecektir.


24
Ah ... Eski güzel Demo-Driven Development metodolojisi.
Álvaro González

@ ÁlvaroGonzález Onu ilk etapta tanıtan orijinal JDK 1.0 geliştiricisini suçlardım.
barell

30

Ayın günü hariç her şey 0 temellidir, aralıklar dahil tam liste için buraya bakın :)

Aslında buradaki tuhaflıklar olan 1 temelli günler ... garip bir şekilde yeterince. Bu neden yapıldı? Bilmiyorum ... ama muhtemelen aynı toplantıda sıvanmış ve noktalı virgüllerin isteğe bağlı olduğuna karar vermişlerdir.


1
"Bir-temelli" günler olayı, muhtemelen aklı başında hiç kimsenin günlerce bir dizi isim dizisi yaratmayacağı (örneğin, { "first", "second", "third", ..., "twenty-seventh", ... }) ve onu indekslemeye çalışmayacağı içindir tm_mday. Sonra tekrar, belki sadece bir hatayı düzenli bir olay haline getirmenin mutlak faydasını görmüşlerdir .
D.Shawley

Yıllar neden 0 temelli değil?
Vedmant


4

Java'da da böyle .. Muhtemelen int'i dizgeye (0 - jan ,, 1-feb) dönüştürmek için, bu şekilde kodladılar .. çünkü ay isimlerinden oluşan bir dizi (0'dan indekslenmiş) olabilir ve bu ay sayılar 0'dan başlarlarsa, ay dizelerine eşlemek çok daha kolay olacaktır ..


3

Bunun orijinal soruya gerçekten bir cevap olmadığını biliyorum, ancak size zaman zaman ortaya çıktıkça asla ezberlemediğim bu soruna tercih ettiğim çözümü göstermek istedim.

Küçük işlev olan zerofill, gerektiğinde sıfırları doldurmak için hile yapar ve ay +1eklenir:

function zerofill(i) {
    return (i < 10 ? '0' : '') + i;
}

function getDateString() {
    const date = new Date();
    const year = date.getFullYear();
    const month = zerofill(date.getMonth()+1);
    const day = zerofill(date.getDate());
    return year + '-' + month + '-' + day;
}

Ama evet, Date'in oldukça mantıksız bir API'si var, Brendan Eich'in Twitter'ını okuduğumda gülüyordum.


2

Ayları bir numaralandırma (ilk indeks 0) olarak ve kendileriyle ilişkili bir isme sahip olmadıkları için günleri düşünmemiş olabilirler.

Daha doğrusu, günün sayısının günün gerçek temsili olduğunu düşündüler (ayların 12/31 gibi bir tarihte sayılarla temsil edildiği gibi), sanki değişkenler olarak sayılarla bir sıralama yapabilirmişsiniz gibi, ama aslında 0 tabanlı.

Aslında, aylar boyunca, belki de doğru numaralandırma temsilinin sayılar yerine ayın ismini kullanmak olacağını düşündüler ve günler bir isim temsili olsaydı aynı şeyi yapacaklardı. 5 Ocak, 6 Ocak vb. Yerine Beş Ocak, Altıncı Ocak desek, o zaman belki de günlerce 0 tabanlı bir sıralama yapmış olurlardı ...

Belki de bilinçaltında, güne ad yerine sayı olarak eriştiğiniz günler dışında, aylarca {Ocak, Şubat, ...} ve günler için {Bir, İki, Üç, ...} olarak bir sıralama düşünmüşlerdir, Bir için 1 gibi, vb. 0'dan başlamak çok imkansız ...


Psikoloğa çift sınıf yapmalısınız. Hala yaptıkları bir hata, ama en azından şimdi neden yaptıklarını anlıyoruz.
Zesty

0

Bir kusur olabilir, ancak aynı zamanda haftanın aylarını veya günlerini bir dize olarak göstermek istediğinizde de çok kullanışlıdır, sadece ['jan,' feb '... vb] gibi bir dizi oluşturabilirsiniz [new Date () .getMonth ()] yerine ['', 'ocak', feb ... vb] [yeni Tarih (). getMonth ()] veya ['ocak', 'şubat' ... vb] [yeni Tarih ( ) .getMonth () - 1]

Normalde ayın günleri adlandırılmaz, bu nedenle onlar için isimlerle diziler yapmayacaksınız. Bu durumda 1-31'in işlenmesi daha kolaydır, bu nedenle her seferinde 1'i çıkarmak zorunda kalırsınız ...


pek sayılmaz. Kolayca bir tane çıkarabilirsin. Çözdüğünden daha fazla sorun yaratır çünkü artık tarihlerle matematik yaptığınızda, ay içinde sık sık belirli bir manipülasyon yapmanız gerekir.
Rey
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.