Bună! Astăzi vom începe să lucrăm cu un nou tip de date pe care nu l-am întâlnit până acum, și anume datele.
Nu cred că trebuie să explic ce este o întâlnire. :) În principiu, am putea stoca data și ora curentă într-un șir Java obișnuit.
Acest lucru nu înseamnă că aceste metode nu pot fi utilizate deloc. Dacă încercați să rulați cod folosind metode depreciate într-un IDE, cel mai probabil va funcționa. De exemplu, luați în considerare
Cele mai multe dintre
O dată este doar câteva numere care indică un interval de timp specific. Un calendar este un întreg sistem care vă permite să faceți o mulțime de lucruri cu date. :) Acest lucru este evident dacă încercați să afișați obiectul

public class Main {
public static void main(String[] args) {
String date = "June 11, 2018";
System.out.println(date);
}
}
Dar această abordare are multe dezavantaje. Clasa String
este concepută pentru a lucra cu text, iar metodele sale sunt adecvate pentru această sarcină. Dacă trebuie să manipulăm o dată într-un fel (adăugăm 2 ore, de exemplu), String
nu funcționează atât de bine. Sau dacă vrem să afișăm data și ora curentă când programul este compilat. String
nici aici nu ajută: până când scrieți codul și îl rulați, ora se va fi schimbat și consola va afișa informațiile greșite. De aceea, creatorii Java au oferit mai multe clase pentru lucrul cu datele și ora. Prima dintre acestea estejava.util.Date
Clasa de date
Am specificat numele complet, deoarece un alt pachet Java are clasajava.sql.Date
. Nu le amesteca! Primul lucru pe care trebuie să-l știți despre el este că stochează data ca număr de milisecunde care au trecut de la 1 ianuarie 1970. Acest sistem de timp are chiar propriul nume: „ Unix-time ” O abordare destul de interesantă, nu ar fi nu esti de acord? :) Al doilea lucru care merită reținut este următorul: Dacă creați un Date
obiect utilizând constructorul implicit, rezultatul reprezintă data și ora curente în momentul în care obiectul a fost creat . Îți amintești că am spus că o dată reprezentată ca String
s-ar lupta cu o astfel de sarcină? Clasa Date
se descurcă cu ușurință.
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
}
Rulați acest cod de mai multe ori și veți vedea că ora se schimbă în mod repetat. :) Acest lucru este posibil deoarece timpul este stocat ca milisecunde: sunt unități de timp extrem de mici, deci rezultatele sunt foarte precise. Clasa Date
alt constructor: puteți trece numărul exact de milisecunde de la 00:00 pe 1 ianuarie 1970 până la data necesară și va fi creat un obiect data corespunzător:
public class Main {
public static void main(String[] args) {
Date date = new Date(1212121212121L);
System.out.println(date);
}
}
Ieșire din consolă: Vineri , 30 mai 04:20:12 GMT 2008. Primim 30 mai 2008. „Vineri” indică ziua săptămânii (vineri, duh), iar GMT este fusul orar (Greenwich Mean Time). Milisecundele sunt trecute ca long
s, deoarece numărul de milisecunde nu se încadrează de obicei într-un int
. Așadar, ce operațiuni cu datele ar putea fi nevoie să le facem? Ei bine, cea mai evidentă, desigur, este comparația . Pentru a determina dacă o dată vine înainte sau după alta. Acest lucru se poate face în mai multe moduri. De exemplu, puteți apela Date.getTime()
metoda, care returnează numărul de milisecunde care au trecut de la miezul nopții de 1 ianuarie 1970. Apelați-o pe două obiecte Date și comparați rezultatele:
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");
}
}
Ieșire: data1 este anterioară datei2 Dar există și o modalitate mai convenabilă, adică prin utilizarea metodelor speciale oferite de clasa Date before()
: after()
și equals()
. Toate returnează o valoare booleană. Metoda before()
verifică dacă data noastră este anterioară datei trecute ca 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));
}
}
Ieșire din consolă: true În mod similar, after()
metoda verifică dacă data noastră este mai târziu decât data trecută ca 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));
}
}
Ieșire din consolă: false În exemplele noastre, „punem programul în repaus” timp de 2 secunde, astfel încât cele două date sunt garantate a fi diferite. Pe computerele rapide, timpul dintre crearea date1
și date2
poate fi mai mic de o milisecundă, determinând ambele before()
și after()
să revină false. Dar în acest caz, equals()
metoda va reveni adevărată! La urma urmei, compară numărul de milisecunde de la 00:00 pe 1 ianuarie 1970 pentru fiecare dată. Obiectele sunt considerate egale numai dacă se potrivesc cu milisecunda :
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));
}
Iată un alt lucru la care trebuie să fii atent. Dacă deschideți documentația pentru Date
clasă pe site-ul Oracle , veți vedea că multe dintre metodele și constructorii acesteia au fost marcați ca Deprecated (adică nu sunt recomandate pentru utilizare). Iată ce au de spus creatorii Java despre părțile claselor care au fost depreciate:
„Un element de program adnotat @Deprecated este ceva ce programatorilor nu li se recomandă să folosească, de obicei pentru că este periculos sau pentru că există o alternativă mai bună.” |
Date.getHours()
metoda depreciată, care returnează numărul de ore asociat unui Date
obiect.
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.getHours());
}
Dacă începeți codul la 14:21 (2:21 PM), acesta va afișa numărul 14. După cum puteți vedea, metoda depreciată este tăiată, dar încă funcționează. Aceste metode nu sunt eliminate pentru a nu sparge corpul imens de cod existent care le folosește. Cu alte cuvinte, aceste metode nu sunt nici „rupte”, nici „eliminate”. Pur și simplu nu sunt recomandate pentru utilizare, deoarece este disponibilă o alternativă mai convenabilă. De altfel, documentația menționează în mod specific această alternativă:

Date
metodele clasei au fost mutate în Calendar
clasa îmbunătățită și extinsă. Ne vom familiariza cu acea clasă în continuare. :)
Clasa de calendar
JDK 1.1 a introdus o nouă clasă:Calendar
. A făcut lucrul cu date în Java oarecum mai ușor decât înainte. Singura implementare a clasei Calendar
cu care vom lucra este GregorianCalendar
clasa. Implementează calendarul gregorian, care este respectat de majoritatea țărilor lumii. Principalul său avantaj este că poate lucra cu date într-un format mai convenabil. De exemplu, poate:
- Adăugați o lună sau o zi la data curentă
- Verificați dacă anul este un an bisect;
- Returnează componentele individuale ale datei (de exemplu, extrageți numărul lunii dintr-o dată întreagă)
- Conține, de asemenea, un sistem de constante foarte convenabil (dintre care multe le vom vedea mai jos).
Calendar
clasei este constanta Calendar.ERA : puteți indica o dată înaintea erei comune (î.Hr. - înainte de Hristos) sau în era comună (AD - Anno Domini). Să ne uităm la toate acestea cu exemple. Să creăm un calendar
obiect cu data de 25 ianuarie 2017:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
În Calendar
clasă (precum și în Date
clasă), lunile încep de la zero , așa că trecem numărul 0 ca al doilea argument. Când lucrați cu Calendar
clasa, este important să înțelegeți că acesta este doar un calendar , nu o dată individuală. 
Calendar
: Ieșire: 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,?_YEAR=DAY_OF,? ,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?] Vedeți câte informații obțineți ! Un calendar are o grămadă de proprietăți pe care o dată normală nu le are și toate sunt afișate (așatoString()
funcționează metoda înCalendar
clasă). Dacă trebuie doar să obțineți o dată simplă din calendar, adică unDate
obiect, utilizațiCalendar.getTime()
metoda (numele nu este cel mai logic, dar ce poți face?):
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
Date date = calendar.getTime();
System.out.println(date);
}
Ieșire: miercuri 25 ianuarie 00:00:00 GMT 2017 Acum am luat calendarul și l-am „redus” la o dată obișnuită. Să mergem mai departe. Pe lângă desemnarea lunilor după numărul lor, puteți utiliza valorile constante ale câmpuluiCalendar
clasei . Aceste constante sunt câmpuri statice ale clasei cu o valoare prestabilită care nu poate fi modificată. Aceasta este de fapt o opțiune și mai bună, deoarece utilizarea lor îmbunătățește lizibilitatea codului dvs. Calendar
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.IANUARIE este una dintre constantele care reprezintă lunile anului. Folosind aceste constante numite, nimeni nu va uita, de exemplu, că numărul 3 înseamnă aprilie, și nu luna a treia, pe care ne place să o numim martie. Scrieți Calendar.APRIL și ați terminat. :) Toate câmpurile calendarului (număr, lună, minute, secunde etc.) pot fi specificate separat folosindset()
metoda. Această metodă este foarte convenabilă, deoareceCalendar
clasa are o constantă pentru fiecare câmp, iar codul rezultat este foarte ușor de citit. În ultimul exemplu, am creat o dată, dar nu am stabilit o oră pentru aceasta. Să setăm ora 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());
}
Ieșire: Miercuri 25 ianuarie 19:42:12 GMT 2017 Apelăm set()
metoda, trecând o constantă (în funcție de câmpul pe care vrem să-l schimbăm) și noua valoare pentru câmp. Se pare că această set()
metodă este un fel de „super-setter” care știe să stabilească valoarea nu doar pentru un câmp, ci pentru mai multe câmpuri. :) Calendar
Clasa folosește add()
metoda pentru a adăuga și scădea valori. Treci în câmpul pe care vrei să-l schimbi și un număr (exact cât vrei să adaugi/scădezi din valoarea curentă). De exemplu, să obținem o dată care este cu 2 luni înainte de data pe care am creat-o:
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());
}
Ieșire: vineri, 25 noiembrie 19:42:12 GMT 2016 Foarte bine! Am primit data acum 2 luni. Acest lucru nu a determinat doar schimbarea lunii: și anul s-a schimbat din 2017 în 2016. Desigur, la conversia datelor, anul curent este calculat automat, fără a fi nevoie să-l urmăriți manual. Dar dacă dintr-un motiv oarecare trebuie să dezactivați acest comportament, puteți face acest lucru. Metoda roll()
poate adăuga și scădea valori fără a afecta valorile rămase . De exemplu, așa:
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());
}
Am făcut exact același lucru ca în exemplul anterior: am luat 2 luni de la data curentă. Dar acum codul face ceva diferit: luna s-a schimbat din ianuarie până în noiembrie, dar anul rămâne neschimbat — 2017! Ieșire: sâmb. 25 noiembrie 10:42:12 GMT 2017 În mișcare. După cum am spus mai sus, putem obține toate Calendar
câmpurile separat. Facem asta cu get()
metoda:
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));
}
Rezultat: Anul: 2017 Luna: 0 Săptămâna din lună: 5 Ziua: 25 Ore: 10 Minute: 42 Secunde: 12 Milisecunde: 0 Deci, pe lângă Calendar
„super-setter” al clasei, există și un „super-getter”. ". :) Desigur, un alt aspect interesant al acestei clase este lucrul cu epoci. Pentru a crea o dată „BC”, va trebui să utilizați câmpul Calendar.ERA De exemplu, să creăm o dată pentru Bătălia de la Cannae, în care Hannibal a învins armata romană. Acest lucru s-a întâmplat pe 2 august 216 î.Hr.:
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()));
}
Aici am folosit SimpleDateFormat
clasa pentru a tipări data într-un format care este mai ușor de înțeles pentru noi (literele „GG” indică că vrem ca epoca să fie afișată). Ieșire: 02 august 216 î.Hr. Clasa Calendar
are mult mai multe metode și constante. Puteți citi despre ele în documentație . Dacă nu vă place acest format de dată Sâmbătă, 25 noiembrie 10:42:12 GMT 2017, îl puteți utiliza SimpleDateFormat
pentru a face cu ușurință ceea ce doriți să fie.
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()));
}
Ieșire: sâmbătă, 25 noiembrie 2017 E mult mai bine, nu-i așa? :)
GO TO FULL VERSION