Java Dato og tid

⚡ Smart opsummering

Java Dato- og tidshåndtering kombinerer de ældre java.util.Date- og SimpleDateFormat-klasser med den moderne java.time API, der blev introduceret i Java 8, hvilket giver udviklere uforanderlige, trådsikre typer til præcist kalenderarbejde.

  • 🕒 Arvsdato: java.util.Date-klassen gemmer et øjeblik i millisekunder og udskriver en standardstreng frem til toString.
  • 🔤 Mønsterbogstaver: SimpleDateFormat bruger bogstaver som åååå, MM, dd, HH, mm, ss og zzz til at definere brugerdefinerede outputformater.
  • ⚖️ Sammenligning: Metoden compareTo returnerer et negativt, nul eller positivt heltal for at sortere to Date-instanser kronologisk.
  • 🆕 Moderne API: LocalDate, LocalDateTime, ZonedDateTime og Instant i java.time erstatter Date og Calendar med uforanderlige objekter.
  • 🧵 Trådsikkerhed: DateTimeFormatter er uforanderlig og sikker at dele, mens SimpleDateFormat kræver synkronisering eller en ThreadLocal-wrapper.
  • 🔁 interoperabilitet: Konverter mellem de gamle og nye API'er ved hjælp af hjælperne Date.toInstant, Date.from og Calendar.toInstant.

Java Dato og tid

Håndtering af datoer og klokkeslæt i Java er en rutinemæssig del af opbygningen af ​​planlægningslogik, logtidsstempler, rapporter og revisionsspor. Før man skriver kode, er det nyttigt at kende de parametre, der udgør en dato:

  • år (med to eller fire cifre).
  • måned (som to cifre, som de første tre bogstaver i måneden eller som hele månedens navn).
  • dato (det faktiske nummer på månedens dag).
  • dag (dagens navn på den givne dato, f.eks. søn, man, tir).

Java afslører mange andre parametre, der beskriver et øjeblik på tidslinjen, herunder æra, uge ​​i året, tidszone og forskydning. Afsnittene nedenfor dækker hver af dem med eksempler, der kan køres.

Sådan bruger du Dato i Java

Vis dato i Java

Java tilvejebringer en Date klasse i java.util pakke. Klassen gemmer et specifikt tidspunkt med en præcision på millisekunder og tilbyder hjælpemetoder til at udskrive, sammenligne og formatere det pågældende tidspunkt. For at få den aktuelle dato og det aktuelle klokkeslæt skal du instansiere klassen med dens standardkonstruktør:

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

Output:

Wed Nov 29 06:36:22 UTC 2017

Eksemplet udskriver datoen i standard toString-formatet. For at vise det samme øjeblik i et andet mønster, skal du først forstå formateringsbogstaverne, der Java anvendelser.

SimpleDateFormat: Parse og formater datoer

SimpleDateFormat klasse i java.text konverterer en Date objektet ind i en formateret streng og analyserer en formateret streng tilbage til en DateDen bruger mønsterbogstaver, der knyttes til en dato- eller tidskomponent. Tabellen nedenfor viser alle understøttede bogstaver:

BrevDato- eller tidskomponentEksempel
GEpoke betegnerAD
yÅr2026
MMåned i årjuli eller juli eller 07
wUge i år27
WUge i måned2
DDag i år189
dDag i måned10
FUgedag i måned2
EDagens navn i ugentirsdag eller tirsdag
uDagnummer i ugen (1 = Monday, 7 = søndag)1
aAM- eller PM-markørPM
HTime om dagen (0-23)0
kTime om dagen (1-24)24
KTime i AM eller PM (0-11)0
hTime i AM eller PM (1-12)12
mMinut i time30
sAnden på minut55
Smillisekund978
zTidszone (navn)Pacific Standard Time; PST; GMT-08:00
ZTidszone (RFC 822-forskydning)-0800
XTidszone (ISO 8601-forskydning)-08 eller -0800 eller -08:00

Du behøver ikke at huske hele tabellen. Brug den, når du bygger et nyt mønster.

Sådan bruger du SimpleDateFormat

SimpleDateFormat er en underklasse af DateFormat der lader dig formatere og analysere datoer ved hjælp af ovenstående mønsterbogstaver. Kombiner bogstaverne for at beskrive præcis den streng, du vil producere eller læse.

For eksempel:

  1. Påkrævet datoformat: 2012.10.23 20:20:45 PSTDet passende formatmønster er yyyy.MM.dd HH:mm:ss zzz.
  2. Påkrævet datoformat: 09:30:00 AM 23-May-2012Det passende formatmønster er hh:mm:ss a dd-MMM-yyyy.

Tip: Bogstaver i urkassen. Store bogstaver. M er måned, med lille bogstav m er et minut. Store bogstaver H er et 24-timers ur, med små bogstaver h er et 12-timers ur. At blande dem sammen giver lydløst forkert output.

Programmet nedenfor udskriver den aktuelle dato to gange, én gang i standardformat og én gang via et SimpleDateFormat-mønster:

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

Output:

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

Sammenlign Datoer Eksempel

Sammenlign Datoer Eksempel

Den mest pålidelige måde at bestille to på Date objekterne er compareTo() Metoden. Den returnerer et negativt heltal, når kalderen er tidligere, nul, når begge tidspunkter er ens, og et positivt heltal, når kalderen er senere. Kodestykket nedenfor analyserer to dato-strenge og udskriver deres relative rækkefølge:

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

Output:

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

Bemærk: Den oprindelige kode brugte mønsteret dd-mm-yyyy. Små bogstaver mm Bogstavet er minut, ikke måned, så parseren producerede lydløst den forkerte månedsværdi. Ovenstående rettelse bruger store bogstaver MM for måned, hvilket er det korrekte mønsterbogstav.

