Als Anfänger sind Dates eines der interessantesten Themen, die Sie lernen werden. Auch wenn es etwas langweilig klingt, ist es eines der wichtigsten Dinge, die Sie vielleicht wissen; aus Ihrer Datenbank, API, GUI und mehr zu lernen, wie man richtig mit Datumsangaben umgeht, ist ein Schlüsselfaktor beim Schreiben guter Anwendungen.
Ein wichtiges Detail, an das Sie sich erinnern müssen, ist, dass Java schnell für das Web entwickelt wurde, sodass es viele skurrile und etwas dumme Möglichkeiten gibt, Dinge zu tun. Das Ziel dieses Leitfadens besteht darin, Ihnen beizubringen, wie Sie mit den neuesten Java-APIs effizienten und guten Code schreiben. Mein Ziel ist es, Ihnen beizubringen, wie Sie nichts schwer programmieren und stattdessen standardisierte ISO-Codes für eine skalierbare Anwendung verwenden.
Ab Java 8 SE mit der Veröffentlichung der Datumsklasse definiert als:
Die Klasse „Datum“ stellt einen bestimmten Zeitpunkt mit Millisekundengenauigkeit dar.
Außerdem wurde im weiteren Verlauf die Klasse „Abstrakter Kalender“ (mit deutlichem Upgrade mit JDK 1.1) hinzugefügt, die wie folgt definiert ist:
Die Calendar-Klasse ist eine abstrakte Klasse, die Methoden zum Konvertieren zwischen einem bestimmten Zeitpunkt und einer Reihe von Kalenderfeldern wie YEAR, MONTH, DAY_OF_MONTH, HOUR usw. sowie zum Bearbeiten der Kalenderfelder bereitstellt, z das Datum der nächsten Woche abrufen. Ein Zeitpunkt kann durch einen Millisekundenwert dargestellt werden, der einen Offset von der Epoche, 1. Januar 1970 00:00:00.000 GMT (Gregorianisch), darstellt.
Wie aus den Oracle-Dokumenten hervorgeht, war der Grund der Mangel an Internationalisierungsfähigkeiten.
Es ist gut zu beachten, dass die oben verlinkte Dokumentation detaillierter auf den Zeitpunkt eingeht, falls Sie daran interessiert sind.
Außerdem kam mit Java 8 SE die LocalDate-Klasse, auf die verwiesen wird:
Ein Datum ohne Zeitzone im ISO-8601-Kalendersystem, z. B. 2007-12-03.
gespeichert werden
LocalDate ist ein unveränderliches Datum-Uhrzeit-Objekt, das ein Datum darstellt, das oft als Jahr-Monat-Tag angesehen wird. Auf andere Datumsfelder wie Tag des Jahres, Wochentag und Woche des Jahres kann ebenfalls zugegriffen werden. Beispielsweise kann der Wert „2. Oktober 2007“ in einem LocalDate.
Eine wichtige Spezifikation, die Sie beachten sollten, ist:
Diese Klasse speichert oder repräsentiert keine Zeit oder Zeitzone. Stattdessen handelt es sich um eine Datumsbeschreibung, wie sie bei Geburtstagen verwendet wird. Es kann keinen Zeitpunkt auf der Zeitachse ohne zusätzliche Informationen wie einen Versatz oder eine Zeitzone darstellen.
Unterschied und welches zu verwenden ist
Probleme mit den Datums-/Uhrzeit-APIs
Wenn Sie die LocalDate-Klasse weiter lesen, werden Sie zu „Diese Klasse ist unveränderlich und threadsicher“ gelangen. Das bringt uns zu unserem ersten Problem.
- Sowohl das Datum als auch der Kalender waren nicht threadsicher. Wenn Sie etwas verwirrt sind, was das bedeutet: Threads sind eine Möglichkeit, Parallelität mit einer Computeranwendung zu implementieren. Dadurch können mehrere Aufgaben gleichzeitig und nicht nacheinander ausgeführt werden. (Wenn Sie über einen Programmierhintergrund verfügen, können Sie dies als asynchron betrachten.) .
- Ein weiteres Problem mit der Datums-/Kalender-API war ihr schlechtes Design. Später wurde es so umgestaltet, dass es ISO-zentriert ist (falls Sie nicht wissen, was diese ganze ISO-Sache ist; kurz ISO steht für „International Organization for Standardization“). Die zusätzlichen Vorteile davon werden wir später sehen.
- Abschließend komme ich noch einmal auf die mangelnde Internationalisierung zurück: Entwickler mussten ihre Logik für den Umgang mit unterschiedlichen Zeitzonen schreiben, was zu vielen Fehlern wie fehlenden Übereinstimmungen führen kann.
Der größte Unterschied besteht darin, dass „Date“ trotz des Namens sowohl Uhrzeit als auch Datum speichert (wie in den Dokumenten erwähnt, mit Millisekunden-Versatz seit der Epoche – wir werden später über die Epoche sprechen). Mit der neueren API erhalten wir Zugriff auf eine einfachere Formatierung/Analyse/Manipulation von Datumsangaben.
Nun, Java deckt Sie auch hier mit seiner LocalDateTime-Klasse ab
Ein Datum und eine Uhrzeit ohne Zeitzone im ISO-8601-Kalendersystem, z. B. 2007-12-03T10:15:30.
gespeichert werden
LocalDateTime ist ein unveränderliches Datum-Uhrzeit-Objekt, das ein Datum und eine Uhrzeit darstellt, oft betrachtet als Jahr-Monat-Tag-Stunde-Minute-Sekunde. Auf andere Datums- und Zeitfelder wie Tag des Jahres, Wochentag und Woche des Jahres kann ebenfalls zugegriffen werden. Die Zeit wird mit einer Genauigkeit im Nanosekundenbereich dargestellt. Beispielsweise kann der Wert „2. Oktober 2007 um 13:45.30.123456789“ in einem LocalDateTime.
Wenn Sie nur Zeit speichern möchten, können Sie die LocalTime-Klasse verwenden
Name | Should Use | Use Case | Example |
---|---|---|---|
LocalDate | ✅ | Interprating Dates | 2021-02-28 |
LocalTime | ✅ | Interprating Time | 19:32:25.457826 |
LocalDateTime | ✅ | Interprating Time/Date | 2021-02-28T19:32:25.457826. |
Date | prefer not | Represents Time | Tue Jul 12 18:35:37 IST 2016 |
Da wir nun den Hintergrund und die Möglichkeiten, die wir damit machen können, gut verstehen, wollen wir uns mit den Methoden der LocalDate-Klasse befassen.
Das ISO-8601-Kalendersystem ist das moderne zivile Kalendersystem, das heute in den meisten Teilen der Welt verwendet wird. Es entspricht dem proleptischen gregorianischen Kalendersystem, bei dem die heutigen Regeln für Schaltjahre für alle Zeiten gelten. Für die meisten heute geschriebenen Anwendungen sind die ISO-8601-Regeln durchaus geeignet. Für jede Anwendung, die historische Daten verwendet und deren Genauigkeit erfordert, ist der ISO-8601-Ansatz jedoch ungeeignet.
Dies ist der Standard, den Java verwendet, um unsere Daten richtig zu formatieren.
Bevor wir näher darauf eingehen, möchte ich Ihnen das Temporal-Objekt vorstellen, das alle neuen Datums-APIs implementieren (LocalDate, LocalTime, LocalDateTime). Es ist wie folgt definiert:
Dies ist der Basisschnittstellentyp für Datums-, Uhrzeit- und Offset-Objekte, die vollständig genug sind, um mit Plus und Minus manipuliert zu werden. Es wird von den Klassen implementiert, die Informationen als Felder oder Abfragen bereitstellen und bearbeiten können. Die schreibgeschützte Version dieser Schnittstelle finden Sie unter TemporalAccessor.
Ich möchte nicht näher darauf eingehen, ich wollte nur, dass ihr versteht, was das ist, wenn ihr darauf stößt.
Das Format dafür ist in der richtigen Reihenfolge: Der Methodenname, die angegebene Rückgabebeschreibung und eine kurze Zusammenfassung dessen, was sie tut/oder ein ausführlicher Einblick. Wenn Sie mitmachen möchten, verwende ich jshell, importieren Sie einfach java.time.LocalDate und kopieren Sie die gleichen Methoden.
Wie in der Beschreibung erwähnt, wird das aktuelle Datumsformat basierend auf der Zeitzone zurückgegeben. Bei mir ist es beispielsweise der 10.07.2024. Das Format kann sich jedoch je nach Ortszeit ändern, abhängig vom für Ihr Land zugewiesenen ISO 8601-Format (z. B. könnte es 2024.07.10 oder 24/7/10 sein. Dies ist ein Standard, den Ihr Land verwenden würde)
Die LocalDate.now()-Methode kann ein Argument annehmen. Um dies zu nutzen, importieren wir java.time.ZoneId.
ZoneId Veröffentlicht mit Java 8SE definiert als:
Eine ZoneId wird verwendet, um die Regeln zu identifizieren, die zum Konvertieren zwischen einem Instant und einem LocalDateTime verwendet werden. Es gibt zwei verschiedene Arten von IDs:
- Feste Offsets – ein vollständig aufgelöster Offset von UTC/Greenwich, der den gleichen Offset für alle lokalen Datums- und Uhrzeitangaben verwendet
- Geografische Regionen – ein Gebiet, in dem bestimmte Regeln zum Ermitteln des Offsets von UTC/Greenwich gelten
Einfach ausgedrückt löst dies das Internationalisierungsproblem, das wir mit der alten Date-API hatten. Nach dem Import von java.time.ZoneId können wir uns einige der Methoden ansehen, die es zu bieten hat.
Es gibt auch ein Clock-Argument, das Sie weitergeben können, aber ich sehe keinen Nutzen dafür, wenn Sie einfach ZoneID verwenden könnten, aber zögern Sie nicht, das auszuprobieren
Jetzt, wo wir das erfahren haben – schauen wir uns das aktuelle Datum in Paris an!
LocalDate.now(ZoneId.of("Europe/Paris")) // 2024-07-10
Denken Sie daran, dass LocalDate ein Datum darstellt. In diesem Fall können wir dieses Datum auf ein beliebiges Jahr, einen beliebigen Monat und einen beliebigen Tag einstellen!
In vielen Fällen haben Sie möglicherweise nur ein Jahr und einen Tag. Diese Funktion wandelt es in ein Jahr-Monat-Tag-Format um. Hier ist ein Beispiel: LocalDate.ofYearDay(2023, 234) wird der 22.08.2023 sein. Auch Schaltjahre werden berücksichtigt.
Basically, if we generate a String Date format like 2023-08-22 this will convert it into a LocalDate format
There’s one last method I would like to talk about and even though it might not be that useful, it's a good thing to know.
Epoch in simple terms is a date set to the start. Virtually means it's “The start of time”. For example UNIX epoch is set to 1970/1/1 This is when all Unix time is calculated. Now this is not standardized between all computers. Most programming languages will use the UNIX epoch but not between all devices. For example NTP epoch is 1900/1/1. Now you might be asking why. And the simple answer is I don’t know. Unix was developed in 1969 and released in 71 but I guess the developers found 70 easier to work with and now that’s what we use!
Just going based on the description I gave about the output of this would be X days from 1970/1/1. Given epochDay is 1 => 1970-01-02 and so on.
~
~
~
By now I think you guys are all bored of all this nerdy talk and most likely lost interest completely but we are going to make it way more interesting in just a bit.
LocalDate methods have a ton of subsets to modify dates as we talked about above. Explaining all of these is just a waste of time. The best thing is for you guys to check ’em out and play around a bit, they are all very simple to understand.
The main idea of this whole article was to teach you internationalization and we are going to start that now.
If you recall above I talked about how LocalDate.now() might show different numbers/punctuations and this is standardized by Locale Class
A Locale object represents a specific geographical, political, or cultural region. An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user. For example, displaying a number is a locale-sensitive operation— the number should be formatted according to the customs and conventions of the user's native country, region, or culture.
Again the Locale class uses pre-defined ISO standards that Oracle has included.
As I said - In the early days of the web Java was rushed and we can really see that here.
If you import java.util.Locale you can see that we have a few constants. Locale.CANADA as an example. If you're wondering what these are and why they were picked, it's quite simple. Due to the reason mentioned above, the Java devs just picked some Locale constants to support and you should not use them. Now if you look closely we have a Locale.French
and a Locale.France and you might be confused, what is this?? I’ll talk about it in a second
Now how do we go about using these Locales? By using Locale.availableLocales() you will see a large subset of available locales that you can use. you might see it in the format of en_US and you might get confused. Following up on the question listed above Java has accounted for different language subsets used in different countries. In this France/French example, We can refer to Canadian French versus French used in France. They are not entirely the same. Now a country like Iran will use Persian no matter the place, so you could just use Locale.of(language) to specify the Locale, But for French you could rather use Locale.of(language, country). Remember if you split what you got from Locale.availableLocales() by the _ you can just format it like that. An example would be Locale.of("en", "US") for en_US
Now let's implement this into our time for our different users around the globe.
System.out.println( LocalDate.now().format( DateTimeFormatter .ofLocalizedDate(FormatStyle.SHORT) .localizedBy(Locale.GERMAN)));
Now don’t mind the extra code, and even me using Locale.GERMAN cause honestly I was looking for a different output and the easiest way was to use Javas constants. I landed on Locale.GERMAN which outputs 10.07.24 as opposed to what Japan uses (2024/07/10).
Now it might sound weird, but first of all i tell you not to use constants and prefer Locale.of(), then I tell you not to use Locale.of() an important factor to consider is Locale.of() was introduced with Java 19 which goes against supporting Java 8 SE to combat that from now on we will use
new Locale.Builder() .setLanguage("language") .setRegion("country").build();
Now another thing you could use is Locale.setDefault(language, country) which will work as well.
Now looking at the code above you might recall seeing DateTimeFormatter defined by docs as:
Formatter for printing and parsing date-time objects.
As I mentioned above, one of the key features of Date/Time Local* APIs was formatting. And this is how we are going to format our dates. Looking at the code above - everything should make sense apart from the .ofLocalizedDate() method. The easiest way to show what it does is with an example.
LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(anotherSummerDay));
will output the following in order:
Tuesday, August 23, 2016 August 23, 2016 Aug 23, 2016 8/23/16
Now sometimes you might want to have your own pattern which you can easily do with
System.out.println( LocalDate.now().format( DateTimeFormatter .ofPattern("dd-uuuu-MMM")));
Now I’ll quickly go over what these symbols mean:
dd => It's a representation of the day field, now you could also use d and the difference would be that d would not have a fixed character limit since it represents 1 digit from 0-9 and 2 from 10-31. if you're lost it basically means dd would show 01; however d would show 1. However, going into two digits it's the same
uuuu/yyyy => Is the field for years. And you could also do yy which would show only the last two digits of the year. ex. 24 rather than 2024
MMM => The last field as you might have guessed is for the month - MMM tells Java that we want a String representation rather than a number. If you want a number use MM
So by now, you should’ve guessed that the output would be:
10-2024-Jul
Now that you have a firm grip on Dates. I want to introduce you to Instants defined as:
An instantaneous point on the timeline.
Basically, this refers to Instants showing a specific moment.
By now you might have assumed that LocalDateTime has a timezone, but it doesn’t as the docs mentioned they are just a representation of date/time. However a ZoneId is in fact a representation of a time zone. Also, note that Instants don’t provide methods for altering our dates and times.
Instants capture the current moment in UTC with the Instant.now() . Now based on this, you realize that Local* really doesn’t have a meaning unless it's applied, that’s the reason why you would actually refrain from using it in a business-level application. So prefer using ZonedDateTime and Insant. As a general rule of thumb use Locale When it's a specific point on a timeline rather than a moment in time. A moment would be like the moment I publish this, or the moment you read this, or the moment the world explodes, however a point in a timeline would be like an appointment there’s no moment for an appointment. If you're going on a vacation it's a specific time on a timeline, not a moment.
Quite simple. It's just an Instant with a ZoneId and this is why we say Insant has a timezone. No matter what you do it's not going to represent a time but rather be a specific moment.
Aigh’t well that was quite the thing, wasn’t it? phew
have a nice one >#
Das obige ist der detaillierte Inhalt vonLasst uns Dates richtig machen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!