Java Datum och tid

⚡ Smart sammanfattning

Java Datum- och tidshantering kombinerar de äldre klasserna java.util.Date och SimpleDateFormat med det moderna java.time API som introducerades i Java 8, vilket ger utvecklare oföränderliga, trådsäkra typer för korrekt kalenderarbete.

  • 🕒 Äldre datum: Klassen java.util.Date lagrar ett ögonblick i millisekunder och skriver ut en standardsträng till och med toString.
  • 🔤 Mönsterbokstäver: SimpleDateFormat använder bokstäver som yyyy, MM, dd, HH, mm, ss och zzz för att definiera anpassade utdataformat.
  • ⚖️ Jämförelse: Metoden compareTo returnerar ett negativt, noll eller positivt heltal för att ordna två Date-instanser kronologiskt.
  • 🆕 Modernt API: LocalDate, LocalDateTime, ZonedDateTime och Instant i java.time ersätter Date och Calendar med oföränderliga objekt.
  • 🧵 Trådsäkerhet: DateTimeFormatter är oföränderlig och säker att dela, medan SimpleDateFormat behöver synkronisering eller en ThreadLocal-omslag.
  • 🔁 interoperabilitet: Konvertera mellan de gamla och nya API:erna med hjälp av Date.toInstant-, Date.from- och Calendar.toInstant-hjälpverktygen.

Java Datum och tid

Hantera datum och tider i Java är en rutinmässig del av att bygga schemaläggningslogik, logga tidsstämplar, rapporter och revisionsloggar. Innan du skriver någon kod är det bra att känna till de parametrar som utgör ett datum:

  • Ocuco-landskapet år (med två eller fyra siffror).
  • Ocuco-landskapet månad (som två siffror, som de tre första bokstäverna i månaden eller som hela månadens namn).
  • Ocuco-landskapet datum (det faktiska numret för månadens dag).
  • Ocuco-landskapet dag (dagens namn vid det angivna datumet, till exempel sön, mån, tis).

Java exponerar många andra parametrar som beskriver ett ögonblick på tidslinjen, inklusive era, vecka/år, tidszon och offset. Avsnitten nedan täcker var och en av dem med körbara exempel.

Hur man använder Date in Java

Visa datum in Java

Java tillhandahåller en Date klass i java.util paket. Klassen lagrar ett specifikt tidpunkt med millisekunds precision och erbjuder hjälpmetoder för att skriva ut, jämföra och formatera det tidpunkten. För att hämta aktuellt datum och tid, instansiera klassen med dess standardkonstruktor:

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

Produktion:

Wed Nov 29 06:36:22 UTC 2017

Exemplet skriver ut datumet i standardformatet toString. För att visa samma tidpunkt i ett annat mönster måste du först förstå formateringsbokstäverna som Java använder.

SimpleDateFormat: Analysera och formatera datum

Ocuco-landskapet SimpleDateFormat klass i java.text konverterar en Date objekt till en formaterad sträng och tolkar en formaterad sträng tillbaka till en DateDen använder mönsterbokstäver som mappas till en datum- eller tidskomponent. Tabellen nedan listar alla bokstäver som stöds:

BrevDatum eller TidskomponentExempelvis
GEra betecknareAD
yÅr2026
MMånad i årjuli eller juli eller 07
wVecka i år27
WVecka i månad2
DDag i år189
dDag i månad10
FVeckodag i månad2
EDagens namn i veckantisdag eller tis
uDagnummer i veckan (1 = Monday, 7 = söndag)1
aAM- eller PM-markörPM
HTimme på dygnet (0-23)0
kTimme på dygnet (1-24)24
KTimme i AM eller PM (0-11)0
hTimme i AM eller PM (1-12)12
mMinut i timme30
sTvåa på minuten55
Smillisekund978
zTidszon (namn)Pacific Standard Time; PST; GMT-08:00
ZTidszon (RFC 822-förskjutning)-0800
XTidszon (ISO 8601-förskjutning)-08 eller -0800 eller -08:00

Du behöver inte komma ihåg hela tabellen. Använd den varje gång du skapar ett nytt mönster.

Hur man använder SimpleDateFormat

SimpleDateFormat är en underklass av DateFormat som låter dig formatera och analysera datum med hjälp av bokstäverna ovan. Kombinera bokstäverna för att beskriva exakt den sträng du vill producera eller läsa.

Till exempel:

  1. Datumformat krävs: 2012.10.23 20:20:45 PSTDet lämpliga formatmönstret är yyyy.MM.dd HH:mm:ss zzz.
  2. Datumformat krävs: 09:30:00 AM 23-May-2012Det lämpliga formatmönstret är hh:mm:ss a dd-MMM-yyyy.

Dricks: Bokstav i klockan. Versaler M är månad, gemener m är minut. Stor bokstav H är en 24-timmarsklocka, gemener h är en 12-timmarsklocka. Att blanda ihop dem producerar tyst felaktig utdata.

Programmet nedan skriver ut aktuellt datum två gånger, en gång i standardformat och en gång genom ett 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));
    }
}

Produktion:

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

Jämför datum exempel

Jämför datum exempel

Det mest pålitliga sättet att beställa två Date föremålen är compareTo() Metoden. Den returnerar ett negativt heltal när anroparen är tidigare, noll när båda tidpunkterna är lika och ett positivt heltal när anroparen är senare. Kodfragmentet nedan analyserar två datumsträngar och skriver ut deras relativa ordning:

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

Produktion:

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

