Hei! I dag begynner vi å jobbe med en ny datatype vi ikke har møtt før, nemlig datoer.
Jeg tror ikke jeg trenger å forklare hva en date er. :) I prinsippet kunne vi lagre gjeldende dato og klokkeslett i en vanlig Java-streng.
Dette betyr ikke at disse metodene ikke kan brukes i det hele tatt. Hvis du prøver å kjøre kode ved hjelp av utdaterte metoder i en IDE, vil det mest sannsynlig fungere. Tenk for eksempel på den utdaterte
De fleste av
En dato er bare noen få tall som indikerer et spesifikt tidsintervall. En kalender er et helt system som lar deg gjøre mange ting med datoer. :) Dette er rikelig tydelig hvis du prøver å vise objektet

public class Main {
public static void main(String[] args) {
String date = "June 11, 2018";
System.out.println(date);
}
}
Men denne tilnærmingen har mange ulemper. Klassen String
er laget for å jobbe med tekst, og metodene egner seg for denne oppgaven. Hvis vi trenger å manipulere en dato på en eller annen måte (legg til 2 timer, for eksempel), String
fungerer ikke så bra. Eller om vi ønsker å vise gjeldende dato og klokkeslett når programmet er kompilert. String
hjelper ikke her heller: når du skriver koden og kjører den, vil tiden ha endret seg og konsollen vil vise feil informasjon. Det er derfor Javas skapere ga flere klasser for å jobbe med datoer og klokkeslett. Den første av disse erjava.util.Date
Dato klasse
Vi spesifiserte det fulle navnet, fordi en annen Java-pakke har klassenjava.sql.Date
. Ikke bland dem sammen! Det første du trenger å vite om det er at det lagrer datoen som antall millisekunder som har gått siden 1. januar 1970. Dette tidssystemet har til og med sitt eget navn: " Unix-time " En ganske interessant tilnærming, ville' er du enig? :) Den andre tingen som er verdt å huske på er dette: Hvis du oppretter et Date
objekt ved å bruke standardkonstruktøren, representerer resultatet gjeldende dato og klokkeslett i det øyeblikket objektet ble opprettet . Husker du at vi sa at en date representert som en String
ville slite med en slik oppgave? Klassen Date
håndterer det med letthet.
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
}
Kjør denne koden flere ganger, og du vil se tiden endres gjentatte ganger. :) Dette er mulig fordi tiden er lagret som millisekunder: de er ekstremt små tidsenheter, så resultatene er svært nøyaktige. Klassen Date
en annen konstruktør: du kan sende det nøyaktige antallet millisekunder siden 00:00 1. januar 1970 til den nødvendige datoen, og et tilsvarende datoobjekt vil bli opprettet:
public class Main {
public static void main(String[] args) {
Date date = new Date(1212121212121L);
System.out.println(date);
}
}
Konsollutgang: Fre 30. mai 04:20:12 GMT 2008 Vi får 30. mai 2008. "Fre" indikerer ukedagen (fredag, duh), og GMT er tidssonen (Greenwich Mean Time). Millisekunder sendes som long
s, fordi antall millisekunder vanligvis ikke passer inn i en int
. Så, hvilke operasjoner med datoer må vi kanskje utføre? Vel, det mest åpenbare er selvfølgelig sammenligning . For å finne ut om en date kommer før eller etter en annen. Dette kan gjøres på flere måter. Du kan for eksempel kalle Date.getTime()
metoden, som returnerer antall millisekunder som har gått siden midnatt 1. januar 1970. Bare kall den på to Dato-objekter og sammenlign resultatene:
public class Main {
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println((date1.getTime() > date2.getTime())?
"date1 is later than date2" : "date1 is earlier than date2");
}
}
Utdata: dato1 er tidligere enn dato2 Men det er også en mer praktisk måte, dvs. ved å bruke spesielle metoder fra Dato-klassen: before()
, after()
og equals()
. Alle returnerer en boolsk verdi. Metoden before()
sjekker om datoen vår er tidligere enn datoen som ble sendt som argument:
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);// Suspend the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.before(date2));
}
}
Konsoll-utgang: sann På samme måte after()
sjekker metoden for å se om datoen vår er senere enn datoen som ble sendt som argument:
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);// Suspend the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.after(date2));
}
}
Konsollutgang: usann I våre eksempler "setter vi programmet i dvale" i 2 sekunder, slik at de to datoene garantert er forskjellige. På raske datamaskiner kan tiden mellom opprettelsen av date1
og date2
være mindre enn ett millisekund, noe som fører til at både before()
og after()
returnerer falsk. Men i dette tilfellet equals()
vil metoden returnere sann! Tross alt sammenligner den antall millisekunder siden klokken 00:00 1. januar 1970 for hver dato. Objektene anses som like bare hvis de samsvarer med millisekundet :
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println(date1.getTime());
System.out.println(date2.getTime());
System.out.println(date1.equals(date2));
}
Her er en annen ting du må være oppmerksom på. Hvis du åpner dokumentasjonen for Date
klassen på Oracle- nettstedet, vil du se at mange av metodene og konstruktørene har blitt merket som avviklet (dvs. ikke anbefalt for bruk). Her er hva Javas skapere har å si om deler av klasser som har blitt avviklet:
"Et programelement merket @Utviklet er noe programmerere ikke anbefales å bruke, vanligvis fordi det er farlig, eller fordi det finnes et bedre alternativ." |
Date.getHours()
metoden, som returnerer antall timer assosiert med et Date
objekt.
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.getHours());
}
Hvis du starter koden klokken 14:21 (14:21), vil den vise tallet 14. Som du kan se, er den utdaterte metoden krysset over, men den fungerer fortsatt. Disse metodene fjernes ikke for ikke å ødelegge den enorme mengden av eksisterende kode som bruker dem. Disse metodene er med andre ord verken "ødelagt" eller "fjernet". De anbefales rett og slett ikke for bruk fordi et mer praktisk alternativ er tilgjengelig. Dokumentasjonen nevner forøvrig spesifikt dette alternativet:

