Java Päivämäärä ja aika

⚡ Älykäs yhteenveto

Java Päivämäärän ja kellonajan käsittely yhdistää vanhat java.util.Date- ja SimpleDateFormat-luokat moderniin java.time-rajapintaan, joka esiteltiin vuonna Java 8, joka tarjoaa kehittäjille muuttumattomia, säikeeturvallisia tyyppejä tarkkaa kalenterityötä varten.

  • 🕒 Perintöpäivämäärä: java.util.Date-luokka tallentaa hetken millisekunteina ja tulostaa oletusmerkkijonon toString-metodiin asti.
  • 🔤 Kuviokirjaimet: SimpleDateFormat käyttää kirjaimia, kuten vvvv, KK, pp, HH, mm, ss ja zzz, määrittääkseen mukautettuja tulostusmuotoja.
  • 🇧🇷 Vertailu: compareTo-metodi palauttaa negatiivisen, nollan tai positiivisen kokonaisluvun järjestääkseen kaksi Date-esiintymää aikajärjestykseen.
  • 🆕 Moderni API: LocalDate, LocalDateTime, ZonedDateTime ja Instant java.time-tiedostossa korvaavat Date- ja Calendar-objektit muuttumattomilla objekteilla.
  • 🧵 Langan turvallisuus: DateTimeFormatter on muuttumaton ja turvallinen jakaa, kun taas SimpleDateFormat tarvitsee synkronoinnin tai ThreadLocal-kääreen.
  • 🔁 yhteentoimivuus: Muunna vanhan ja uuden API:n välillä käyttämällä Date.toInstant-, Date.from- ja Calendar.toInstant-apureita.

Java Päivämäärä ja aika

Päivämäärien ja kellonaikojen käsittely Java on rutiininomainen osa aikataululogiikan, lokien aikaleimojen, raporttien ja tarkastuspolkujen rakentamista. Ennen minkään koodin kirjoittamista on hyödyllistä tietää päivämäärän muodostavat parametrit:

  • vuosi (kahdella tai neljällä numerolla).
  • kuukausi (kahdena numerona, kuukauden kolmena ensimmäisenä kirjaimena tai kuukauden koko nimellä).
  • data (kuukauden todellinen päivän numero).
  • päivä (päivän nimi annettuna päivämääränä, kuten su, ma, ti).

Java paljastaa monia muita parametreja, jotka kuvaavat aikajanan hetkeä, mukaan lukien aikakauden, viikon vuodessa, aikavyöhykkeen ja offsetin. Alla olevat osiot käsittelevät kutakin niistä suoritettavien esimerkkien avulla.

Kuinka käyttää päivämäärää Java

Näytä päivämäärä Java

Java tarjoaa a Date luokka java.util paketti. Luokka tallentaa tietyn ajanhetken millisekunnin tarkkuudella ja tarjoaa apumetodeja kyseisen ajanhetken tulostamiseen, vertailuun ja muotoiluun. Saadaksesi nykyisen päivämäärän ja kellonajan, luo luokan instanssi sen oletuskonstruktorilla:

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

lähtö:

Wed Nov 29 06:36:22 UTC 2017

Esimerkki tulostaa päivämäärän oletusarvoisessa toString-muodossa. Jos haluat näyttää saman hetken eri muodossa, sinun on ensin ymmärrettävä muotoilukirjaimet, jotka Java käyttötarkoituksia.

SimpleDateFormat: jäsennys ja muotoile päivämäärät

SimpleDateFormat luokka sisään java.text muuntaa Date objekti muotoilluksi merkkijonoksi ja jäsentää muotoillun merkkijonon takaisin DateSe käyttää päivämäärä- tai aikakomponenttiin liittyviä kirjaimia. Alla olevassa taulukossa luetellaan kaikki tuetut kirjaimet:

KirjePäivämäärä tai aika -komponenttiesimerkki
GAikakauden merkkiAD
yVuosi2026
MKuukausi vuodessaheinäkuuta tai heinäkuuta tai 07
wViikko vuodessa27
WViikko kuukaudessa2
DPäivä vuodessa189
dPäivä kuukaudessa10
FViikonpäivä kuukaudessa2
EPäivän nimi viikollatiistai tai ti
uViikon päivän numero (1 = Monday, 7 = sunnuntai)1
aAM- tai PM-merkkiPM
HTunti päivässä (0-23)0
kTunti päivässä (1-24)24
KTunnit AM- tai PM-muodossa (0–11)0
hTunnit AM- tai PM-muodossa (1–12)12
mMinuutti tunnissa30
sToinen minuutilla55
Smillisekunnin978
zAikavyöhyke (nimi)Tyynenmeren normaaliaika; PST; GMT-08:00
ZAikavyöhyke (RFC 822 -poikkeama)-0800
XAikavyöhyke (ISO 8601 -standardin mukainen siirtymä)-08 tai -0800 tai -08:00

