Java Ημερομηνία και ώρα

⚡ Έξυπνη Σύνοψη

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

  • 🕒 Ημερομηνία παλαιού τύπου: Η κλάση java.util.Date αποθηκεύει μια στιγμή σε χιλιοστά του δευτερολέπτου και εκτυπώνει μια προεπιλεγμένη συμβολοσειρά μέσω του toString.
  • 🔤 Γράμματα μοτίβων: Το SimpleDateFormat χρησιμοποιεί γράμματα όπως yyyy, MM, dd, HH, mm, ss και zzz για να ορίσει προσαρμοσμένες μορφές εξόδου.
  • Σύγκριση: Η μέθοδος compareTo επιστρέφει έναν αρνητικό, μηδενικό ή θετικό ακέραιο αριθμό για να ταξινομήσει δύο στιγμιότυπα Date χρονολογικά.
  • 🆕 Σύγχρονο API: Οι LocalDate, LocalDateTime, ZonedDateTime και Instant στο java.time αντικαθιστούν την ημερομηνία και το ημερολόγιο με αμετάβλητα αντικείμενα.
  • 🧵 Ασφάλεια νήματος: Το DateTimeFormatter είναι αμετάβλητο και ασφαλές για κοινή χρήση, ενώ το SimpleDateFormat χρειάζεται συγχρονισμό ή ένα περιτύλιγμα ThreadLocal.
  • 🔁 Διαλειτουργικότητα: Μετατρέψτε τα παλιά και τα νέα API χρησιμοποιώντας τους βοηθούς Date.toInstant, Date.from και Calendar.toInstant.

Java Ημερομηνία και ώρα

Χειρισμός ημερομηνιών και ωρών σε Java είναι ένα συνηθισμένο μέρος της δημιουργίας λογικής προγραμματισμού, χρονικών σημάνσεων καταγραφής, αναφορών και διαδρομών ελέγχου. Πριν από τη σύνταξη οποιουδήποτε κώδικα, είναι χρήσιμο να γνωρίζετε τις παραμέτρους που αποτελούν μια ημερομηνία:

  • The έτος (σε δύο ή τέσσερα ψηφία).
  • The μήνας (ως δύο ψηφία, ως τα τρία πρώτα γράμματα του μήνα ή ως το πλήρες όνομα του μήνα).
  • The Ραντεβού (ο πραγματικός αριθμός ημέρας του μήνα).
  • The ημέρα (το όνομα της ημέρας στη δεδομένη ημερομηνία, όπως Κυρ, Δευτ, Τρί).

Java αποκαλύπτει πολλές άλλες παραμέτρους που περιγράφουν μια στιγμή στη χρονογραμμή, όπως η εποχή, η εβδομάδα ανά έτος, η ζώνη ώρας και η μετατόπιση. Οι παρακάτω ενότητες καλύπτουν καθεμία από αυτές με παραδείγματα που μπορούν να εκτελεστούν.

Πώς να χρησιμοποιήσετε το Date in 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 που σας επιτρέπει να μορφοποιείτε και να αναλύετε ημερομηνίες χρησιμοποιώντας τα γράμματα του μοτίβου παραπάνω. Συνδυάστε τα γράμματα για να περιγράψετε την ακριβή συμβολοσειρά που θέλετε να δημιουργήσετε ή να διαβάσετε.

Για παράδειγμα:

  1. Απαιτούμενη μορφή ημερομηνίας: 2012.10.23 20:20:45 PSTΤο κατάλληλο μοτίβο μορφοποίησης είναι yyyy.MM.dd HH:mm:ss zzz.
  2. Απαιτούμενη μορφή ημερομηνίας: 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 δεν έχει ζώνη, οπότε μετατρέψτε σε ZonedDateTime or Instant όποτε η ακριβής στιγμή έχει σημασία, ειδικά για αρχεία καταγραφής, στήλες βάσης δεδομένων και ωφέλιμα φορτία δικτύου.
  • Μετατρέψτε προσεκτικά μεταξύ των δύο API. Χρήση date.toInstant(), Date.from(instant)και calendar.toInstant().atZone(zone) στα όρια μεταξύ παλαιού και σύγχρονου κώδικα.
  • Αποθήκευση χρονικών σημάνσεων σε UTC. Επιμένω και transmit ημερομηνίες ως UTC (ένα Instant ή μια συμβολοσειρά ISO 8601) και μετατρέπεται σε ζώνη χρήστη μόνο κατά την εμφάνιση.

Συχνές Ερωτήσεις

Καλέστε την LocalDateTime.now() από το πακέτο java.time για μια ημερομηνία και ώρα στη ζώνη συστήματος ή την LocalDate.now() μόνο για μια ημερομηνία. Σε παλαιότερες εκδόσεις Java, χρησιμοποιήστε τη new java.util.Date() για να λάβετε την τρέχουσα στιγμή.

Η java.util.Date αντιπροσωπεύει μια στιγμή σε χιλιοστά του δευτερολέπτου από την εποχή και είναι μεταβλητή. Η LocalDate μοντελοποιεί μια ημερομηνία ημερολογίου χωρίς ώρα ή ζώνη, είναι αμετάβλητη και ασφαλής για threads, και προσφέρει πιο σαφείς μεθόδους όπως plusDays και isBefore.

Όχι. Το SimpleDateFormat διατηρεί την κατάσταση μεταβλητής ανάλυσης και παράγει λανθασμένα αποτελέσματα όταν γίνεται κοινή χρήση σε διάφορα νήματα. Τυλίξτε το σε ένα ThreadLocal, συγχρονίστε το στην παρουσία ή μεταβείτε στο DateTimeFormatter, το οποίο είναι αμετάβλητο και ασφαλές.

Μεταβιβάστε την ακριβή συμβολοσειρά «yyyy-MM-dd». Με κεφαλαία γράμματα MM είναι ο μήνας, με πεζά γράμματα mm είναι τα λεπτά. Για πλήρη ημερομηνία και ώρα, χρησιμοποιήστε «yyyy-MM-dd HH:mm:ss». Να καθορίζετε πάντα μια τοπική ρύθμιση, ώστε τα ονόματα των μηνών να παραμένουν αναπαραγώγιμα.

Με την legacy Date, χρησιμοποιήστε την compareTo η οποία επιστρέφει έναν αρνητικό, μηδενικό ή θετικό ακέραιο. Με την java.time, καλέστε την isBefore, isAfter ή isEqual σε μια LocalDate ή Instant. Και οι δύο προσεγγίσεις σέβονται τη χρονολογική σειρά.

Καλέστε την συνάρτηση date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). Για να επιστρέψετε, χρησιμοποιήστε την συνάρτηση Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Επιλέξτε τη ζώνη ρητά όποτε η ακριβής στιγμή έχει σημασία.

Τα μοντέλα τεχνητής νοημοσύνης που έχουν εκπαιδευτεί σε σώματα αρχείων καταγραφής και εγγράφων συνάγουν το πιθανό μοτίβο από δείγματα συμβολοσειρών και επιστρέφουν ένα αντίστοιχο μοτίβο DateTimeFormatter. Οι ταξινομητές μηχανικής μάθησης επισημαίνουν επίσης ασαφή πεδία, όπως η σειρά μήνα-ημέρα έναντι της σειράς ημέρας-μήνα.

Ναι. Το GitHub Copilot προτείνει μοτίβα DateTimeFormatter, μετατροπές ZonedDateTime και JUnit δοκιμές για έξοδο ευαίσθητη στις τοπικές ρυθμίσεις. RevΔείτε κάθε πρόταση για τα σωστά γράμματα μοτίβου, την τοπική ρύθμιση και τη ζώνη ώρας πριν την υποβολή.

Συνοψίστε αυτήν την ανάρτηση με: