Java Data și ora

⚡ Rezumat inteligent

Java Gestionarea datei și orei combină clasele vechi java.util.Date și SimpleDateFormat cu API-ul modern java.time introdus în Java 8, oferind dezvoltatorilor tipuri imuabile, sigure pentru thread-uri, pentru o lucru precis cu calendarul.

  • 🕒 Data moștenirii: Clasa java.util.Date stochează un instant în milisecunde și afișează un șir implicit până la toString.
  • 🔤 Litere model: SimpleDateFormat folosește litere precum aaaa, MM, zz, HH, mm, ss și zzz pentru a defini formate de ieșire personalizate.
  • 🇧🇷 Comparaţie: Metoda compareTo returnează un număr întreg negativ, zero sau pozitiv pentru a ordona cronologic două instanțe de tip Date.
  • 🆕 API modern: LocalDate, LocalDateTime, ZonedDateTime și Instant din java.time înlocuiesc Date și Calendar cu obiecte imuabile.
  • 🧵 Siguranța firului: DateTimeFormatter este imuabil și sigur de partajat, în timp ce SimpleDateFormat necesită sincronizare sau un wrapper ThreadLocal.
  • 🔁 interoperabilitate: Conversia între API-urile vechi și noi se face folosind instrumentele auxiliare Date.toInstant, Date.from și Calendar.toInstant.

Java Data și ora

Gestionarea datelor și orelor în Java este o parte obișnuită a construirii logicii de programare, a înregistrării timestamp-urilor, a rapoartelor și a jurnalelor de audit. Înainte de a scrie orice cod, este util să cunoașteți parametrii care alcătuiesc o dată:

  • an (în două sau patru cifre).
  • lună (ca două cifre, ca primele trei litere ale lunii sau ca denumirea completă a lunii).
  • data (numărul real al zilei din lună).
  • zi (numele zilei la data dată, cum ar fi Dum, Lun, Mar).

Java expune mulți alți parametri care descriu un moment pe cronologie, inclusiv era, săptămâna din an, fusul orar și decalajul orar. Secțiunile de mai jos acoperă fiecare dintre ei cu exemple rulabile.

Cum se utilizează Data în Java

Afișează data în Java

Java oferă o Date clasa în java.util pachet. Clasa stochează un moment specific în timp cu precizie de milisecunde și oferă metode auxiliare pentru a afișa, compara și formata acel moment. Pentru a obține data și ora curente, instanțiați clasa cu constructorul său implicit:

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());
    }
}

ieșire:

Wed Nov 29 06:36:22 UTC 2017

Exemplul afișează data în formatul implicit toString. Pentru a afișa același moment într-un model diferit, trebuie mai întâi să înțelegeți formatarea literelor care Java utilizări.

SimpleDateFormat: Analizați și formatați datele

SimpleDateFormat clasa în java.text convertește a Date obiect într-un șir formatat și analizează un șir formatat înapoi într-un DateFolosește litere tipare care se asociază cu o componentă de dată sau oră. Tabelul de mai jos listează toate literele acceptate:

ScrisoareComponenta dată sau orăExemplu
GIndicator de epocăAD
yAn2026
MLună în aniulie sau iulie sau 07
wSăptămâna în an27
WSăptămână de lună2
DZi de an189
dZi de lună10
FZi a săptămânii în lună2
ENumele zilei în săptămânămarți sau marți
uNumărul zilei săptămânii (1 = Monday, 7 = duminică)1
amarcaj AM sau PMPM
HOra în zi (0-23)0
kOra în zi (1-24)24
KOră în AM sau PM (0-11)0
hOră în AM sau PM (1-12)12
mMinut în oră30
sAl doilea în minut55
SMilisecunda978
zFus orar (nume)Ora standard a Pacificului; PST; GMT-08:00
ZFus orar (decalaj RFC 822)-0800
XFus orar (decalaj ISO 8601)-08 sau -0800 sau -08:00

Nu trebuie să vă amintiți întregul tabel. Consultați-l ori de câte ori construiți un model nou.

Cum se utilizează SimpleDateFormat

SimpleDateFormat este o subclasă a DateFormat care vă permite să formatați și să analizați date folosind literele model de mai sus. Combinați literele pentru a descrie exact șirul pe care doriți să îl produceți sau să îl citiți.

De exemplu:

  1. Formatul datei este necesar: 2012.10.23 20:20:45 PSTModelul de format corespunzător este yyyy.MM.dd HH:mm:ss zzz.
  2. Formatul datei este necesar: 09:30:00 AM 23-May-2012Modelul de format corespunzător este hh:mm:ss a dd-MMM-yyyy.

Sfat: Literă de ceas majusculă. M este luna, cu litere mici m este minuscul. Majusculă H este un ceas de 24 de ore, cu litere mici h este un ceas de 12 ore. Amestecarea lor produce o ieșire eronată în tăcere.

Programul de mai jos afișează data curentă de două ori, o dată în formatul implicit și o dată printr-un model 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));
    }
}

ieșire:

Wed Nov 29 06:31:41 UTC 2017
06:31:41 AM 29-Nov-2017

Exemplu de comparare a datelor

Exemplu de comparare a datelor

Cea mai fiabilă modalitate de a comanda două Date obiectele sunt compareTo() Metodă. Returnează un număr întreg negativ când apelantul este mai devreme, zero când ambele momente sunt egale și un număr întreg pozitiv când apelantul este mai târziu. Fragmentul de mai jos analizează două șiruri de date și afișează ordinea lor relativă:

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");
        }
    }
}

ieșire:

Date1 : 20-08-1981
Date2 : 12-10-2012
Date 1 occurs before Date 2

Notă: Codul original a folosit modelul dd-mm-yyyy. Minuscule mm Litera este minut, nu lună, așa că parserul a produs în mod silențios valoarea greșită a lunii. Corecția de mai sus folosește majuscule MM pentru lună, care este litera modelului corect.

Java 8 API-uri moderne pentru dată și oră (java.time)

Java 8 a introdus java.time pachet, o API reproiectată, inspirată de biblioteca Joda-Time. Noile clase sunt imuabile, sigure pentru thread-uri și separă calendarul uman de cronologia mașinii. Cele mai comune tipuri sunt:

  • LocalDate pentru o dată fără oră sau fus orar (de exemplu, o zi de naștere).
  • LocalTime pentru o oră de ceas de perete fără dată sau fus orar.
  • LocalDateTime pentru o dată și o oră fără zonă.
  • ZonedDateTime pentru o dată și o oră cu un anumit fus orar.
  • OffsetDateTime pentru o dată și o oră cu un decalaj UTC, dar fără o zonă denumită.
  • Instant pentru o amprentă temporală a mașinii măsurată din epoca UNIX.
  • Duration și Period pentru sume bazate pe timp și pe dată.

Exemplul de mai jos afișează data, ora, marcajul temporal și fusul orar curente folosind API-ul modern:

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);
    }
}

Fiecare tip are metode din fabrică (now, of, parse) și operații imuabile (plusDays, minusHours, withYear) care returnează o valoare nouă în loc să modifice obiectul original.

DateTimeFormatter: Formatează datele în limbajul modern Java

DateTimeFormatter in java.time.format înlocuiește SimpleDateFormatFolosește același stil de litere de tipar, este imuabil și poate fi partajat în siguranță între fire de execuție fără sincronizare suplimentară. Clasa expune, de asemenea, constante predefinite, cum ar fi ISO_LOCAL_DATE și ISO_ZONED_DATE_TIME pentru formate standard.

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);
    }
}

Pentru a compara două date în API-ul modern, apelați isBefore, isAfter, isEqualAceste metode se citesc mai clar decât compareTo și să lucreze cu fiecare java.time clasă.