Java 8 Moderne dato og klokkeslæt API (java.time)

Java 8 introducerede java.time pakke, en redesignet API inspireret af Joda-Time-biblioteket. De nye klasser er uforanderlige, trådsikre og adskiller den menneskelige kalender fra maskinens tidslinje. De mest almindelige typer er:

  • LocalDate for en dato uden et tidspunkt eller en zone (f.eks. en fødselsdag).
  • LocalTime for et vægur uden dato eller zone.
  • LocalDateTime for en dato og et klokkeslæt uden en zone.
  • ZonedDateTime for en dato og et klokkeslæt med en bestemt tidszone.
  • OffsetDateTime for en dato og et klokkeslæt med en UTC-forskydning, men ingen navngiven zone.
  • Instant for et maskintidsstempel målt fra UNIX-epoken.
  • Duration og Period for tidsbaserede og datobaserede beløb.

Eksemplet nedenfor udskriver den aktuelle dato, klokkeslæt, tidsstempel og tidszone ved hjælp af den moderne 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);
    }
}

Hver type har fabriksmetoder (now, of, parse) og uforanderlige operationer (plusDays, minusHours, withYear) der returnerer en ny værdi i stedet for at mutere det oprindelige objekt.

DateTimeFormatter: Formatér datoer i Modern Java

DateTimeFormatter in java.time.format erstatter SimpleDateFormatDen bruger den samme stil af mønsterbogstaver, er uforanderlig og er sikker at dele på tværs af tråde uden ekstra synkronisering. Klassen eksponerer også færdige konstanter såsom ISO_LOCAL_DATE og ISO_ZONED_DATE_TIME for standardformater.

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

For at sammenligne to datoer i den moderne API, kald isBefore, isAfter eller isEqualDisse metoder er tydeligere end compareTo og arbejde med alle java.time klasse.

Trådsikkerhed og bedste praksis for Java Dato og tid

Både java.util.Date og SimpleDateFormat forud for moderne samtidighed Java, og hver af dem har kendte faldgruber. Følg nedenstående fremgangsmåder for at holde datohåndteringen korrekt i produktionskoden:

  • Foretræk java.time frem for dato og kalender. De nye typer er uforanderlige og trådsikre, og de modellerer domænet mere præcist (datoer uden tidspunkter, tidspunkter uden zoner osv.).
  • Del ikke et SimpleDateFormat på tværs af tråde. Klassen gemmer intern parse-tilstand og er ikke trådsikker. Pak den ind i en ThreadLocal, synkroniser på instansen, eller skift til DateTimeFormatter.
  • Angiv altid en lokalitet. Måned- og dagnavne ændres med JVM-standardlokaliteten, hvilket skaber mønstre som MMM og EEE ikke-portabel. Angiv en lokalitet eksplicit (f.eks. Locale.ENGLISH).
  • Vær tydelig omkring tidszoner. LocalDateTime har ingen zone, så konverter til ZonedDateTime or Instant når det præcise tidspunkt er vigtigt, især for logfiler, databasekolonner og netværksnyttelast.
  • Konverter omhyggeligt mellem de to API'er. Brug date.toInstant(), Date.from(instant)og calendar.toInstant().atZone(zone) på grænsen mellem ældre kode og moderne kode.
  • Gem tidsstempler i UTC. Vedhold og transmit datoer som UTC (en Instant eller en ISO 8601-streng) og konverter kun til brugerzonen ved visning.

Ofte Stillede Spørgsmål

Kald LocalDateTime.now() fra java.time-pakken for en dato og et klokkeslæt i systemzonen, eller LocalDate.now() kun for en dato. På ældre Java, brug new java.util.Date() til at hente det aktuelle øjeblik.

java.util.Date repræsenterer et øjeblik i millisekunder siden epoken og er foranderlig. LocalDate modellerer en kalenderdato uden et tidspunkt eller en zone, er uforanderlig og trådsikker og tilbyder klarere metoder såsom plusDays og isBefore.

Nej. SimpleDateFormat beholder en foranderlig parse-tilstand og producerer forkerte resultater, når den deles på tværs af tråde. Pak den ind i en ThreadLocal, synkroniser på instansen, eller skift til DateTimeFormatter, som er uforanderlig og sikker.

Brug den nøjagtige streng "yyyy-MM-dd". Stor MM er måned, lille mm er minut. For en fuld dato og klokkeslæt skal du bruge "yyyy-MM-dd HH:mm:ss". Angiv altid en lokalitet, så månedsnavne forbliver reproducerbare.

Med den traditionelle Date-metode skal du bruge compareTo, som returnerer et negativt, nul eller positivt heltal. Med java.time skal du kalde isBefore, isAfter eller isEqual på en LocalDate eller Instant. Begge tilgange respekterer kronologisk rækkefølge.

Kald date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). For at gå tilbage, brug Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Vælg zonen eksplicit, når det præcise tidspunkt er vigtigt.

AI-modeller trænet på log- og dokumentkorpora udleder det sandsynlige mønster fra eksempelstrenge og returnerer et matchende DateTimeFormatter-mønster. Maskinlæringsklassifikatorer markerer også tvetydige felter såsom måned-dag versus dag-måned rækkefølge.

Ja. GitHub Copilot foreslår DateTimeFormatter-mønstre, ZonedDateTime-konverteringer og JUnit test for lokalitetsfølsomt output. RevSe hvert forslag for de korrekte mønsterbogstaver, lokalitet og tidszone, før du forpligter dig.

Opsummer dette indlæg med: