Programiranje

Delo v času Java

Ta članek temelji na informacijah, predstavljenih v mojem članku o izračunu datumov Java (JavaWorld, 29. decembra 2000). Tu sem naštel nekaj ključnih točk iz tega članka, ki bi vam morale biti znane. Če vam te točke niso jasne, priporočam, da preberete "Izračun datumov Java" za nadaljnjo razlago.

  1. Java računa čas v milisekundah pred začetkom 1. januarja 1970 ali po njem.
  2. The Datum konstruktor razreda Datum () vrne objekt, ki predstavlja trenutek, ko je bil objekt ustvarjen. Datumje getTime () metoda vrne a dolga vrednost, katere število je enako številu milisekund pred ali po 1. januarju 1970.
  3. The Format datuma class se uporablja za pretvorbo Datums do Vrvicas in obratno. Statična getDateInstance () metoda vrne a Format datuma objekt v privzeti obliki; getDateInstance (DateFormat.FIELD) vrne a Format datuma predmet z določeno obliko. The oblika (datum d) metoda vrne a Vrvica ki predstavlja datum, na primer "1. januar 2002." Nasprotno pa razčlenitev (nizi) metoda vrne a Datum predmet glede na datum Vrvica argument predstavlja.
  4. Videz Vrvicas vrnil format () metoda se lahko razlikuje glede na regionalne nastavitve v računalniku, v katerem se izvaja program.
  5. The Gregorijanski koledar class ima dva pomembna konstruktorja: GregorianCalendar (), ki vrne objekt, ki predstavlja trenutek, ko je bil ustvarjen, in GregorianCalendar (int leto, int mesec, int datum) konstruktor, ki se uporablja za ustvarjanje predmeta, ki predstavlja poljuben datum. The Gregorijanski koledar razredov getTime () metoda vrne a Datum predmet. The dodaj (int polje, int znesek) metoda izračuna datume z dodajanjem ali odštevanjem časovnih enot, kot so dnevi, meseci ali leta.

Gregorijanski koledar in čas

Dva Gregorijanski koledar s konstruktorji razredov se lahko ukvarjamo s časom. Prvi ustvari objekt, ki predstavlja datum, uro in minuto:

GregorianCalendar (int leto, int mesec, int datum, int ura, int minuta) 

Drugi ustvari objekt, ki predstavlja datum, uro, minuto in sekundo:

GregorianCalendar (int leto, int mesec, int datum, int ura, int minuta, int sekunda) 

Najprej moram opozoriti, da vsak konstruktor poleg podatkov o času zahteva še podatke o datumu (leto, mesec in dan). Če želite govoriti o 14.30, morate določiti datum.

Tudi vsak Gregorijanski koledar konstruktor ustvari objekt, ki predstavlja trenutek v času, izračunan z natančnostjo milisekunde. Če torej vaš konstruktor vzame argumente samo za leto, mesec in datum, so vrednosti za ure, minute, sekunde in milisekunde nastavljene na nič. Če vaš konstruktor vzame argumente za leto, mesec, datum, ure in minute, so sekunde in milisekunde nastavljene na nič.

DateFormat in čas

Če želite ustvariti a Format datuma predmet za prikaz ure in datuma, lahko uporabite statično metodo getDateTimeInstance (int dateStyle, int timeStyle). Ta metoda določa datume in časovne sloge, ki jih želite uporabiti. Če ste zadovoljni s privzetimi slogi, lahko nadomestite krajšega getDateTimeInstance ().

Če želite ustvariti a Format datuma Če želite prikazati samo čas, lahko uporabite statično metodo getTimeInstance (int timeStyle).

Spodnji program prikazuje, kako getDateTimeInstance () in getTimeInstance () metode delujejo:

uvoz java.util. *; uvoz java.text. *; javni razred Apollo {javna statična praznina main (String [] args) {GregorianCalendar liftOffApollo11 ​​= new GregorianCalendar (1969, Calendar.JULY, 16, 9, 32); Datum d = liftOffApollo11.getTime (); DateFormat df1 = DateFormat.getDateTimeInstance (DateFormat.MEDIUM, DateFormat.MEDIUM); DateFormat df2 = DateFormat.getTimeInstance (DateFormat.SHORT); Niz s1 = df1.format (d); Niz s2 = df2.format (d); System.out.println (s1); System.out.println (s2); }} 

V mojem računalniku zgornji program prikazuje naslednje:

16. julij 1969 9:32:00

9:32

(Izhod se lahko razlikuje glede na regionalne nastavitve računalnika.)

Izračunavanje pretečenega časa

Včasih boste morda morali izračunati pretečeni čas; na primer, morda boste želeli vedeti trajanje proizvodnega procesa glede na začetni in končni čas. Podjetje za najem, ki najame predmete po urah ali dnevih, bo morda koristno izračunati pretečeni čas. Podobno je v finančnem svetu pogosto treba izračunati plačila obresti v preteklem času.

