Java Ημερομηνία και ώρα
⚡ Έξυπνη Σύνοψη
Java Η διαχείριση ημερομηνίας και ώρας συνδυάζει τις παλαιότερες κλάσεις java.util.Date και SimpleDateFormat με το σύγχρονο API java.time που εισήχθη στο Java 8, παρέχοντας στους προγραμματιστές αμετάβλητους, ασφαλείς για νήματα τύπους για ακριβή εργασία ημερολογίου.

Χειρισμός ημερομηνιών και ωρών σε Java είναι ένα συνηθισμένο μέρος της δημιουργίας λογικής προγραμματισμού, χρονικών σημάνσεων καταγραφής, αναφορών και διαδρομών ελέγχου. Πριν από τη σύνταξη οποιουδήποτε κώδικα, είναι χρήσιμο να γνωρίζετε τις παραμέτρους που αποτελούν μια ημερομηνία:
- The έτος (σε δύο ή τέσσερα ψηφία).
- The μήνας (ως δύο ψηφία, ως τα τρία πρώτα γράμματα του μήνα ή ως το πλήρες όνομα του μήνα).
- The Ραντεβού (ο πραγματικός αριθμός ημέρας του μήνα).
- The ημέρα (το όνομα της ημέρας στη δεδομένη ημερομηνία, όπως Κυρ, Δευτ, Τρί).
Java αποκαλύπτει πολλές άλλες παραμέτρους που περιγράφουν μια στιγμή στη χρονογραμμή, όπως η εποχή, η εβδομάδα ανά έτος, η ζώνη ώρας και η μετατόπιση. Οι παρακάτω ενότητες καλύπτουν καθεμία από αυτές με παραδείγματα που μπορούν να εκτελεστούν.
Εμφάνιση ημερομηνίας σε Java
Java παρέχει ένα Date τάξη στο java.util πακέτο. Η κλάση αποθηκεύει μια συγκεκριμένη χρονική στιγμή με ακρίβεια χιλιοστών του δευτερολέπτου και προσφέρει βοηθητικές μεθόδους για την εκτύπωση, τη σύγκριση και τη μορφοποίηση αυτής της στιγμής. Για να λάβετε την τρέχουσα ημερομηνία και ώρα, δημιουργήστε την κλάση με τον προεπιλεγμένο κατασκευαστή της:
import java.util.Date; class Date_Ex1 { public static void main(String args[]) { // Instantiate a Date object by invoking its constructor Date objDate = new Date(); // Display the Date and Time using toString() System.out.println(objDate.toString()); } }
Παραγωγή:
Wed Nov 29 06:36:22 UTC 2017
Το παράδειγμα εκτυπώνει την ημερομηνία στην προεπιλεγμένη μορφή toString. Για να εμφανίσετε την ίδια στιγμή με διαφορετικό μοτίβο, πρέπει πρώτα να κατανοήσετε τα γράμματα μορφοποίησης που Java χρήσεις.
SimpleDateFormat: Ανάλυση και Μορφοποίηση Ημερομηνιών
The SimpleDateFormat τάξη μέσα java.text μετατρέπει ένα Date αντικείμενο σε μια μορφοποιημένη συμβολοσειρά και αναλύει μια μορφοποιημένη συμβολοσειρά ξανά σε ένα DateΧρησιμοποιεί γράμματα μοτίβου που αντιστοιχούν σε ένα στοιχείο ημερομηνίας ή ώρας. Ο παρακάτω πίνακας παραθέτει κάθε υποστηριζόμενο γράμμα:
| Επιστολή | Στοιχείο ημερομηνίας ή ώρας | Παράδειγμα |
|---|---|---|
| G | Προσδιορισμός εποχής | AD |
| y | Έτος | 2026 |
| M | Μήνας σε χρόνο | Ιουλίου ή Ιουλίου ή 07 |
| w | Εβδομάδα με το χρόνο | 27 |
| W | Εβδομάδα σε μήνα | 2 |
| D | Ημέρα το χρόνο | 189 |
| d | Ημέρα σε μήνα | 10 |
| F | Ημέρα της εβδομάδας στον μήνα | 2 |
| E | Όνομα ημέρας στην εβδομάδα | Τρίτη ή Τρίτη |
| u | Αριθμός ημέρας της εβδομάδας (1 = Monday, 7 = Κυριακή) | 1 |
| a | Δείκτης π.μ. ή μ.μ. | PM |
| H | Ώρα την ημέρα (0-23) | 0 |
| k | Ώρα την ημέρα (1-24) | 24 |
| K | Ώρα σε π.μ. ή μ.μ. (0-11) | 0 |
| h | Ώρα σε π.μ. ή μ.μ. (1-12) | 12 |
| m | Λεπτό σε ώρα | 30 |
| s | Δεύτερος στο λεπτό | 55 |
| S | Μιλιδευτερόλεπτο | 978 |
| z | Ζώνη ώρας (όνομα) | Τυπική ώρα Ειρηνικού; PST; GMT-08:00 |
| Z | Ζώνη ώρας (μετατόπιση RFC 822) | -0800 |
| X | Ζώνη ώρας (μετατόπιση ISO 8601) | -08 ή -0800 ή -08:00 |
Δεν χρειάζεται να θυμάστε ολόκληρο τον πίνακα. Ανατρέξτε σε αυτόν κάθε φορά που δημιουργείτε ένα νέο μοτίβο.
Πώς να χρησιμοποιήσετε το SimpleDateFormat
SimpleDateFormat είναι μια υποκλάση του DateFormat που σας επιτρέπει να μορφοποιείτε και να αναλύετε ημερομηνίες χρησιμοποιώντας τα γράμματα του μοτίβου παραπάνω. Συνδυάστε τα γράμματα για να περιγράψετε την ακριβή συμβολοσειρά που θέλετε να δημιουργήσετε ή να διαβάσετε.
Για παράδειγμα:
- Απαιτούμενη μορφή ημερομηνίας: 2012.10.23 20:20:45 PSTΤο κατάλληλο μοτίβο μορφοποίησης είναι
yyyy.MM.dd HH:mm:ss zzz. - Απαιτούμενη μορφή ημερομηνίας: 09:30:00 AM 23-May-2012Το κατάλληλο μοτίβο μορφοποίησης είναι
hh:mm:ss a dd-MMM-yyyy.
Συμβουλή: Θήκη ρολογιού με γράμμα. Κεφαλαία γράμματα. M είναι μήνας, πεζά γράμματα m είναι λεπτό. Κεφαλαία γράμματα H είναι ένα 24ωρο ρολόι, με πεζά γράμματα h είναι ένα ρολόι 12 ωρών. Η ανάμειξή τους παράγει σιωπηλά λανθασμένη έξοδο.
Το παρακάτω πρόγραμμα εκτυπώνει την τρέχουσα ημερομηνία δύο φορές, μία φορά στην προεπιλεγμένη μορφή και μία φορά μέσω ενός μοτίβου SimpleDateFormat:
import java.text.SimpleDateFormat; import java.util.Date; class TestDates_Format { public static void main(String args[]) { // Current system date and time is assigned to objDate Date objDate = new Date(); System.out.println(objDate); // Build the target pattern and format the date String strDateFormat = "hh:mm:ss a dd-MMM-yyyy"; SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat); System.out.println(objSDF.format(objDate)); } }
Παραγωγή:
Wed Nov 29 06:31:41 UTC 2017 06:31:41 AM 29-Nov-2017
Παράδειγμα σύγκρισης ημερομηνιών
Ο πιο αξιόπιστος τρόπος για να παραγγείλετε δύο Date αντικείμενα είναι το compareTo() μέθοδος. Επιστρέφει έναν αρνητικό ακέραιο αριθμό όταν ο καλών είναι νωρίτερα, μηδέν όταν και οι δύο χρονικές στιγμές είναι ίσες και έναν θετικό ακέραιο αριθμό όταν ο καλών είναι αργότερα. Το παρακάτω τμήμα κώδικα αναλύει δύο συμβολοσειρές ημερομηνίας και εκτυπώνει τη σχετική τους σειρά:
import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Date; class TestDates_Compare { public static void main(String args[]) throws ParseException { SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy"); Date dt_1 = objSDF.parse("20-08-1981"); Date dt_2 = objSDF.parse("12-10-2012"); System.out.println("Date1 : " + objSDF.format(dt_1)); System.out.println("Date2 : " + objSDF.format(dt_2)); // compareTo returns > 0 when dt_1 is after dt_2 if (dt_1.compareTo(dt_2) > 0) { System.out.println("Date 1 occurs after Date 2"); } // compareTo returns < 0 when dt_1 is before dt_2 else if (dt_1.compareTo(dt_2) < 0) { System.out.println("Date 1 occurs before Date 2"); } // compareTo returns 0 when both dates are equal else { System.out.println("Both are the same date"); } } }
Παραγωγή:
Date1 : 20-08-1981 Date2 : 12-10-2012 Date 1 occurs before Date 2
Σημείωση: Ο αρχικός κώδικας χρησιμοποιούσε το μοτίβο dd-mm-yyyy. Το πεζά mm Το γράμμα είναι λεπτό, όχι μήνας, επομένως ο αναλυτής παρήγαγε σιωπηλά λάθος τιμή μήνα. Η παραπάνω διόρθωση χρησιμοποιεί κεφαλαία γράμματα MM για τον μήνα, το οποίο είναι το σωστό γράμμα μοτίβου.
Java 8 Σύγχρονο API Ημερομηνίας και Ώρας (java.time)
Java 8 εισήγαγε το java.time πακέτο, ένα επανασχεδιασμένο API εμπνευσμένο από τη βιβλιοθήκη Joda-Time. Οι νέες κλάσεις είναι αμετάβλητες, ασφαλείς για threads και διαχωρίζουν το ανθρώπινο ημερολόγιο από τη χρονογραμμή του μηχανήματος. Οι πιο συνηθισμένοι τύποι είναι:
LocalDateγια μια ημερομηνία χωρίς ώρα ή ζώνη (για παράδειγμα, γενέθλια).LocalTimeγια μια ώρα ρολογιού τοίχου χωρίς ημερομηνία ή ζώνη.LocalDateTimeγια ημερομηνία και ώρα χωρίς ζώνη.ZonedDateTimeγια μια ημερομηνία και ώρα με μια συγκεκριμένη ζώνη ώρας.OffsetDateTimeγια μια ημερομηνία και ώρα με μετατόπιση UTC αλλά χωρίς ονομαστική ζώνη.Instantγια μια χρονική σήμανση μηχανής που μετριέται από την εποχή του UNIX.DurationκαιPeriodγια ποσά που βασίζονται σε χρόνο και ημερομηνία.
Το παρακάτω παράδειγμα εκτυπώνει την τρέχουσα ημερομηνία, ώρα, χρονική σήμανση και ζώνη ώρας χρησιμοποιώντας το σύγχρονο API:
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.Instant; import java.time.ZoneId; class ModernDateDemo { public static void main(String args[]) { LocalDate today = LocalDate.now(); LocalDateTime now = LocalDateTime.now(); ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")); Instant epoch = Instant.now(); System.out.println("LocalDate : " + today); System.out.println("LocalDateTime : " + now); System.out.println("ZonedDateTime : " + zoned); System.out.println("Instant : " + epoch); } }
Κάθε τύπος έχει εργοστασιακές μεθόδους (now, of, parse) και αμετάβλητες λειτουργίες (plusDays, minusHours, withYear) που επιστρέφουν μια νέα τιμή αντί να μεταλλάσσουν το αρχικό αντικείμενο.
DateTimeFormatter: Μορφοποίηση ημερομηνιών σε Σύγχρονη γραφή Java
DateTimeFormatter in java.time.format αντικαθιστά SimpleDateFormatΧρησιμοποιεί το ίδιο στυλ γραμμάτων μοτίβου, είναι αμετάβλητο και είναι ασφαλές για κοινή χρήση σε νήματα χωρίς επιπλέον συγχρονισμό. Η κλάση εκθέτει επίσης έτοιμες σταθερές όπως ISO_LOCAL_DATE και ISO_ZONED_DATE_TIME για τυπικές μορφές.
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; class FormatterDemo { public static void main(String args[]) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME; DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy"); System.out.println(now.format(iso)); System.out.println(now.format(human)); LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso); System.out.println("Parsed back : " + parsed); } }
Για να συγκρίνετε δύο ημερομηνίες στο σύγχρονο API, καλέστε isBefore, isAfterΤο HIFU, ή Υψηλής Έντασης Εστιασμένος Υπέρηχος, στοχεύει επίσης στο πρόσωπο και τον λαιμό. Προσφέρει θεραπεία σε γρήγορες εκπομπές, γεγονός που κάνει τις συνεδρίες θεραπείας συντομότερες. isEqualΑυτές οι μέθοδοι διαβάζονται πιο καθαρά από compareTo και να συνεργάζεστε με κάθε java.time τάξη.
Thread Safety and καλυτερα Practices for Java Ημερομηνία και ώρα
Και τα δύο java.util.Date και SimpleDateFormat προηγούνται του σύγχρονου σύγχρονου Java, και το καθένα έχει γνωστές παγίδες. Ακολουθήστε τις παρακάτω πρακτικές για να διατηρήσετε τη σωστή διαχείριση ημερομηνιών στον κώδικα παραγωγής:
- Προτιμήστε το java.time αντί για το Date and Calendar. Οι νέοι τύποι είναι αμετάβλητοι και ασφαλείς για νήματα, και μοντελοποιούν τον τομέα με μεγαλύτερη ακρίβεια (ημερομηνίες χωρίς ώρες, ώρες χωρίς ζώνες, και ούτω καθεξής).
- Μην κάνετε κοινή χρήση ενός SimpleDateFormat σε διάφορα νήματα. Η κλάση αποθηκεύει εσωτερική κατάσταση ανάλυσης και δεν είναι ασφαλής για νήματα. Τυλίξτε την σε ένα
ThreadLocal, συγχρονισμός στην παρουσία ή εναλλαγή σεDateTimeFormatter. - Να καθορίζετε πάντα μια Τοπική ρύθμιση. Τα ονόματα των μηνών και των ημερών αλλάζουν με τις προεπιλεγμένες τοπικές ρυθμίσεις της JVM, γεγονός που δημιουργεί μοτίβα όπως
MMMκαιEEEμη φορητό. Μεταβιβάστε ρητά μια τοπική ρύθμιση (για παράδειγμα,Locale.ENGLISH). - Να είστε σαφείς σχετικά με τις ζώνες ώρας.
LocalDateTimeδεν έχει ζώνη, οπότε μετατρέψτε σεZonedDateTimeorInstantόποτε η ακριβής στιγμή έχει σημασία, ειδικά για αρχεία καταγραφής, στήλες βάσης δεδομένων και ωφέλιμα φορτία δικτύου. - Μετατρέψτε προσεκτικά μεταξύ των δύο API. Χρήση
date.toInstant(),Date.from(instant)καιcalendar.toInstant().atZone(zone)στα όρια μεταξύ παλαιού και σύγχρονου κώδικα. - Αποθήκευση χρονικών σημάνσεων σε UTC. Επιμένω και transmit ημερομηνίες ως UTC (ένα
Instantή μια συμβολοσειρά ISO 8601) και μετατρέπεται σε ζώνη χρήστη μόνο κατά την εμφάνιση.


