Programování

Práce v Javě

Tento článek navazuje na informace uvedené v mém článku Výpočet dat Java (JavaWorld, 29. prosince 2000). Zde jsem uvedl několik klíčových bodů z tohoto článku, které by vám měly být známé. Pokud vám tyto body nejsou jasné, doporučuji vám přečíst „Výpočet dat Java“ pro další vysvětlení.

  1. Java počítá s časem v milisekundách před nebo po začátku 1. ledna 1970.
  2. The datum konstruktor třídy Datum() vrací objekt, který představuje okamžik, kdy byl objekt vytvořen. datumje getTime () metoda vrací a dlouho hodnota, jejíž počet se rovná počtu milisekund před nebo po 1. lednu 1970.
  3. The Datový formát třída se používá k převodu datums až Tětivas a naopak. Statická getDateInstance () metoda vrací a Datový formát objekt ve výchozím formátu; the getDateInstance (DateFormat.FIELD) vrací a Datový formát objekt se zadaným formátem. The formát (datum d) metoda vrací a Tětiva který představuje datum, například „1. ledna 2002“. Naopak analyzovat (řetězce) metoda vrací a datum objekt založený na datu Tětiva argument představuje.
  4. Vzhled Tětivas vrácen formát() metoda se může lišit podle regionálního nastavení v počítači, kde je program spuštěn.
  5. The Gregoriánský kalendář třída má dva důležité konstruktory: Gregoriánský kalendář(), který vrací objekt, který představuje okamžik, kdy byl vytvořen, a GregorianCalendar (int rok, int měsíc, int datum) konstruktor použitý k vytvoření objektu, který představuje libovolné datum. The Gregoriánský kalendář třídy getTime () metoda vrací a datum objekt. The přidat (int pole, int částka) metoda vypočítá data přidáním nebo odečtením jednotek času, jako jsou dny, měsíce nebo roky.

GregorianCalendar a čas

Dva Gregoriánský kalendář konstruktory třídy lze použít k řešení času. První vytvoří objekt, který představuje datum, hodinu a minutu:

GregorianCalendar (int rok, int měsíc, int datum, int hodina, int minuta) 

Druhý vytvoří objekt, který představuje datum, hodinu, minutu a sekundu:

GregorianCalendar (int rok, int měsíc, int datum, int hodina, int minuta, int sekunda) 

Nejprve bych měl poznamenat, že každý konstruktor vyžaduje kromě časových informací také informace o datu (rok, měsíc a den). Pokud chcete mluvit o 14:30, musíte zadat datum.

Také každý Gregoriánský kalendář konstruktor vytvoří objekt, který představuje časový okamžik vypočítaný na nejbližší milisekundu. Pokud tedy váš konstruktér přebírá argumenty pouze pro rok, měsíc a datum, jsou hodnoty hodin, minut, sekund a milisekund nastaveny na nulu. Podobně, pokud váš konstruktér vezme argumenty pro rok, měsíc, datum, hodiny a minuty, pak jsou sekundy a milisekundy nastaveny na nulu.

DateFormat a čas

Chcete-li vytvořit Datový formát objekt k zobrazení času a data, můžete použít statickou metodu getDateTimeInstance (int dateStyle, int timeStyle). Tato metoda určuje styly data a času, které chcete použít. Pokud jste spokojeni s výchozími styly, můžete nahradit kratší getDateTimeInstance ().

Chcete-li vytvořit Datový formát objekt zobrazit jen čas, můžete použít statickou metodu getTimeInstance (int timeStyle).

Níže uvedený program ukazuje, jak getDateTimeInstance () a getTimeInstance () metody práce:

import java.util. *; importovat java.text. *; public class Apollo {public static void 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); Řetězec s1 = df1.formát (d); Řetězec s2 = df2.formát (d); System.out.println (s1); System.out.println (s2); }} 

Výše uvedený program na mém počítači zobrazuje následující:

16. července 1969 9:32:00

9:32

(Výstup se může lišit podle regionálního nastavení vašeho počítače.)

Výpočet uplynulého času

Někdy budete možná muset vypočítat uplynulý čas; například možná budete chtít znát dobu trvání výrobního procesu vzhledem k počáteční a koncové době. Také může být užitečné vypočítat uplynulý čas v půjčovně, která pronajímá položky za hodinu nebo den. Podobně ve finančním světě je často nutné počítat splátky úroků za uplynulý čas.

Aby se problém vyřešil, vypočítávají lidé uplynulý čas alespoň dvěma způsoby. Můžete říci, že den uplynul, když uplynulo 24 hodin, nebo když se kalendář změní ze dne na den. Nyní budu diskutovat o těchto dvou způsobech myšlení.

Uplynulý čas, případ 1: Plné jednotky

V tomto případě neuplynul den, dokud neuplynulo 24 hodin, neuplynula hodina, dokud neuplynulo 60 minut, minuta neuplynula, dokud neuplynulo 60 sekund atd. Podle této metody by 23 hodin uplynulého času znamenalo nula dní.

Chcete-li vypočítat uplynulý čas tímto způsobem, začnete výpočtem uplynulých milisekund. Chcete-li tak učinit, nejprve převeďte každé datum na počet milisekund od začátku 1. ledna 1970. Poté odečtěte hodnotu první milisekundy od hodnoty druhé milisekundy. Zde je ukázkový výpočet:

import java.util. *; public class 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); // výše uvedená dvě data jsou od sebe vzdálena jednu sekundu Date d1 = gc1.getTime (); Datum d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); dlouhý rozdíl = l2 - l1; System.out.println ("Uplynulé milisekundy:" + rozdíl); }} 

Výše uvedený program vytiskne následující:

Uplynulé milisekundy: 1000

Tento program také způsobuje určité nejasnosti. The Gregoriánský kalendář třídy getTime () vrací a datum objekt, zatímco datum třídy getTime () metoda vrací a dlouho číslo představující milisekundy před nebo po začátku 1. ledna 1970. Takže i když mají metody stejný název, jejich návratové typy se liší!

Milisekundy na sekundy můžete převést pomocí jednoduchého celočíselného dělení, jako v následujícím fragmentu kódu:

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

Tento způsob převodu milisekund na sekundy vylučuje zlomky, takže 1 999 milisekund se rovná 1 sekundě, zatímco 2 000 milisekund se rovná 2 sekundám.

Chcete-li vypočítat větší jednotky - například dny, hodiny a minuty - vzhledem k počtu sekund, můžete použít následující postup:

  1. Vypočítejte největší jednotku a odpovídajícím způsobem snižte počet sekund
  2. Vypočítejte další největší jednotku a odpovídajícím způsobem snižte počet sekund
  3. Opakujte, dokud nezůstanou jen sekundy

Například pokud je váš uplynulý čas 10 000 sekund a chcete vědět, kolik hodin, minut a sekund odpovídá tato hodnota, začněte s největší hodnotou: hodin. Rozdělte 10 000 na 3 600 (sekundy za hodinu) a vypočítejte počet hodin. Při použití celočíselného dělení je odpověď 2 hodiny (zlomky jsou vynechány v celočíselném dělení). Chcete-li vypočítat zbývající sekundy, snižte 10 000 o 3 600krát za 2 hodiny: 10 000 - (3 600 x 2) = 2 800 sekund. Takže máte 2 hodiny a 2 800 sekund.

Chcete-li převést 2 800 sekund na minuty, rozdělte 2 800 na 60 (sekundy za minutu). Při celočíselném dělení je odpověď 46. A 2 800 - (60 x 46) = 40 sekund. Konečná odpověď je 2 hodiny, 46 minut a 40 sekund.

Výše uvedený výpočet je uveden v následujícím programu Java:

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

Výstup z výše uvedeného programu je:

2 hodiny 46 minut 40 sekund

Výše uvedený program vypočítá počet hodin správně, i když je uplynulý čas kratší než hodina. Pokud například použijete výše uvedený program k výpočtu 1 000 sekund, výstup bude:

0 hodin 16 minut 40 sekund

Chcete-li ukázat příklad ze skutečného světa, následující program vypočítá uplynulý čas na základě letu Apolla 11 na Měsíc:

import java.util. *; public class LunarLanding {public long getElapsedSeconds (GregorianCalendar gc1, GregorianCalendar gc2) {Datum d1 = gc1.getTime (); Datum d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); dlouhý rozdíl = Math.abs (l2 - l1); návratový rozdíl / 1000; } public void calcHM (long timeInSeconds) {dlouhé hodiny, minuty, sekundy; hodiny = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (hodiny * 3600); minut = timeInSeconds / 60; System.out.println (hodiny + "hodiny" + minuty + "minuty"); } public static void main (String [] args) {GregorianCalendar lunarLanding = new 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 ("doba trvání EVA ="); apollo.calcHM (eva); long lunarStay = apollo.getElapsedSeconds (lunarLanding, lunarDeparture); System.out.print ("Lunar stay ="); apollo.calcHM (lunarStay); }} 

Výstup z výše uvedeného programu je:

Doba trvání EVA = 2 hodiny 13 minut

Měsíční pobyt = 21 hodin 37 minut

Doposud jsem provedl výpočty na základě jednoduchých vzorců jako: „1 minuta = 60 sekund“, „1 hodina = 60 minut“ a „1 den = 24 hodin“.

A co „1 měsíc =? Dny“ a „1 rok =? Dny“?

Měsíce se mohou skládat z 28, 29, 30 nebo 31 dnů; let může být 365 nebo 366 dní. Problémy tedy vznikají, když se pokoušíte vypočítat celé jednotky času za měsíce a roky. Například pokud použijete průměrný počet dní v měsíci (přibližně 30,4375) a vypočítáte počet uplynulých měsíců na základě následujících dvou intervalů:

  • 1. července, 2:00 až 31. července, 22:00
  • 1. února, 2:00 - 29. února, 22:00

první výpočet bude mít za 1 měsíc; druhý způsobí nula měsíců!

Než tedy vypočítáte uplynulý čas v celých jednotkách za měsíce a roky, zvažte to velmi pečlivě.

Uplynulý čas, případ 2: Změna časové jednotky

Definice změny časové jednotky je poměrně jednoduchá: Pokud počítáte dny, jednoduše spočítejete, kolikrát se datum změnilo. Například pokud něco začíná 15. a končí 17., uplynuly 2 dny. (Datum se změnilo nejprve na 16., poté na 17.) Podobně, pokud proces začíná v 3:25 odpoledne a končí v 16:10, uběhla 1 hodina, protože hodina se jednou změnila (ze 3 na 4).

Knihovny často počítají čas tímto způsobem. Například pokud si půjčím knihu ze své knihovny, nemusím mít knihu v držení minimálně 24 hodin, aby ji knihovna mohla považovat za vypůjčenou na jeden den. Místo toho je na můj účet zaznamenán den, kdy si knihu půjčím. Jakmile se datum přepne na další den, knihu jsem si vypůjčil na jeden den, i když čas je často menší než 24 hodin.

Při výpočtu uplynulého času ve smyslu změny časové jednotky nemá obvykle smysl počítat více než jednu jednotku času. Například pokud si půjčím knihu z knihovny v 21:00 a vrátím ji další den v poledne, mohu spočítat, že jsem si knihu vypůjčil na jeden den. Nemá však smysl ptát se: „Jednoho dne a kolik hodin?“ Jelikož byla kniha zapůjčena celkem na 15 hodin, je odpověď jeden den a záporná devět hodin? Proto pro tento výukový program vypočítám změnu časové jednotky pouze pro jednu jednotku času.

Algoritmus pro výpočet časové jednotky změny

Takto vypočítáte časovou jednotku změny mezi dvěma daty:

  1. Vytvořte kopie těchto dvou dat. The klon () metoda vám může vytvořit kopie.
  2. Pomocí kopií dat nastavte všechna pole, která jsou menší než jednotka změny, na minimální hodnotu každého pole. Pokud například počítáte uplynulé dny, nastavte hodiny, minuty, sekundy a milisekundy na nulu. V tomto případě použijte Průhledná() metoda nastavení časových polí na jejich nejnižší hodnotu.
  3. Vezměte dřívější datum a přidejte jedno do pole, které počítáte, a opakujte, dokud nebudou dvě data stejná. Kolikrát jeden přidáte, je odpověď. Můžete použít před() a po() metody, které vracejí logickou hodnotu, k otestování, zda je jedno datum před nebo po jiném datu.

Následující třída má metody pro počítání dnů a měsíců.