Da bi zapletli težavo, ljudje izračunani čas izračunajo na vsaj dva načina. Lahko rečete, da je minil dan, ko je preteklo 24 ur ali ko se koledar spreminja iz enega dne v drugega. Zdaj bom razpravljal o teh dveh načinih razmišljanja.

Pretečeni čas, primer 1: celotne enote

V tem primeru dan ni potekel, dokler ni minilo 24 ur, ura ni minila, dokler ni minilo 60 minut, minuta ni minila, dokler ni minilo 60 sekund itd. Po tej metodi bi 23 ur pretečenega časa pomenilo nič dni.

Če želite na ta način izračunati pretečeni čas, najprej začnite z izračunom pretečenih milisekund. Če želite to narediti, najprej vsak datum pretvorite v število milisekund od začetka 1. januarja 1970. Nato prvo vrednost milisekunde odštejete od druge milisekunde. Tu je vzorec izračuna:

uvoz java.util. *; javni razred ElapsedMillis {public static void main (String [] args) {GregorianCalendar gc1 = new GregorianCalendar (1995, 11, 1, 3, 2, 1); GregorianCalendar gc2 = nov GregorianCalendar (1995, 11, 1, 3, 2, 2); // zgornja dva datuma sta eno sekundo narazen. Datum d1 = gc1.getTime (); Datum d2 = gc2.getTime (); dolga l1 = d1.getTime (); dolga l2 = d2.getTime (); dolga razlika = l2 - l1; System.out.println ("Pretekle milisekunde:" + razlika); }} 

Zgornji program natisne naslednje:

Pretekle milisekunde: 1000

Ta program povzroča tudi nekaj zmede. The Gregorijanski koledar razredov getTime () vrne a Datum predmet, medtem ko Datum razredov getTime () metoda vrne a dolga število, ki predstavlja milisekunde pred začetkom 1. januarja 1970 ali po njem. Kljub temu da imajo metode isto ime, so njihove vrste vračanja različne!

Milisekunde lahko pretvorite v sekunde z uporabo preproste celoštevilčne delitve, kot v naslednjem fragmentu kode:

dolge milisekunde = 1999; dolge sekunde = 1999/1000; 

Ta način pretvorbe milisekund v sekunde odstrani ulomke, tako da je 1.999 milisekund enako 1 sekundi, 2000 milisekund pa 2 sekundi.

Če želite izračunati večje enote - na primer dneve, ure in minute - glede na število sekund, lahko uporabite naslednji postopek:

  1. Izračunajte največjo enoto in ustrezno zmanjšajte število sekund
  2. Izračunajte naslednjo največjo enoto in ustrezno zmanjšajte število sekund
  3. Ponavljajte, dokler ne ostanejo samo sekunde

Če je na primer pretečeni čas 10.000 sekund in želite vedeti, koliko ur, minut in sekund ustreza tej vrednosti, začnete z največjo vrednostjo: ure. 10.000 delite s 3.600 (sekunde na uro), da izračunate število ur. Z uporabo celoštevilčne delitve je odgovor 2 uri (ulomki se pri celoštevilčni delitvi spustijo). Za izračun preostalih sekund zmanjšajte 10.000 za 3.600 krat 2 uri: 10.000 - (3.600 x 2) = 2.800 sekund. Torej imate 2 uri in 2800 sekund.

Če želite 2.800 sekund pretvoriti v minute, jih 2.800 delite s 60 (sekunde na minuto). Pri celoštevilčni delitvi je odgovor 46. In 2.800 - (60 x 46) = 40 sekund. Končni odgovor je 2 uri, 46 minut in 40 sekund.

Zgornji izračun je prikazan v naslednjem programu Java:

uvoz java.util. *; javni razred Elapsed1 {public void calcHMS (int timeInSeconds) {int ure, minute, sekunde; ur = časInSekunde / 3600; timeInSeconds = timeInSeconds - (ure * 3600); minute = timeInSeconds / 60; timeInSeconds = timeInSeconds - (minute * 60); sekunde = timeInSeconds; System.out.println (ure + "ure (s)" + minute + "minute (s)" + sekunde + "sekunde (s)"); } public static void main (String [] args) {Elapsed1 elap = novo Elapsed1 (); elap.calcHMS (10000); }} 

Rezultat iz zgornjega programa je:

2 uri 46 minut 40 s 40 s

Zgornji program pravilno izračuna število ur, tudi če je pretečeni čas krajši od ene ure. Če na primer uporabite zgornji program za izračun 1.000 sekund, je rezultat:

0 ur 16 minut 40 sekund 40 sekund

Za prikaz resničnega primera naslednji program izračuna pretekli čas na podlagi leta Apollo 11 na Luno:

uvoz java.util. *; javni razred LunarLanding {public long getElapsedSeconds (GregorianCalendar gc1, GregorianCalendar gc2) {Datum d1 = gc1.getTime (); Datum d2 = gc2.getTime (); dolga l1 = d1.getTime (); dolga l2 = d2.getTime (); dolga razlika = Math.abs (l2 - l1); povratna razlika / 1000; } public void calcHM (long timeInSeconds) {dolge ure, minute, sekunde; ur = časInSekunde / 3600; timeInSeconds = timeInSeconds - (ure * 3600); minute = timeInSeconds / 60; System.out.println (ure + "ure (s)" + minute + "minute (s)"); } public static void main (String [] args) {GregorianCalendar lunarLanding = nov GregorianCalendar (1969, Koledar.JULIJ, 20., 16., 17.); GregorianCalendar lunarDeparture = nov GregorianCalendar (1969, Koledar. 21., 13., 54. JULIJ); GregorianCalendar startEVA = nov GregorianCalendar (1969, Koledar. JULIJ, 20., 22., 56); GregorianCalendar endEVA = nov GregorianCalendar (1969, Koledar. JULIJ, 21., 1., 9.); LunarLanding apollo = novo LunarLanding (); dolga eva = apollo.getElapsedSeconds (startEVA, endEVA); System.out.print ("EVA duration ="); apollo.calcHM (eva); long lunarStay = apollo.getElapsedSeconds (lunarLanding, lunarDeparture); System.out.print ("Lunarno bivanje ="); apollo.calcHM (lunarStay); }} 

Rezultat iz zgornjega programa je:

Trajanje EVA = 2 uri 13 minut

Lunino bivanje = 21 ur 37 minut

Do zdaj sem izračune izdeloval na podlagi preprostih formul, kot so: "1 minuta = 60 sekund", "1 ura = 60 minut" in "1 dan = 24 ur."

Kaj pa "1 mesec =? Dni" in "1 leto =? Dni"?

Meseci so lahko sestavljeni iz 28, 29, 30 ali 31 dni; leta lahko 365 ali 366 dni. Zato se težave pojavijo, ko poskušate izračunati polne enote časa za mesece in leta. Če na primer uporabite povprečno število dni v mesecu (približno 30,4375), in število preteklih mesecev izračunate na podlagi naslednjih dveh intervalov:

  • 1. julija od 2:00 do 31. julija do 22:00
  • 1. februarja od 2:00 do 29. februarja ob 22:00

rezultat prvega izračuna bo čez en mesec; rezultat drugega bo čez nič mesecev!

Torej, dobro premislite, preden izračunate pretečeni čas v polnih enotah za mesece in leta.

Pretečeni čas, 2. primer: Sprememba časovne enote

Opredelitev spremembe časovne enote je razmeroma preprosta: če štejete dneve, preprosto štejete, kolikokrat se je datum spremenil. Na primer, če se nekaj začne 15. in konča 17., sta minila 2 dni. (Datum se je najprej spremenil na 16., nato na 17.). Podobno, če se postopek začne ob 3:25 popoldan in konča ob 16:10, je minila 1 ura, ker se je ura enkrat spremenila (s 3 na 4).

Knjižnice pogosto izračunajo čas na ta način. Če si na primer knjigo sposodim v svoji knjižnici, mi knjige ni treba imeti v lasti najmanj 24 ur, da bi jo knjižnica lahko izposodila za en dan. Namesto tega je na moj račun zabeležen dan, ko sem si sposodil knjigo. Takoj, ko se datum preklopi na naslednji dan, sem si knjigo izposodil za en dan, čeprav je čas pogosto krajši od 24 ur.

Pri izračunu pretečenega časa v smislu spremembe časovne enote običajno ni smiselno izračunati več kot ene časovne enote. Če si na primer knjigo iz knjižnice izposodim ob 21.00 in jo vrnem naslednji dan opoldne, lahko izračunam, da sem si knjigo izposodil za en dan. Vendar je malo smisla spraševati: "En dan in koliko ur?" Ker je bila knjiga skupaj izposojena 15 ur, ali je odgovor en dan, negativni pa devet ur? Zato bom za to vadbo izračunal spremembo časovne enote samo za eno enoto časa.

Algoritem za izračun časovne enote spremembe

Tako izračunate časovno enoto spremembe med dvema datumoma:

  1. Naredite kopije obeh datumov. The klon () metoda vam lahko naredi kopije.
  2. Z uporabo kopij datumov nastavite vsa polja, ki so manjša od enote spremembe, na najmanjšo vrednost vsakega polja. Če na primer štejete pretečene dni, nastavite ure, minute, sekunde in milisekunde na nič. V tem primeru uporabite jasno () metoda, da nastavite časovna polja na najnižjo vrednost.
  3. Vzemite prejšnji datum in dodajte enega v polje, ki ga štejete, ponavljajte, dokler nista enaka. Kolikokrat dodate enega, je odgovor. Lahko uporabite pred () in po () metode, ki vrnejo logično vrednost, da preizkusijo, ali je en datum pred ali za drugim datumom.

Naslednji razred ima metode za štetje dni in mesecev.

$config[zx-auto] not found$config[zx-overlay] not found