Sinun ei tarvitse muistaa koko taulukkoa. Käytä sitä aina, kun rakennat uuden kuvion.

SimpleDateFormatin käyttö

SimpleDateFormat on alaluokka DateFormat jonka avulla voit muotoilla ja jäsentää päivämääriä yllä olevien kirjainmerkkien avulla. Yhdistä kirjaimet kuvaamaan tarkkaa merkkijonoa, jonka haluat tuottaa tai lukea.

Esimerkiksi:

  1. Vaadittu päivämäärämuoto: 2012.10.23 20:20:45 PSTSopiva muotoilu on yyyy.MM.dd HH:mm:ss zzz.
  2. Vaadittu päivämäärämuoto: 09:30:00 AM 23-May-2012Sopiva muotoilu on hh:mm:ss a dd-MMM-yyyy.

Vinkki: Kellon kirjainkoko. Iso kirjain M on kuukausi, pienellä kirjaimella m on minuutti. Iso kirjain H on 24-tuntinen kello, pienellä kirjaimella h on 12-tuntinen kello. Niiden sekoittaminen tuottaa hiljaa väärän tulosteen.

Alla oleva ohjelma tulostaa nykyisen päivämäärän kahdesti, kerran oletusmuodossa ja kerran SimpleDateFormat-kuvion avulla:

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

lähtö:

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

Vertaa päivämääriä esimerkki

Vertaa päivämääriä esimerkki

Luotettavin tapa tilata kaksi Date esineet ovat compareTo() metodi. Se palauttaa negatiivisen kokonaisluvun, kun kutsuja on aikaisempi, nollan, kun molemmat ajanhetket ovat samat, ja positiivisen kokonaisluvun, kun kutsuja on myöhemmin. Alla oleva koodinpätkä jäsentää kaksi päivämäärämerkkijonoa ja tulostaa niiden suhteellisen järjestyksen:

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

lähtö:

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

Huomautus: Alkuperäisessä koodissa käytettiin mallia dd-mm-yyyyPienet kirjaimet mm kirjain on minuutti, ei kuukausi, joten jäsennin tuotti huomaamattomasti väärän kuukauden arvon. Yllä oleva korjaus käyttää isoja kirjaimia MM kuukaudelle, joka on oikea kuvion kirjain.

Java 8 Nykyaikainen päivämäärä- ja aikarajapinta (java.time)

Java 8 esitteli java.time paketti, uudelleensuunniteltu API, joka on saanut inspiraationsa Joda-Time-kirjastosta. Uudet luokat ovat muuttumattomia, säikeeturvallisia ja erottavat ihmisen kalenterin koneen aikajanasta. Yleisimmät tyypit ovat:

  • LocalDate päivämäärälle, jolle ei ole määritetty aikaa tai vyöhykettä (esimerkiksi syntymäpäivä).
  • LocalTime seinäkelloaikaa varten ilman päivämäärää tai vyöhykettä.
  • LocalDateTime päivämäärälle ja kellonajalle ilman vyöhykettä.
  • ZonedDateTime päivämäärälle ja kellonajalle tietyllä aikavyöhykkeellä.
  • OffsetDateTime päivämäärälle ja kellonajalle, jolla on UTC-offset, mutta ei nimettyä vyöhykettä.
  • Instant UNIX-epookista mitatulle koneen aikaleimalle.
  • Duration ja Period aika- ja päivämääräperusteisille summille.

Alla oleva esimerkki tulostaa nykyisen päivämäärän, kellonajan, aikaleiman ja aikavyöhykkeen käyttämällä modernia API:a:

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

Jokaisella tyypillä on tehdasmenetelmät (now, of, parse) ja muuttumattomat operaatiot (plusDays, minusHours, withYear), jotka palauttavat uuden arvon alkuperäisen objektin muuntamisen sijaan.

DateTimeFormatter: Päivämäärien muotoilu Modernissa Java

DateTimeFormatter in java.time.format korvaa SimpleDateFormatSe käyttää samantyylisiä kaavakirjaimia, on muuttumaton ja turvallinen jakaa säikeiden välillä ilman ylimääräistä synkronointia. Luokka tarjoaa myös valmiita vakioita, kuten ISO_LOCAL_DATE ja ISO_ZONED_DATE_TIME vakiomuotoja varten.

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

Kahden päivämäärän vertailemiseksi modernissa API:ssa, kutsu isBefore, isAftertai isEqualNämä menetelmät lukevat selkeämmin kuin compareTo ja työskentele jokaisen kanssa java.time luokka.