Siguranța firelor de execuție și cele mai bune practici pentru Java Data și ora

Ambele java.util.Date și SimpleDateFormat precede concurența modernă Java, și fiecare are capcane cunoscute. Urmați practicile de mai jos pentru a menține gestionarea corectă a datelor în codul de producție:

  • Preferă java.time în locul Date și Calendar. Noile tipuri sunt imuabile și sigure pentru thread-uri și modelează domeniul mai precis (date fără oră, ore fără zone și așa mai departe).
  • Nu partajați un SimpleDateFormat între fire de execuție. Clasa stochează starea de analiză internă și nu este sigură pentru fire de execuție. Încadrați-o într-un ThreadLocal, sincronizați pe instanță sau comutați la DateTimeFormatter.
  • Specificați întotdeauna o setare regională. Numele lunilor și zilelor se schimbă în funcție de setările regionale implicite ale JVM, ceea ce creează modele precum MMM și EEE neportabil. Transmiteți explicit o setare regională (de exemplu, Locale.ENGLISH).
  • Fii explicit în privința fusurilor orare. LocalDateTime nu are zonă, deci convertiți la ZonedDateTime or Instant ori de câte ori contează momentul exact, în special pentru jurnale, coloane ale bazei de date și sarcini utile ale rețelei.
  • Conversia între cele două API-uri este atentă. Utilizare date.toInstant(), Date.from(instant) și calendar.toInstant().atZone(zone) la granița dintre codul moștenit și codul modern.
  • Stochează marcajele temporale în UTC. Persistă și transmit date ca UTC (un Instant sau un șir ISO 8601) și se convertesc în zona utilizatorului doar la afișare.

Întrebări frecvente

Apelați LocalDateTime.now() din pachetul java.time pentru o dată și o oră în zona sistemului sau LocalDate.now() doar pentru o dată. Pe versiunile mai vechi Java, folosește new java.util.Date() pentru a obține momentul curent.

java.util.Date reprezintă un moment în milisecunde de la epocă și este modificabil. LocalDate modelează o dată calendaristică fără oră sau o zonă, este imuabilă și sigură pentru thread-uri și oferă metode mai clare, cum ar fi plusDays și isBefore.

Nu. SimpleDateFormat menține starea de analiză mutabilă și produce rezultate greșite atunci când este partajat între fire de execuție. Încadrați-l într-un ThreadLocal, sincronizați-l pe instanță sau treceți la DateTimeFormatter, care este imuabil și sigur.

Transmiteți șirul exact „aaaa-LL-zz”. MM (majusculă) reprezintă luna, mm (minuscul) reprezintă minutul. Pentru o dată și o oră complete, utilizați „aaaa-LL-zz HH:mm:ss”. Specificați întotdeauna o setare regională pentru ca numele lunilor să rămână reproductibile.

Cu o valoare Date moștenită, se folosește compareTo, care returnează un număr întreg negativ, zero sau pozitiv. Cu java.time, se apelează isBefore, isAfter sau isEqual într-o valoare LocalDate sau Instant. Ambele abordări respectă ordinea cronologică.

Apelați date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). Pentru a reveni, utilizați Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Selectați zona explicit ori de câte ori momentul exact contează.

Modelele de inteligență artificială antrenate pe corpusuri de jurnale și documente deduc modelul probabil din șiruri de eșantionare și returnează un model DateTimeFormatter corespunzător. Clasificatoarele de învățare automată semnalează, de asemenea, câmpuri ambigue, cum ar fi ordinea lună-zi versus zi-lună.

Da. GitHub Copilot sugerează modele DateTimeFormatter, conversii ZonedDateTime și JUnit teste pentru ieșiri sensibile la setările regionale. RevVizualizați fiecare sugestie pentru literele de model corecte, setările regionale și fusul orar înainte de a vă confirma.

Rezumați această postare cu: