Programovanie

Práca v čase Java

Tento článok nadväzuje na informácie uvedené v mojom článku Výpočet dátumov Java (JavaWorld, 29.12.2000). Tu som uviedol niektoré kľúčové body z tohto článku, ktoré by vám mali byť známe. Ak vám tieto body nie sú jasné, odporúčam vám prečítať si časť „Výpočet dátumov Java“, kde nájdete ďalšie vysvetlenie.

  1. Java počíta čas v milisekundách pred alebo po začiatku 1. januára 1970.
  2. The Dátum konštruktor triedy Dátum() vráti objekt, ktorý predstavuje okamih, kedy bol objekt vytvorený. Dátumje getTime () metóda vracia a dlho hodnota, ktorej počet sa rovná počtu milisekúnd pred alebo po 1. januári 1970.
  3. The Formát dátumu trieda sa používa na prevod Dátums až Strings, a naopak. Statická getDateInstance () metóda vracia a Formát dátumu objekt v predvolenom formáte; the getDateInstance (DateFormat.FIELD) vracia a Formát dátumu objekt v určenom formáte. The formát (dátum d) metóda vracia a String ktorý predstavuje dátum, napríklad „1. január 2002“. Naopak, analyzovať (reťazce) metóda vracia a Dátum objekt založený na dátume String argument predstavuje.
  4. Vzhľad Strings vrátil formát () Táto metóda sa môže líšiť v závislosti od regionálnych nastavení počítača, na ktorom je program spustený.
  5. The Gregoriánsky kalendár trieda má dva dôležité konštruktory: Gregoriánsky kalendár(), ktorý vracia objekt, ktorý predstavuje okamih, kedy bol vytvorený, a znak GregorianCalendar (int rok, int mesiac, int dátum) konštruktor použitý na vytvorenie objektu, ktorý predstavuje ľubovoľný dátum. The Gregoriánsky kalendár triedy getTime () metóda vracia a Dátum objekt. The pridať (int pole, int suma) metóda počíta dátumy sčítaním alebo odčítaním časových jednotiek, ako sú dni, mesiace alebo roky.

Gregoriánsky kalendár a čas

Dva Gregoriánsky kalendár na prácu s časom je možné použiť konštruktory triedy. Prvý vytvorí objekt, ktorý predstavuje dátum, hodinu a minútu:

GregorianCalendar (int rok, int mesiac, int dátum, int hodina, int minúta) 

Druhý vytvorí objekt, ktorý predstavuje dátum, hodinu, minútu a druhý:

GregorianCalendar (int rok, int mesiac, int dátum, int hodina, int minúta, int sekunda) 

Najprv by som mal poznamenať, že každý konštruktér vyžaduje okrem časových informácií aj údaj o dátume (rok, mesiac a deň). Ak chcete hovoriť o 14:30, musíte uviesť dátum.

Tiež každý Gregoriánsky kalendár konštruktor vytvorí objekt, ktorý predstavuje časový okamih vypočítaný na najbližšiu milisekundu. Ak teda váš konštruktér vezme argumenty iba pre rok, mesiac a dátum, potom sú hodnoty pre hodiny, minúty, sekundy a milisekundy nastavené na nulu. Podobne, ak váš konštruktér vezme argumenty pre rok, mesiac, dátum, hodiny a minúty, potom sú sekundy a milisekundy nastavené na nulu.

Formát dátumu a čas

Ak chcete vytvoriť Formát dátumu objektu na zobrazenie času a dátumu, môžete použiť statickú metódu getDateTimeInstance (int dateStyle, int timeStyle). Táto metóda určuje štýly dátumu a času, ktoré chcete použiť. Ak ste spokojní s predvolenými štýlmi, môžete nahradiť kratšie getDateTimeInstance ().

Ak chcete vytvoriť Formát dátumu objekt zobraziť iba čas, môžete použiť statickú metódu getTimeInstance (int timeStyle).