Date
klassens metoder har blitt flyttet til den forbedrede og utvidede Calendar
klassen. Vi blir kjent med den timen neste gang. :)
Kalenderklasse
JDK 1.1 introduserte en ny klasse:Calendar
. Det gjorde arbeidet med datoer i Java noe enklere enn før. Den eneste implementeringen av klassen Calendar
vi skal jobbe med er GregorianCalendar
klassen. Den implementerer den gregorianske kalenderen, som observeres av de fleste land i verden. Dens største fordel er at den kan fungere med datoer i et mer praktisk format. For eksempel kan det:
- Legg til en måned eller dag til gjeldende dato
- Sjekk om året er et skuddår;
- Returner individuelle komponenter av datoen (trekk for eksempel ut månedsnummeret fra en hel dato)
- Den inneholder også et veldig praktisk system med konstanter (mange av dem vil vi se nedenfor).
Calendar
klassen er dens Calendar.ERA konstant: du kan angi en dato før den vanlige epoken (f.Kr. - før Kristus) eller i den vanlige epoken (AD - Anno Domini). La oss se på alt dette med eksempler. La oss lage et calendar
objekt med datoen 25. januar 2017:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
I Calendar
klassen (så vel som Date
klassen for den saks skyld) starter måneder fra null , så vi passerer tallet 0 som det andre argumentet. Når du arbeider med Calendar
klassen, er det viktig å forstå at dette er nettopp det, en kalender , ikke en individuell dato. 
Calendar
: Output: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=0,useDaylight= false,transitions=79,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=1,ERA=?,YEAR=2017,MONTH=0,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_DAY_OF_YEAR? ,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?] Se hvor mye informasjon du får ! En kalender har en haug med egenskaper som en vanlig dato ikke har, og alle vises (sliktoString()
fungerer metoden iCalendar
klassen). Hvis du bare trenger å få en enkel dato fra kalenderen, altså etDate
objekt, brukCalendar.getTime()
metode (navnet er ikke det mest logiske, men hva kan du gjøre?):
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
Date date = calendar.getTime();
System.out.println(date);
}
Utgang: Wed Jan 25 00:00:00 GMT 2017 Nå har vi tatt kalenderen og "redusert den" til en ordinær dato. La oss gå videre. I tillegg til å angi måneder etter antall, kan du bruke Calendar
klassens konstante feltverdier . Disse konstantene er statiske felt i Calendar
klassen med en forhåndsinnstilt verdi som ikke kan endres. Dette er faktisk et enda bedre alternativ, fordi bruk av dem forbedrer lesbarheten til koden din.
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Kalender.JANUAR er en av konstantene som representerer månedene i året. Ved å bruke disse navngitte konstantene vil ingen glemme for eksempel at tallet 3 betyr april, og ikke tredje måned, som vi gjerne kaller mars. Bare skriv Kalender.APRIL , så er du ferdig. :) Alle kalenderfelt (tall, måned, minutter, sekunder osv.) kan spesifiseres separat ved hjelp av metodenset()
. Denne metoden er veldig praktisk, fordiCalendar
klassen har en konstant for hvert felt, og den resulterende koden er veldig lett å lese. I det siste eksemplet opprettet vi en dato, men satte ikke noe tidspunkt for den. La oss stille klokken 19:42:12
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.YEAR, 2017);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 25);
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println(calendar.getTime());
}
Utdata: Wed Jan 25 19:42:12 GMT 2017 Vi kaller set()
metoden, og sender en konstant (avhengig av feltet vi ønsker å endre) og den nye verdien for feltet. Det viser seg at denne set()
metoden er en slags "super-setter" som vet hvordan man setter verdien ikke bare for ett felt, men for mange felt. :) Calendar
Klassen bruker add()
metoden for å addere og subtrahere verdier. Du sender inn feltet du ønsker å endre, og et tall (nøyaktig hvor mye du vil legge til/trekke fra fra gjeldende verdi). La oss for eksempel få en dato som er 2 måneder før datoen vi opprettet:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.add(Calendar.MONTH, -2); // To subtract, pass a negative number
System.out.println(calendar.getTime());
}
Utgang: Fre 25. nov 19:42:12 GMT 2016 Veldig bra! Vi fikk datoen for 2 måneder siden. Dette førte ikke bare til at måneden endret seg: året endret seg også fra 2017 til 2016. Selvfølgelig, når du konverterer datoer, beregnes gjeldende år automatisk uten at du trenger å holde styr på det manuelt. Men hvis du av en eller annen grunn trenger å deaktivere denne oppførselen, kan du gjøre det. Metoden roll()
kan legge til og trekke fra verdier uten å påvirke de gjenværende verdiene . For eksempel slik:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
}
Vi gjorde nøyaktig det samme som i forrige eksempel: vi tok 2 måneder fra gjeldende dato. Men nå gjør koden noe annerledes: måneden har endret seg fra januar til november, men året forblir uendret—2017! Utgang: Lør 25. nov 10:42:12 GMT 2017 Går videre. Som vi sa ovenfor, kan vi få alle Calendar
feltene separat. Dette gjør vi med get()
metoden:
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println("Year: " + calendar.get(Calendar.YEAR));
System.out.println("Month: " + calendar.get(Calendar.MONTH));
System.out.println("Week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// Week in this month?
System.out.println("Day: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("Hours: " + calendar.get(Calendar.HOUR));
System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));
}
Utgang: År: 2017 Måned: 0 Uke i måneden: 5 Dag: 25 Timer: 10 minutter: 42 sekunder: 12 millisekunder: 0 Så, i tillegg til Calendar
klassens "super-setter", er det også en "super-getter" ". :) Selvfølgelig er et annet interessant aspekt ved denne klassen å jobbe med epoker. For å lage en "BC"-dato, må du bruke Calendar.ERA- feltet La oss for eksempel lage en dato for slaget ved Cannae, der Hannibal beseiret den romerske hæren. Dette skjedde 2. august 216 f.Kr.:
public static void main(String[] args) {
GregorianCalendar cannae = new GregorianCalendar(216, Calendar.AUGUST, 2);
cannae.set(Calendar.ERA, GregorianCalendar.BC);
DateFormat df = new SimpleDateFormat("MMM dd, yyy GG");
System.out.println(df.format(cannae.getTime()));
}
Her brukte vi SimpleDateFormat
klassen til å skrive ut datoen i et format som er lettere for oss å forstå (bokstavene "GG" indikerer at vi ønsker at epoken skal vises). Utgang: 2. august 216 f.Kr. Klassen Calendar
har mange flere metoder og konstanter. Du kan lese om dem i dokumentasjonen . Hvis du ikke liker dette datoformatet Sat Nov 25 10:42:12 GMT 2017, kan du bruke det SimpleDateFormat
til å enkelt gjøre det til det du vil ha det til.
public static void main(String[] args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(dateFormat.format(calendar.getTime()));
}
Utgang: lørdag 25. november 2017 Det er mye bedre, ikke sant? :)
GO TO FULL VERSION