Säikeiden turvallisuus ja parhaat käytännöt Java Päivämäärä ja aika

molemmat java.util.Date ja SimpleDateFormat ennen nykyistä samanaikaista Java, ja jokaisessa on tunnettuja sudenkuoppia. Noudata alla olevia käytäntöjä pitääksesi päivämäärän käsittelyn oikein tuotantokoodissa:

  • Suosi java.time-käskyä Date and Calendar -käskyn sijaan. Uudet tyypit ovat muuttumattomia ja säikeeturvallisia, ja ne mallintavat toimialuetta tarkemmin (päivämäärät ilman aikoja, ajat ilman vyöhykkeitä ja niin edelleen).
  • Älä jaa SimpleDateFormat-muotoa eri säikeiden välillä. Luokka tallentaa sisäisen jäsennystilan eikä ole säikeille turvallinen. Kääri se ThreadLocal, synkronoi instanssissa tai vaihda DateTimeFormatter.
  • Määritä aina kieliasetus. Kuukausien ja päivien nimet muuttuvat JVM:n oletuskieliasetuksen mukaan, mikä tekee malleista, kuten MMM ja EEE ei-siirrettävä. Välitä kieliasetus eksplisiittisesti (esimerkiksi Locale.ENGLISH).
  • Ole selkeä aikavyöhykkeistä. LocalDateTime ei ole vyöhykettä, joten muunna muotoon ZonedDateTime or Instant aina kun tarkka hetki on tärkeä, erityisesti lokien, tietokanta-sarakkeiden ja verkon hyötykuormien kohdalla.
  • Muunna kahden API:n välillä huolellisesti. Käyttää date.toInstant(), Date.from(instant)ja calendar.toInstant().atZone(zone) perinteisen ja modernin koodin rajalla.
  • Tallenna aikaleimat UTC-aikavyöhykkeessä. Jatka ja transmit päivämäärät UTC-muodossa ( Instant tai ISO 8601 -merkkijono) ja muuntaa ne käyttäjävyöhykkeeksi vain näytettäessä.

UKK

Kutsu LocalDateTime.now()-funktiota java.time-paketista saadaksesi järjestelmävyöhykkeen päivämäärän ja kellonajan tai LocalDate.now()-funktiota pelkän päivämäärän saamiseksi. Vanhemmilla versioilla Java, käytä funktiota new java.util.Date() saadaksesi nykyisen hetken.

java.util.Date edustaa millisekunteina kulunutta hetkeä epookista ja on muokattava. LocalDate mallintaa kalenteripäivämäärää ilman aikaa tai vyöhykettä, on muuttumaton ja säikeiden kanssa yhteensopiva, ja tarjoaa selkeämpiä metodeja, kuten plusDays ja isBefore.

Ei. SimpleDateFormat säilyttää muuttuvan jäsennystilan ja tuottaa virheellisiä tuloksia, kun sitä jaetaan säikeiden välillä. Kääri se ThreadLocal-elementtiin, synkronoi instanssissa tai vaihda DateTimeFormatteriin, joka on muuttumaton ja turvallinen.

Anna tarkka merkkijono ”vvvv-KK-pp”. Iso KK tarkoittaa kuukautta, pieni mm minuuttia. Koko päivämäärän ja kellonajan saat muodossa ”vvvv-KK-pp HH:mm:ss”. Määritä aina kieli- ja aluekoodi, jotta kuukausien nimet pysyvät toistettavissa.

Käytä vanhan Date-funktion kanssa compareTo-funktiota, joka palauttaa negatiivisen, nollan tai positiivisen kokonaisluvun. java.time-funktion kanssa kutsu isBefore-, isAfter- tai isEqual-funktiota LocalDate- tai Instant-date-date-daten yhteydessä. Molemmat lähestymistavat noudattavat aikajärjestystä.

Kutsu funktiota date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). Palataksesi taaksepäin, käytä funktiota Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Valitse vyöhyke eksplisiittisesti aina, kun tarkka hetki on tärkeä.

Loki- ja dokumenttikorpuksilla koulutetut tekoälymallit päättelevät todennäköisen kuvion esimerkkimerkkijonoista ja palauttavat vastaavan DateTimeFormatter-kuvion. Koneoppimisen luokittelijat merkitsevät myös epäselvät kentät, kuten kuukausi-päivä vs. päivä-kuukausi -järjestys.

Kyllä. GitHub Copilot ehdottaa DateTimeFormatter-malleja, ZonedDateTime-muunnoksia ja JUnit testaa kieliasetuksista riippuvaa tulostetta. RevKatso jokainen ehdotus oikeiden kuviokirjainten, kieliasetuksen ja aikavyöhykkeen osalta ennen vahvistamista.

Tiivistä tämä viesti seuraavasti: