En java.util.Calendar
Der Januar ist als Monat 0 definiert, nicht als Monat 1. Gibt es dafür einen bestimmten Grund?
Ich habe gesehen, wie viele Leute darüber verwirrt waren...
En java.util.Calendar
Der Januar ist als Monat 0 definiert, nicht als Monat 1. Gibt es dafür einen bestimmten Grund?
Ich habe gesehen, wie viele Leute darüber verwirrt waren...
Das ist nur ein Teil des schrecklichen Durcheinanders, das die Java Datum/Zeit-API darstellt. Aufzulisten, was damit nicht in Ordnung ist, würde sehr lange dauern (und ich bin sicher, dass ich nicht einmal die Hälfte der Probleme kenne). Zugegeben, die Arbeit mit Daten und Zeiten ist knifflig, aber aaargh sowieso.
Tun Sie sich einen Gefallen und verwenden Sie Joda Zeit stattdessen, oder möglicherweise JSR-310 .
EDIT: Was die Gründe dafür angeht - wie in anderen Antworten erwähnt, könnte es durchaus an alten C-APIs liegen, oder einfach an dem allgemeinen Gefühl, dass alles bei 0 anfängt... außer, dass Tage mit 1 beginnen, natürlich. Ich bezweifle, dass irgendjemand außerhalb des ursprünglichen Implementierungsteams wirklich Gründe nennen kann - aber auch hier möchte ich den Lesern raten, sich nicht so viele Sorgen zu machen 如何して Fehlentscheidungen getroffen wurden, als die ganze Palette der Gemeinheiten in java.util.Calendar
und etwas Besseres zu finden.
Ein Punkt, der ist für die Verwendung von 0-basierten Indizes ist, dass es Dinge wie "Arrays von Namen" einfacher macht:
// I "know" there are 12 months
String[] monthNames = new String[12]; // and populate...
String name = monthNames[calendar.get(Calendar.MONTH)];
Das klappt natürlich nicht, sobald man einen Kalender mit 13 Monaten erhält... aber zumindest ist die angegebene Größe die Anzahl der Monate, die man erwartet.
Dies ist keine gut Grund, aber es ist a Grund...
EDIT: Als eine Art Kommentar fordert einige Ideen darüber, was ich denke, ist falsch mit Datum/Kalender:
Date
y Calendar
als unterschiedliche Dinge, aber die Trennung zwischen "lokalen" und "zonierten" Werten fehlt, ebenso wie die Trennung zwischen Datum/Uhrzeit und Datum/ZeitDate.toString()
Implementierung, die immer die lokale Zeitzone des Systems verwendet (das hat schon viele Stack Overflow-Benutzer verwirrt)Denn Rechnen mit Monaten ist viel einfacher.
1 Monat nach Dezember ist Januar, aber um das herauszufinden, müssten Sie normalerweise die Monatszahl nehmen und rechnen
12 + 1 = 13 // What month is 13?
Ich weiß! Ich kann dies schnell beheben, indem ich einen Modulus von 12 verwende.
(12 + 1) % 12 = 1
Das funktioniert 11 Monate lang gut, bis November...
(11 + 1) % 12 = 0 // What month is 0?
Man kann das Ganze wieder hinbekommen, indem man 1 subtrahiert, bevor man den Monat addiert, dann den Modulus durchführt und schließlich wieder 1 addiert... aka ein zugrundeliegendes Problem umgehen.
((11 - 1 + 1) % 12) + 1 = 12 // Lots of magical numbers!
Betrachten wir nun das Problem mit den Monaten 0 - 11.
(0 + 1) % 12 = 1 // February
(1 + 1) % 12 = 2 // March
(2 + 1) % 12 = 3 // April
(3 + 1) % 12 = 4 // May
(4 + 1) % 12 = 5 // June
(5 + 1) % 12 = 6 // July
(6 + 1) % 12 = 7 // August
(7 + 1) % 12 = 8 // September
(8 + 1) % 12 = 9 // October
(9 + 1) % 12 = 10 // November
(10 + 1) % 12 = 11 // December
(11 + 1) % 12 = 0 // January
Alle Monate funktionieren gleich und eine Umgehung ist nicht erforderlich.
C-basierte Sprachen kopieren C bis zu einem gewissen Grad. Die tm
Struktur (definiert in time.h
) hat ein ganzzahliges Feld tm_mon
mit dem (kommentierten) Bereich von 0-11.
C-basierte Sprachen beginnen Arrays bei Index 0. Dies war also praktisch für die Ausgabe einer Zeichenkette in einem Array mit Monatsnamen, mit tm_mon
als Index.
Es gab schon viele Antworten auf diese Frage, aber ich werde trotzdem meine Meinung zu diesem Thema äußern. Der Grund für dieses merkwürdige Verhalten liegt, wie bereits erwähnt, in der POSIX C time.h
wobei die Monate in einem int mit dem Bereich 0-11 gespeichert wurden. Um zu erklären, warum, betrachten Sie es so: Jahre und Tage werden in der gesprochenen Sprache als Zahlen betrachtet, aber Monate haben ihre eigenen Namen. Da der Januar also der erste Monat ist, wird er als Offset 0, dem ersten Array-Element, gespeichert. monthname[JANUARY]
wäre "January"
. Der erste Monat des Jahres ist das erste Element des Monatsarrays.
Da die Tageszahlen keine Namen haben, wäre es verwirrend, sie als 0-30 in einer int-Datei zu speichern, was eine Menge an day+1
Anweisungen für die Ausgabe und sind natürlich anfällig für viele Bugs.
Abgesehen davon ist die Inkonsistenz verwirrend, vor allem in Javascript (das dieses "Feature" ebenfalls geerbt hat), einer Skriptsprache, in der dies weit von der Sprache abstrahiert werden sollte.
TL;DR : Weil die Monate Namen haben und die Tage des Monats nicht.
In Java 8 gibt es eine neue Date/Time-API JSR 310 die vernünftiger ist. Der Leiter der Spezifikation ist derselbe wie der Hauptautor von JodaTime und sie teilen viele ähnliche Konzepte und Muster.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.