Programmering

Arbejder i Java-tid

Denne artikel bygger på de oplysninger, der præsenteres i min artikel om beregning af Java-datoer (JavaWorld, 29. december 2000). Her har jeg nævnt nogle nøglepunkter fra den artikel, der burde være kendt for dig. Hvis disse punkter ikke er klare for dig, anbefaler jeg, at du læser "Beregning af Java-datoer" for yderligere forklaring.

  1. Java regner tid i millisekunder før eller efter starten af ​​1. januar 1970.
  2. Det Dato klassens konstruktør Dato() returnerer et objekt, der repræsenterer det øjeblik objektet blev oprettet. Dato's getTime () metode returnerer a lang værdi, hvis antal er lig med antallet af millisekunder før eller efter 1. januar 1970.
  3. Det Datoformat klasse bruges til at konvertere Datos til Snors og omvendt. Det statiske getDateInstance () metode returnerer a Datoformat objekt i standardformatet; det getDateInstance (DateFormat.FIELD) returnerer a Datoformat objekt med et specificeret format. Det format (dato d) metode returnerer a Snor der repræsenterer datoen, såsom "1. januar 2002." Omvendt parse (streng s) metode returnerer a Dato objekt baseret på datoen den Snor argument repræsenterer.
  4. Udseendet af Snors returneret af format() metoden kan variere alt efter de regionale indstillinger på den computer, hvor programmet køres.
  5. Det Gregoriansk kalender klasse har to vigtige konstruktører: Gregoriansk kalender (), som returnerer et objekt, der repræsenterer det øjeblik det blev oprettet, og GregorianCalendar (int år, int måned, int dato) konstruktør bruges til at oprette et objekt, der repræsenterer en vilkårlig dato. Det Gregoriansk kalender klassens getTime () metode returnerer a Dato objekt. Det tilføj (int-felt, int-beløb) metoden beregner datoer ved at tilføje eller trække tidsenheder som dage, måneder eller år.

Gregoriansk kalender og tid

To Gregoriansk kalender klassekonstruktører kan bruges til at håndtere tid. Den første opretter et objekt, der repræsenterer en dato, en time og et minut:

GregorianCalendar (int år, int måned, int dato, int time, int minut) 

Det andet opretter et objekt, der repræsenterer en dato, time, minut og sekund:

GregorianCalendar (int år, int måned, int dato, int time, int minut, int sekund) 

Først skal jeg bemærke, at hver konstruktør kræver datooplysninger (år, måned og dag) ud over tidsinformation. Hvis du vil tale om kl. 14.30, skal du angive datoen.

Også hver Gregoriansk kalender konstruktør opretter et objekt, der repræsenterer et øjeblik i tid beregnet til nærmeste millisekund. Således, hvis din konstruktør kun tager argumenter for år, måned og dato, så er værdierne for timer, minutter, sekunder og millisekunder indstillet til nul. Tilsvarende, hvis din konstruktør tager argumenter for år, måned, dato, timer og minutter, så er sekunder og millisekunder sat til nul.

Datoformat og klokkeslæt

At oprette en Datoformat mod at vise tid og dato, kan du bruge den statiske metode getDateTimeInstance (int dateStyle, int timeStyle). Denne metode specificerer dato og klokkeslæt, du ønsker at bruge. Hvis du er tilfreds med standardformaterne, kan du erstatte den kortere getDateTimeInstance ().

At oprette en Datoformat objekt til kun at vise tiden, kan du bruge den statiske metode getTimeInstance (int timeStyle).

Programmet nedenfor viser, hvordan getDateTimeInstance () og getTimeInstance () metoder fungerer:

importer java.util. *; importer java.text. *; offentlig klasse Apollo {public static void main (String [] args) {GregorianCalendar liftOffApollo11 ​​= new GregorianCalendar (1969, Calendar. JULI, 16, 9, 32); Dato d = liftOffApollo11.getTime (); DateFormat df1 = DateFormat.getDateTimeInstance (DateFormat.MEDIUM, DateFormat.MEDIUM); DateFormat df2 = DateFormat.getTimeInstance (DateFormat.SHORT); Streng s1 = df1.format (d); Streng s2 = df2.format (d); System.out.println (s1); System.out.println (s2); }} 

På min computer viser ovenstående program følgende:

16. juli 1969 09:32:00

9:32

(Output kan variere alt efter din computers regionale indstillinger.)

Beregning af forløbet tid

Det kan være nødvendigt at du beregner forløbet tid; for eksempel vil du måske vide varigheden af ​​en fremstillingsproces, givet start- og sluttiderne. Et udlejningsfirma, der lejer varer pr. Time eller dag, kan også finde det nyttigt at beregne forløbet tid. Tilsvarende er det ofte nødvendigt i den finansielle verden at beregne rentebetalinger over forløbet tid.

For at komplicere problemet beregner mennesker den forløbne tid på mindst to måder. Du kan sige, at en dag er gået, når der er gået 24 timer, eller når kalenderen skifter fra en dag til den næste. Jeg vil nu diskutere disse to måder at tænke på.

Forløbet tid, sag 1: Fuld enheder

I dette tilfælde er der ikke gået en dag, før der er gået 24 timer, en time er ikke gået, før der er gået 60 minutter, et minut er ikke gået, før der er gået 60 sekunder osv. I henhold til denne metode vil 23 timers forløbet tid oversætte til nul dage.

For at beregne forløbet tid på denne måde starter du med at beregne forløbne millisekunder. For at gøre dette skal du først konvertere hver dato til antallet af millisekunder siden starten af ​​1. januar 1970. Du trækker derefter den første millisekundværdi fra den anden millisekundværdi. Her er en prøveberegning:

importer java.util. *; offentlig klasse ElapsedMillis {public static void main (String [] args) {GregorianCalendar gc1 = new GregorianCalendar (1995, 11, 1, 3, 2, 1); GregorianCalendar gc2 = ny GregorianCalendar (1995, 11, 1, 3, 2, 2); // ovenstående to datoer er et sekund fra hinanden Dato d1 = gc1.getTime (); Dato d2 = gc2.getTime (); lang l1 = d1.getTime (); lang l2 = d2.getTime (); lang forskel = l2 - l1; System.out.println ("Forløbne millisekunder:" + forskel); }} 

Ovenstående program udskriver følgende:

Forløbne millisekunder: 1000

Dette program medfører også en vis forvirring. Det Gregoriansk kalender klassens getTime () returnerer a Dato objekt, mens Dato klassens getTime () metode returnerer a lang nummer, der repræsenterer millisekunder før eller efter begyndelsen af ​​1. januar 1970. Så selvom metoderne har samme navn, er deres returtyper forskellige!

Du kan konvertere millisekunder til sekunder ved hjælp af simpel heltalsdeling, som i følgende kodefragment:

lange millisekunder = 1999; lange sekunder = 1999/1000; 

Denne måde at konvertere millisekunder til sekunder eliminerer brøker, så 1.999 millisekunder er lig med 1 sekund, mens 2.000 millisekunder er lig med 2 sekunder.

For at beregne større enheder - såsom dage, timer og minutter - givet et antal sekunder, kan du bruge følgende proces:

  1. Beregn den største enhed, reducer antallet af sekunder i overensstemmelse hermed
  2. Beregn den næststørste enhed, reducer antallet af sekunder i overensstemmelse hermed
  3. Gentag, indtil der kun er sekunder tilbage

For eksempel, hvis din forløbne tid er 10.000 sekunder, og du vil vide, hvor mange timer, minutter og sekunder denne værdi svarer til, starter du med den største værdi: timer. Opdel 10.000 med 3.600 (sekunder på en time) for at beregne antal timer. Ved hjælp af heltalsdeling er svaret 2 timer (brøker slettes i heltalsdeling). For at beregne de resterende sekunder skal du reducere 10.000 med 3.600 gange 2 timer: 10.000 - (3.600 x 2) = 2.800 sekunder. Så du har 2 timer og 2.800 sekunder.

For at konvertere 2.800 sekunder til minutter, divider 2.800 med 60 (sekunder pr. Minut). Med heltalsdeling er svaret 46. Og 2.800 - (60 x 46) = 40 sekunder. Det endelige svar er 2 timer, 46 minutter og 40 sekunder.

Ovenstående beregning vises i følgende Java-program:

importer java.util. *; public class Elapsed1 {public void calcHMS (int timeInSeconds) {int hours, minutes, seconds; timer = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (timer * 3600); minutter = timeInSeconds / 60; timeInSeconds = timeInSeconds - (minutter * 60); sekunder = timeInSeconds; System.out.println (timer + "time (r)" + minutter + "minut (er)" + sekunder + "sekund (er)"); } offentlig statisk ugyldig hoved (String [] args) {Elapsed1 elap = new Elapsed1 (); elap.calcHMS (10000); }} 

Output fra ovenstående program er:

2 time (r) 46 minut (er) 40 sekund (er)

Ovenstående program beregner antal timer korrekt, selv når den forløbne tid er mindre end en time. Hvis du f.eks. Bruger ovenstående program til at beregne 1.000 sekunder, er output:

0 time (r) 16 minutter 40 sekunder

For at vise et virkeligt eksempel beregner følgende program forløbet tid baseret på Apollo 11-flyvningen til månen:

importer java.util. *; offentlig klasse LunarLanding {public long getElapsedSeconds (GregorianCalendar gc1, GregorianCalendar gc2) {Date d1 = gc1.getTime (); Dato d2 = gc2.getTime (); lang l1 = d1.getTime (); lang l2 = d2.getTime (); lang forskel = Math.abs (l2 - l1); returforskel / 1000; } public void calcHM (long timeInSeconds) {lange timer, minutter, sekunder; timer = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (timer * 3600); minutter = timeInSeconds / 60; System.out.println (timer + "time (r)" + minutter + "minut (er)"); } public static void main (String [] args) {GregorianCalendar lunarLanding = new GregorianCalendar (1969, Calendar. JULI, 20, 16, 17); GregorianCalendar lunarDeparture = ny GregorianCalendar (1969, kalender. JULI, 21, 13, 54); GregorianCalendar startEVA = ny GregorianCalendar (1969, kalender. JULI, 20, 22, 56); GregorianCalendar endEVA = ny GregorianCalendar (1969, kalender. JULI, 21, 1, 9); LunarLanding apollo = ny LunarLanding (); lang eva = apollo.getElapsedSeconds (startEVA, endEVA); System.out.print ("EVA-varighed ="); apollo.calcHM (eva); lang lunarStay = apollo.getElapsedSeconds (lunarLanding, lunarDeparture); System.out.print ("Lunar stay ="); apollo.calcHM (lunarStay); }} 

Output fra ovenstående program er:

EVA-varighed = 2 time (r) 13 minutter

Månens ophold = 21 time (r) 37 minutter

Indtil videre har jeg foretaget beregninger baseret på enkle formler som: "1 minut = 60 sekunder," "1 time = 60 minutter" og "1 dag = 24 timer."

Hvad med "1 måned =? Dage" og "1 år =? Dage"?

Måneder kan bestå af 28, 29, 30 eller 31 dage; år kan være 365 eller 366 dage. Derfor opstår der problemer, når du prøver at beregne fulde tidsenheder i måneder og år. For eksempel, hvis du bruger det gennemsnitlige antal dage i en måned (ca. 30.4375), og du beregner antallet af forløbne måneder baseret på følgende to intervaller:

  • 1. juli, 02:00 til 31. juli, 10:00
  • 1. februar, 02:00 til 29. februar, 10:00

den første beregning vil resultere i 1 måned; det andet vil resultere i nul måneder!

Så tænk meget grundigt, inden du beregner forløbet tid i fulde enheder i måneder og år.

Forløbet tid, sag 2: Ændring af tidsenhed

Definitionen af ​​tidsenhedsændring er relativt enkel: Hvis du tæller dage, tæller du blot antallet af gange datoen er ændret. For eksempel, hvis noget starter den 15. og slutter den 17., er der gået 2 dage. (Datoen blev først ændret til den 16. og derefter til den 17.) Hvis en proces starter kl. 3:25 om eftermiddagen og slutter kl. 16:10, er der ligeledes gået 1 time, fordi timen har ændret sig en gang (fra 3 til 4).

Biblioteker beregner ofte tid på denne måde. For eksempel, hvis jeg låner en bog fra mit bibliotek, behøver jeg ikke at have bogen i min besiddelse i mindst 24 timer for, at biblioteket kan betragte den som lånt i en dag. I stedet registreres den dag, jeg låner bogen, på min konto. Så snart datoen skifter til den næste dag, har jeg lånt bogen i en dag, selvom tiden ofte er mindre end 24 timer.

Ved beregning af forløbet tid i betydningen tidsenhedsændring giver det normalt ikke mening at beregne mere end en tidsenhed. For eksempel, hvis jeg låner en biblioteksbog kl. 21:00 og returnerer den næste dag kl. 12, kan jeg beregne, at jeg har lånt bogen i en dag. Der er dog ringe mening i at spørge: "En dag og hvor mange timer?" Da bogen blev lånt i alt 15 timer, er svaret en dag og negativt ni timer? Derfor beregner jeg tidsændring for denne vejledning kun for en tidsenhed.

Algoritme til beregning af tidsenhedsændring

Sådan beregner du tidsenheden for ændring mellem to datoer:

  1. Lav kopier af de to datoer. Det klon () metode kan lave kopier til dig.
  2. Brug kopierne af datoerne til at indstille alle felter, der er mindre end ændringsenheden, til hvert felts minimumsværdi. Hvis du f.eks. Tæller forløbne dage, skal du indstille timer, minutter, sekunder og millisekunder til nul. I dette tilfælde skal du bruge klar() metode til at indstille tidsfelter til deres laveste værdi.
  3. Tag den tidligere dato, og tilføj en til det felt, du tæller, og gentag, indtil de to datoer er ens. Antallet af gange du tilføjer en er svaret. Du kan bruge Før() og efter() metoder, som returnerer en boolsk værdi, for at teste, om en dato er før eller efter en anden dato.

Den følgende klasse har metoder til at tælle dage og måneder.