Nasledujúci program ukazuje, ako getDateTimeInstance () a getTimeInstance () metódy fungujú:

import java.util. *; import java.text. *; public class Apollo {public static void main (String [] args) {GregorianCalendar liftOffApollo11 ​​= nový GregorianCalendar (1969, Calendar.JULY, 16, 9, 32); Dátum d = liftOffApollo11.getTime (); DateFormat df1 = DateFormat.getDateTimeInstance (DateFormat.MEDIUM, DateFormat.MEDIUM); DateFormat df2 = DateFormat.getTimeInstance (DateFormat.SHORT); Reťazec s1 = df1.formát (d); Reťazec s2 = df2.formát (d); System.out.println (s1); System.out.println (s2); }} 

V mojom počítači vyššie uvedený program zobrazuje nasledovné:

16. júla 1969 9:32:00

9:32

(Výstup sa môže líšiť podľa regionálnych nastavení vášho počítača.)

Výpočet uplynulého času

Možno budete niekedy musieť vypočítať uplynulý čas; napríklad možno budete chcieť poznať trvanie výrobného procesu vzhľadom na počiatočný a konečný čas. Požičovňa, ktorá prenajíma predmety za hodinu alebo deň, môže byť tiež užitočné vypočítať uplynulý čas. Podobne vo finančnom svete je často potrebné vypočítať splátky úrokov za uplynulý čas.

Aby sa problém skomplikoval, ľudia vypočítavajú uplynulý čas najmenej dvoma spôsobmi. Môžete povedať, že uplynul jeden deň, keď uplynulo 24 hodín alebo keď sa kalendár mení z jedného dňa na druhý. Teraz rozoberiem tieto dva spôsoby myslenia.

Uplynulý čas, prípad 1: Celé jednotky

V takom prípade neuplynul deň, kým neuplynulo 24 hodín, neuplynula hodina, kým neuplynulo 60 minút, neuplynula minúta, kým neuplynie 60 sekúnd atď. Podľa tejto metódy by sa 23 hodín uplynulého času premietlo do nulových dní.

Ak chcete vypočítať uplynulý čas týmto spôsobom, začnete výpočtom uplynutej milisekundy. Ak to chcete urobiť, najskôr preveďte každý dátum na počet milisekúnd od začiatku 1. januára 1970. Potom odčítate hodnotu prvej milisekundy od hodnoty druhej milisekundy. Tu je ukážka výpočtu:

import java.util. *; public class ElapsedMillis {public static void main (String [] args) {GregorianCalendar gc1 = nový GregorianCalendar (1995, 11, 1, 3, 2, 1); GregorianCalendar gc2 = nový GregorianCalendar (1995, 11, 1, 3, 2, 2); // vyššie uvedené dva dátumy sú od seba vzdialené jednu sekundu Date d1 = gc1.getTime (); Dátum d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); dlhý rozdiel = l2 - l1; System.out.println ("Uplynulé milisekundy:" + rozdiel); }} 

Vyššie uvedený program tlačí nasledujúce:

Uplynulé milisekundy: 1 000

Tento program tiež spôsobuje určité nejasnosti. The Gregoriánsky kalendár triedy getTime () vracia a Dátum objekt, zatiaľ čo Dátum triedy getTime () metóda vracia a dlho číslo predstavujúce milisekundy pred alebo po začiatku 1. januára 1970. Takže aj keď majú metódy rovnaký názov, ich návratové typy sú odlišné!

Milisekundy na sekundy môžete prevádzať pomocou jednoduchého celočíselného delenia, ako v nasledujúcom fragmente kódu:

dlhé milisekundy = 1999; dlhé sekundy = 1999/1000; 

Tento spôsob prepočtu milisekúnd na sekundy eliminuje zlomky, takže 1 999 milisekúnd sa rovná 1 s, zatiaľ čo 2 000 milisekúnd sa rovná 2 sekundám.

Ak chcete vypočítať väčšie jednotky - napríklad dni, hodiny a minúty - dané počtom sekúnd, môžete použiť nasledujúci postup:

  1. Vypočítajte najväčšiu jednotku a podľa toho znížte počet sekúnd
  2. Vypočítajte ďalšiu najväčšiu jednotku a podľa toho znížte počet sekúnd
  3. Opakujte, kým nezostanú iba sekundy

Napríklad, ak je váš uplynulý čas 10 000 sekúnd a chcete vedieť, koľko hodín, minút a sekúnd táto hodnota zodpovedá, začnete s najväčšou hodnotou: hodinami. 10 000 vydelte 3 600 (sekundami za hodinu), aby ste vypočítali počet hodín. Pri použití celočíselného delenia je odpoveď 2 hodiny (zlomky sú vynechané v celočíselnom delení). Ak chcete vypočítať zostávajúce sekundy, znížte 10 000 krát o 3 600 krát za 2 hodiny: 10 000 - (3 600 x 2) = 2 800 sekúnd. Takže máte 2 hodiny a 2 800 sekúnd.

Ak chcete previesť 2 800 sekúnd na minúty, rozdeľte 2 800 na 60 (sekúnd za minútu). Pri celočíselnom delení je odpoveď 46. A 2 800 - (60 x 46) = 40 sekúnd. Konečná odpoveď je 2 hodiny, 46 minút a 40 sekúnd.

Vyššie uvedený výpočet je uvedený v nasledujúcom programe Java:

import java.util. *; public class Elapsed1 {public void calcHMS (int timeInSeconds) {int hodiny, minúty, sekundy; hodiny = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (hodiny * 3600); minúty = timeInSeconds / 60; timeInSeconds = timeInSeconds - (minúty * 60); sekundy = timeInSeconds; System.out.println (hodiny + "hodiny" + minúty + "minúty" + sekundy + "sekundy"); } public static void main (String [] args) {Elapsed1 elap = new Elapsed1 (); elap.calcHMS (10 000); }} 

Výstup z vyššie uvedeného programu je:

2 hodiny 46 minút 40 sekúnd

Vyššie uvedený program správne počíta počet hodín, aj keď je uplynulý čas menej ako hodina. Ak napríklad použijete vyššie uvedený program na výpočet 1 000 sekúnd, výstup bude:

0 hodín 16 minút 40 sekúnd

Nasledujúci program na výpočet príkladu z reálneho sveta počíta uplynulý čas na základe letu Apolla 11 na Mesiac:

import java.util. *; public class LunarLanding {public long getElapsedSeconds (GregorianCalendar gc1, GregorianCalendar gc2) {Dátum d1 = gc1.getTime (); Dátum d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); dlhý rozdiel = Math.abs (l2 - l1); návratový rozdiel / 1000; } public void calcHM (long timeInSeconds) {dlhé hodiny, minúty, sekundy; hodiny = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (hodiny * 3600); minúty = timeInSeconds / 60; System.out.println (hodiny + "hodiny" + minúty + "minúty"); } public static void main (String [] args) {GregorianCalendar lunarLanding = nový GregorianCalendar (1969, Calendar.JULY, 20, 16, 17); GregorianCalendar lunarDeparture = nový GregorianCalendar (1969, Calendar.JULY, 21, 13, 54); GregorianCalendar startEVA = nový GregorianCalendar (1969, Calendar.JULY, 20, 22, 56); GregorianCalendar endEVA = nový GregorianCalendar (1969, Calendar.JULY, 21, 1, 9); LunarLanding apollo = nový LunarLanding (); long eva = apollo.getElapsedSeconds (startEVA, endEVA); System.out.print ("trvanie EVA ="); apollo.calcHM (eva); long lunarStay = apollo.getElapsedSeconds (lunarLanding, lunarDeparture); System.out.print ("Mesačný pobyt ="); apollo.calcHM (lunarStay); }} 

Výstup z vyššie uvedeného programu je:

Trvanie EVA = 2 hodiny 13 minút

Mesačný pobyt = 21 hodín 37 minút

Zatiaľ som robil výpočty na základe jednoduchých vzorcov ako: „1 minúta = 60 sekúnd“, „1 hodina = 60 minút“ a „1 deň = 24 hodín“.

Čo „1 mesiac =? Dni“ a „1 rok =? Dni“?

Mesiace môžu pozostávať z 28, 29, 30 alebo 31 dní; rokov môže byť 365 alebo 366 dní. Preto vznikajú problémy, keď sa pokúsite vypočítať celé časové jednotky mesiacov a rokov. Napríklad ak použijete priemerný počet dní v mesiaci (približne 30,4375) a počet uplynulých mesiacov vypočítate na základe nasledujúcich dvoch intervalov:

  • 1. júla od 02:00 do 31. júla do 22:00
  • 1. 2. od 2.00 do 29. februára, 22:00

výsledkom prvého výpočtu bude 1 mesiac; druhá bude mať za následok nula mesiacov!

Pred výpočtom uplynulého času v celých jednotkách za mesiace a roky teda premýšľajte veľmi opatrne.

Uplynulý čas, prípad 2: Zmena časovej jednotky

Definícia zmeny časovej jednotky je pomerne jednoduchá: Ak počítate dni, stačí spočítať, koľkokrát sa dátum zmenil. Ak napríklad niečo začína 15. a končí 17., uplynuli 2 dni. (Dátum sa zmenil najskôr na 16., potom na 17. deň.) Podobne, ak proces začína o 3:25 popoludní a končí o 16:10, prešla 1 hodina, pretože hodina sa zmenila raz (z 3 na 4).

Knižnice týmto spôsobom často počítajú čas. Ak si napríklad požičiavam knihu zo svojej knižnice, nemusím mať knihu v držbe minimálne 24 hodín, aby ju knižnica mohla považovať za vypožičanú na jeden deň. Namiesto toho je na môj účet zaznamenaný deň, keď si knihu požičiam. Len čo sa dátum prepne na ďalší deň, knihu som si na jeden deň požičal, aj keď čas je často menší ako 24 hodín.

Pri výpočte uplynulého času v zmysle zmeny časových jednotiek zvyčajne nemá zmysel počítať viac ako jednu časovú jednotku. Napríklad, ak si požičiam knihu z knižnice o 21:00 a vrátim ju nasledujúci deň na poludnie, môžem vypočítať, že som si knihu požičal na jeden deň. Nemá však zmysel pýtať sa: „Jedného dňa a koľko hodín?“ Keďže kniha bola zapožičaná celkovo na 15 hodín, je odpoveď jeden deň a záporná deväť hodín? Preto pre tento tutoriál budem počítať zmenu časových jednotiek iba pre jednu časovú jednotku.

Algoritmus pre výpočet časovej jednotky zmeny

Takto vypočítate časovú jednotku zmeny medzi dvoma dátumami:

  1. Vytvorte kópie týchto dvoch dátumov. The klon () metóda vám môže vytvoriť kópie.
  2. Pomocou kópií dátumov nastavte všetky polia, ktoré sú menšie ako jednotka zmeny, na minimálnu hodnotu každého poľa. Napríklad ak počítate uplynulé dni, potom nastavte hodiny, minúty, sekundy a milisekundy na nulu. V takom prípade použite jasný() metóda nastavenia časových polí na ich najnižšiu hodnotu.
  3. Vezmite skorší dátum a pridajte jeden do poľa, ktoré počítate, a opakujte, kým sa tieto dva dátumy nerovnajú. Koľko krát pridáte jeden, je odpoveďou. Môžete použiť pred () a po () metódy, ktoré vracajú logickú hodnotu, na otestovanie, či je jeden dátum pred alebo po inom dátume.

Nasledujúca trieda obsahuje metódy počítania dní a mesiacov.

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