Hej! Idag börjar vi arbeta med en ny datatyp som vi inte har stött på tidigare, nämligen datum. Jag tror inte att jag behöver förklara vad en dejt är. :) I princip skulle vi kunna lagra aktuellt datum och tid i en vanlig Java-sträng.
Detta betyder inte att dessa metoder inte kan användas alls. Om du försöker köra kod med föråldrade metoder i en IDE, kommer det med största sannolikhet att fungera. Tänk till exempel på den föråldrade
De flesta av
public class Main {
public static void main(String[] args) {
String date = "June 11, 2018";
System.out.println(date);
}
}
Men detta tillvägagångssätt har många nackdelar. Klassen String
är designad för att arbeta med text, och dess metoder är lämpliga för denna uppgift. Om vi behöver manipulera ett datum på något sätt (lägg till 2 timmar till exempel), String
fungerar inte så bra. Eller om vi vill visa aktuellt datum och tid när programmet kompileras. String
hjälper inte här heller: när du skriver koden och kör den kommer tiden att ha ändrats och konsolen kommer att visa fel information. Det är därför Javas skapare gav flera klasser för att arbeta med datum och tid. Den första av dessa ärjava.util.Date
Datum klass
Vi angav dess fullständiga namn, eftersom ett annat Java-paket harjava.sql.Date
klassen. Blanda inte ihop dem! Det första du behöver veta om det är att det lagrar datumet som antalet millisekunder som har gått sedan 1 januari 1970. Det här tidssystemet har till och med ett eget namn: " Unix-time " Ett ganska intressant tillvägagångssätt, skulle' håller du med? :) Det andra värt att komma ihåg är detta: Om du skapar ett Date
objekt med standardkonstruktorn, representerar resultatet aktuellt datum och tid då objektet skapades . Kommer du ihåg att vi sa att en dejt representerad som en String
skulle kämpa med en sådan uppgift? Klassen Date
hanterar det med lätthet.
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
}
Kör den här koden flera gånger så kommer du att se tiden ändras upprepade gånger. :) Detta är möjligt eftersom tiden lagras som millisekunder: de är extremt små tidsenheter, så resultaten är mycket exakta. Klassen Date
en annan konstruktor: du kan skicka det exakta antalet millisekunder sedan 00:00 den 1 januari 1970 till det önskade datumet, och ett motsvarande datumobjekt kommer att skapas:
public class Main {
public static void main(String[] args) {
Date date = new Date(1212121212121L);
System.out.println(date);
}
}
Konsolutdata: Fre 30 maj 04:20:12 GMT 2008 Vi får 30 maj 2008. "Fre" indikerar veckodagen (fredag, duh), och GMT är tidszonen (Greenwich Mean Time). Millisekunder skickas som long
s, eftersom antalet millisekunder vanligtvis inte passar in i en int
. Så, vilka operationer med datum kan vi behöva utföra? Tja, det mest uppenbara är förstås jämförelse . För att avgöra om ett datum kommer före eller efter ett annat. Detta kan göras på flera sätt. Du kan till exempel anropa Date.getTime()
metoden, som returnerar antalet millisekunder som har förflutit sedan midnatt den 1 januari 1970. Kalla den bara på två Date-objekt och jämför resultaten:
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: datum1 är tidigare än datum2 Men det finns också ett bekvämare sätt, t.ex. genom att använda speciella metoder som tillhandahålls av klassen Date: before()
, after()
och equals()
. Alla returnerar ett booleskt värde. Metoden before()
kontrollerar om vårt datum är tidigare än det datum som passerade som ett 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));
}
}
Konsolutdata: sant På samma sätt after()
kontrollerar metoden om vårt datum är senare än det datum som skickades 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));
}
}
Konsolutgång: false I våra exempel "ställer vi programmet i vila" i 2 sekunder, så att de två datumen garanterat är olika. På snabba datorer kan tiden mellan skapandet av date1
och date2
vara mindre än en millisekund, vilket gör att både before()
och after()
returnerar false. Men i det här fallet equals()
kommer metoden att returnera sant! När allt kommer omkring jämför den antalet millisekunder sedan 00:00 den 1 januari 1970 för varje datum. Objekten anses vara lika endast om de matchar millisekunden :
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));
}
Här är en annan sak du måste vara uppmärksam på. Om du öppnar dokumentationen för Date
klassen på Oracle -webbplatsen ser du att många av dess metoder och konstruktörer har markerats som föråldrade (dvs. rekommenderas inte för användning). Här är vad Javas skapare har att säga om delar av klasser som har fasats ut:
"Ett programelement som är kommenterat @Föråldrat är något som programmerare inte rekommenderas att använda, vanligtvis för att det är farligt eller för att det finns ett bättre alternativ." |
Date.getHours()
metoden, som returnerar antalet timmar som är associerade med ett Date
objekt.
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.getHours());
}
Om du startar koden klockan 14:21 (14:21) kommer den att visa siffran 14. Som du kan se är den föråldrade metoden överstruken, men den fungerar fortfarande. Dessa metoder tas inte bort för att inte bryta den enorma mängden befintlig kod som använder dem. Med andra ord är dessa metoder varken "trasiga" eller "borttagna". De rekommenderas helt enkelt inte för användning eftersom det finns ett bekvämare alternativ. För övrigt nämner dokumentationen specifikt detta alternativ:
Date
klassens metoder har flyttats till den förbättrade och utökade Calendar
klassen. Vi ska bekanta oss med den klassen härnäst. :)
Kalenderklass
JDK 1.1 introducerade en ny klass:Calendar
. Det gjorde arbetet med datum i Java något enklare än tidigare. Den enda implementeringen av klassen Calendar
som vi kommer att arbeta med är GregorianCalendar
klassen. Den implementerar den gregorianska kalendern, som observeras av de flesta länder i världen. Dess främsta fördel är att den kan arbeta med datum i ett mer bekvämt format. Det kan till exempel:
- Lägg till en månad eller dag till det aktuella datumet
- Kontrollera om året är ett skottår;
- Returnera enskilda komponenter av datumet (extrahera till exempel månadsnumret från ett helt datum)
- Den innehåller också ett mycket bekvämt system av konstanter (av vilka många kommer att se nedan).
Calendar
klassen är dess Calendar.ERA- konstant: du kan ange ett datum före den vanliga eran (BC - före Kristus) eller i den vanliga eran (AD - Anno Domini). Låt oss titta på allt detta med exempel. Låt oss skapa ett calendar
objekt med datumet 25 januari 2017:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
I Calendar
klassen (liksom Date
klassen för den delen) börjar månader från noll , så vi skickar siffran 0 som andra argument. När du arbetar med klassen Calendar
är det viktigt att förstå att detta är just det, en kalender , inte ett individuellt datum. Ett datum är bara några siffror som indikerar ett specifikt tidsintervall. En kalender är ett helt system som låter dig göra många saker med datum. :) Detta är rikligt uppenbart om du försöker visa objektet 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=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 hur mycket information du får! En kalender har ett gäng egenskaper som ett normalt datum inte har, och alla visas (så härtoString()
fungerar metoden iCalendar
klassen). Om du bara behöver få ett enkelt datum från kalendern, dvs ettDate
objekt, användCalendar.getTime()
metod (namnet är inte det mest logiska, men vad kan du göra?):
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
Date date = calendar.getTime();
System.out.println(date);
}
Utdata: Wed Jan 25 00:00:00 GMT 2017 Nu har vi tagit kalendern och "förminskat den" till ett vanligt datum. Låt oss gå längre. Förutom att ange månader efter deras antal kan du använda Calendar
klassens konstanta fältvärden . Dessa konstanter är statiska fält i Calendar
klassen med ett förinställt värde som inte kan ändras. Detta är faktiskt ett ännu bättre alternativ, eftersom att använda dem förbättrar läsbarheten för din kod.
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Kalender.JANUARI är en av konstanterna som representerar årets månader. Med dessa namngivna konstanter kommer ingen att glömma till exempel att siffran 3 betyder april och inte tredje månaden, som vi gärna kallar mars. Skriv bara Kalender.APRIL så är du klar. :) Alla kalenderfält (antal, månad, minuter, sekunder, etc.) kan specificeras separat med metodenset()
. Denna metod är mycket bekväm, eftersomCalendar
klassen har en konstant för varje fält, och den resulterande koden är mycket lätt att läsa. I det sista exemplet skapade vi ett datum, men satte ingen tid för det. Låt oss ställa in tiden 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 kallar set()
metoden och skickar en konstant (beroende på vilket fält vi vill ändra) och det nya värdet för fältet. Det visar sig att denna set()
metod är en slags "super-setter" som vet hur man ställer in värdet inte bara för ett fält, utan för många fält. :) Calendar
Klassen använder add()
metoden för att addera och subtrahera värden. Du skickar i fältet du vill ändra, och ett tal (exakt hur mycket du vill lägga till/subtrahera från det aktuella värdet). Låt oss till exempel få ett datum som ligger 2 månader före det datum vi skapade:
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());
}
Utdata: fre 25 nov 19:42:12 GMT 2016 Mycket bra! Vi fick datumet för 2 månader sedan. Detta ledde inte bara till att månaden ändrades: året ändrades också från 2017 till 2016. Naturligtvis, vid konvertering av datum, beräknas det aktuella året automatiskt utan att du behöver hålla reda på det manuellt. Men om du av någon anledning behöver inaktivera detta beteende kan du göra det. Metoden roll()
kan addera och subtrahera värden utan att påverka de återstående värdena . Till exempel, så här:
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 exakt samma sak som i föregående exempel: vi tog 2 månader från det aktuella datumet. Men nu gör koden något annorlunda: månaden har ändrats från januari till november, men året förblir oförändrat—2017! Utdata: lör 25 nov 10:42:12 GMT 2017 Går vidare. Som vi sa ovan kan vi få alla Calendar
fält separat. Vi gör detta 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));
}
Utdata: År: 2017 Månad: 0 Vecka i månaden: 5 Dag: 25 Timmar: 10 minuter: 42 sekunder: 12 millisekunder: 0 Så, förutom klassens Calendar
"super-setter", finns det också en "super-getter" ". :) Naturligtvis är en annan intressant aspekt av den här klassen att arbeta med epoker. För att skapa ett "BC"-datum måste du använda fältet Calendar.ERA Låt oss till exempel skapa ett datum för slaget vid Cannae, där Hannibal besegrade den romerska armén. Detta hände den 2 augusti 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()));
}
Här använde vi SimpleDateFormat
klassen för att skriva ut datumet i ett format som är lättare för oss att förstå (bokstäverna "GG" indikerar att vi vill att eran ska visas). Utgång: 2 augusti 216 f.Kr. Klassen Calendar
har många fler metoder och konstanter. Du kan läsa om dem i dokumentationen . Om du inte gillar det här datumformatet Sat Nov 25 10:42:12 GMT 2017 kan du använda SimpleDateFormat
för att enkelt göra det till vad du vill att det ska vara.
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()));
}
Utdata: Lördagen den 25 november 2017 Det är mycket bättre, eller hur? :)
GO TO FULL VERSION