Obs: Den ursprungliga koden använde mönstret dd-mm-yyyy. Små bokstäver mm bokstaven är minut, inte månad, så parsern producerade tyst fel månadsvärde. Åtgärden ovan använder versaler MM för månad, vilket är den korrekta mönsterbokstaven.

Java 8 Modernt datum och tid API (java.time)

Java 8 introducerade java.time paket, ett omdesignat API inspirerat av Joda-Time-biblioteket. De nya klasserna är oföränderliga, trådsäkra och separerar den mänskliga kalendern från maskinens tidslinje. De vanligaste typerna är:

  • LocalDate för ett datum utan tid eller zon (till exempel en födelsedag).
  • LocalTime för en väggklocka utan datum eller zon.
  • LocalDateTime för ett datum och en tid utan zon.
  • ZonedDateTime för ett datum och en tid med en specifik tidszon.
  • OffsetDateTime för ett datum och en tid med en UTC-förskjutning men ingen namngiven zon.
  • Instant för en maskintidsstämpel mätt från UNIX-epoken.
  • Duration och Period för tidsbaserade och datumbaserade belopp.

Exemplet nedan skriver ut aktuellt datum, tid, tidsstämpel och tidszon med hjälp av det moderna API:et:

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

Varje typ har fabriksmetoder (now, of, parse) och oföränderliga operationer (plusDays, minusHours, withYear) som returnerar ett nytt värde istället för att mutera det ursprungliga objektet.

DateTimeFormatter: Formatera datum i Modern Java

DateTimeFormatter in java.time.format ersätter SimpleDateFormatDen använder samma stil av mönsterbokstäver, är oföränderlig och säker att dela mellan trådar utan extra synkronisering. Klassen exponerar också färdiga konstanter som ISO_LOCAL_DATE och ISO_ZONED_DATE_TIME för standardformat.

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

För att jämföra två datum i det moderna API:et, anropa isBefore, isAfter, eller isEqualDessa metoder är tydligare än compareTo och arbeta med alla java.time klass.

Trådsäkerhet och bästa praxis för Java Datum och tid

Både java.util.Date och SimpleDateFormat föregår modern samtidighet Java, och var och en har kända fallgropar. Följ metoderna nedan för att hålla datumhanteringen korrekt i produktionskoden:

  • Föredra java.time framför Datum och Kalender. De nya typerna är oföränderliga och trådsäkra, och de modellerar domänen mer exakt (datum utan tider, tider utan zoner och så vidare).
  • Dela inte ett SimpleDateFormat mellan trådar. Klassen lagrar intern parsningsstatus och är inte trådsäker. Slå in den i en ThreadLocal, synkronisera på instansen eller växla till DateTimeFormatter.
  • Ange alltid en språkinställning. Månads- och dagsnamn ändras med JVM:s standardspråk, vilket skapar mönster som MMM och EEE icke-portabel. Skicka en språkinställning explicit (till exempel Locale.ENGLISH).
  • Var tydlig med tidszoner. LocalDateTime har ingen zon, så konvertera till ZonedDateTime or Instant närhelst det exakta ögonblicket är viktigt, särskilt för loggar, databaskolumner och nätverksnyttolaster.
  • Konvertera noggrant mellan de två API:erna. Använda date.toInstant(), Date.from(instant)och calendar.toInstant().atZone(zone) i gränslandet mellan äldre kod och modern kod.
  • Lagra tidsstämplar i UTC. Fortsätt och transmit datum som UTC (en Instant eller en ISO 8601-sträng) och konvertera endast till användarzonen vid visning.

Vanliga frågor

Anropa LocalDateTime.now() från java.time-paketet för datum och tid i systemzonen, eller LocalDate.now() endast för datum. På äldre Java, använd new java.util.Date() för att hämta aktuellt tidpunkt.

java.util.Date representerar ett tidpunkt i millisekunder sedan epoken och är föränderlig. LocalDate modellerar ett kalenderdatum utan tid eller zon, är oföränderlig och trådsäker, och erbjuder tydligare metoder som plusDays och isBefore.

Nej. SimpleDateFormat behåller ett föränderligt parsningstillstånd och ger fel resultat när det delas mellan trådar. Slå in det i en ThreadLocal, synkronisera på instansen eller växla till DateTimeFormatter, vilket är oföränderligt och säkert.

Skicka in den exakta strängen "yyyy-MM-dd". Stor bokstav MM är månad, liten bokstav mm är minut. För ett fullständigt datum och tid, använd "yyyy-MM-dd HH:mm:ss". Ange alltid en språkinställning så att månadsnamnen förblir reproducerbara.

Med äldre Date, använd compareTo som returnerar ett negativt, noll eller positivt heltal. Med java.time, anropa isBefore, isAfter eller isEqual på en LocalDate eller Instant. Båda metoderna respekterar kronologisk ordning.

Anropa date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). För att gå tillbaka, använd Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Välj zonen explicit närhelst det exakta ögonblicket är viktigt.

AI-modeller som tränas på logg- och dokumentkorpus härleder det sannolika mönstret från exempelsträngar och returnerar ett matchande DateTimeFormatter-mönster. Maskininlärningsklassificerare flaggar också tvetydiga fält som månad-dag kontra dag-månad-ordning.

Ja. GitHub Copilot föreslår DateTimeFormatter-mönster, ZonedDateTime-konverteringar och JUnit tester för lokalkänslig utdata. RevVisa varje förslag för korrekta mönsterbokstäver, språk och tidszon innan du bestämmer dig.

Sammanfatta detta inlägg med: