Programmering

Jobber i Java-tid

Denne artikkelen bygger på informasjonen som presenteres i artikkelen min Beregner Java-datoer (JavaWorld, 29. desember 2000). Her har jeg listet opp noen viktige punkter fra den artikkelen som skal være kjent for deg. Hvis disse punktene ikke er klare for deg, anbefaler jeg at du leser "Beregne Java-datoer" for nærmere forklaring.

  1. Java regner tid i millisekunder før eller etter starten av 1. januar 1970.
  2. De Dato klassens konstruktør Dato() returnerer et objekt som representerer øyeblikket objektet ble opprettet. Datos getTime () metoden returnerer a lang verdi hvis antall tilsvarer antall millisekunder før eller etter 1. januar 1970.
  3. De DateFormat klasse brukes til å konvertere Datos til Strings, og omvendt. Det statiske getDateInstance () metoden returnerer a DateFormat objekt i standardformat; de getDateInstance (DateFormat.FIELD) returnerer a DateFormat objekt med et spesifisert format. De format (dato d) metoden returnerer a String som representerer datoen, for eksempel "1. januar 2002." Omvendt, den analyse (streng s) metoden returnerer a Dato objekt basert på datoen String argument representerer.
  4. Utseendet til Strings returnert av format() metoden kan variere i henhold til de regionale innstillingene på datamaskinen der programmet kjøres.
  5. De Gregorianske kalender klassen har to viktige konstruktører: Gregorianske kalender(), som returnerer et objekt som representerer øyeblikket det ble opprettet, og GregorianCalendar (int år, int måned, int dato) konstruktør brukes til å lage et objekt som representerer en vilkårlig dato. De Gregorianske kalender klassen getTime () metoden returnerer a Dato gjenstand. De legg til (int-felt, int-beløp) metoden beregner datoer ved å legge til eller trekke fra tidsenheter som dager, måneder eller år.

Gregoriansk kalender og tid

To Gregorianske kalender klassekonstruktører kan brukes til å håndtere tid. Den første oppretter et objekt som representerer en dato, time og minutt:

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

Det andre oppretter et objekt som representerer en dato, time, minutt og sekund:

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

Først bør jeg merke meg at hver konstruktør krever datoinformasjon (år, måned og dag) i tillegg til tidsinformasjon. Hvis du vil snakke om 14:30, må du spesifisere datoen.

Også hver Gregorianske kalender konstruktør oppretter et objekt som representerer et øyeblikk beregnet til nærmeste millisekund. Hvis konstruktøren din bare tar argumenter for bare året, måneden og datoen, blir verdiene for timer, minutter, sekunder og millisekunder satt til null. Tilsvarende, hvis konstruktøren tar argumenter for år, måned, dato, timer og minutter, så er sekunder og millisekunder satt til null.

Datoformat og klokkeslett

Å lage en DateFormat objekt for å vise tid og dato, kan du bruke den statiske metoden getDateTimeInstance (int dateStyle, int timeStyle). Denne metoden spesifiserer dato og klokkeslett du vil bruke. Hvis du er fornøyd med standardstilene, kan du erstatte den kortere getDateTimeInstance ().

Å lage en DateFormat objektet for å vise akkurat den tiden, kan du bruke den statiske metoden getTimeInstance (int timeStyle).

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

importer java.util. *; importer java.text. *; public class 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å datamaskinen min viser programmet ovenfor følgende:

16. juli 1969 09:32:00

9:32

(Output kan variere avhengig av datamaskinens regionale innstillinger.)

Beregning av forløpt tid

Noen ganger må du kanskje beregne forløpt tid; for eksempel vil du kanskje vite varigheten av en produksjonsprosess, gitt start- og sluttider. Et utleieselskap som leier varer etter time eller dag, kan også finne det nyttig å beregne forløpt tid. På samme måte er det ofte i finansverdenen nødvendig å beregne rentebetalinger over forløpt tid.

For å komplisere problemet beregner mennesker forløpt tid på minst to måter. Du kan si at en dag har gått da det har gått 24 timer, eller når kalenderen endres fra en dag til den neste. Jeg skal nå diskutere de to måtene å tenke på.

Forløpt tid, sak 1: Fulle enheter

I dette tilfellet har det ikke gått en dag før 24 timer har gått, en time har ikke gått før 60 minutter har gått, et minutt har ikke gått før 60 sekunder har gått, og så videre. I henhold til denne metoden vil 23 timer medgått tid bli null dager.

For å beregne forløpt tid på denne måten starter du med å beregne forløpne millisekunder. For å gjøre det må du først konvertere hver dato til antall millisekunder siden begynnelsen av 1. januar 1970. Deretter trekker du den første millisekundverdien fra den andre millisekundverdien. Her er et eksempel på beregning:

importer java.util. *; public class 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); // de to ovennevnte datoene er ett sekund fra hverandre Dato d1 = gc1.getTime (); Dato d2 = gc2.getTime (); lang l1 = d1.getTime (); lang l2 = d2.getTime (); lang forskjell = l2 - l1; System.out.println ("Forløpne millisekunder:" + forskjell); }} 

Ovennevnte program skriver ut følgende:

Forløpne millisekunder: 1000

Dette programmet gir også litt forvirring. De Gregorianske kalender klassen getTime () returnerer a Dato objekt, mens Dato klassen getTime () metoden returnerer a lang nummer som representerer millisekundene før eller etter begynnelsen av 1. januar 1970. Så selv om metodene har samme navn, er returtypene forskjellige!

Du kan konvertere millisekunder til sekunder ved hjelp av enkel heltallsdeling, som i følgende kodefragment:

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

Den måten å konvertere millisekunder til sekunder, eliminerer brøker, så 1,999 millisekunder tilsvarer 1 sekund, mens 2000 millisekunder tilsvarer 2 sekunder.

For å beregne større enheter - som dager, timer og minutter - gitt et antall sekunder, kan du bruke følgende prosess:

  1. Beregn den største enheten, og reduser antall sekunder tilsvarende
  2. Beregn den nest største enheten, og reduser antall sekunder tilsvarende
  3. Gjenta til bare sekunder er igjen

For eksempel, hvis den forløpte tiden din er 10 000 sekunder, og du vil vite hvor mange timer, minutter og sekunder denne verdien tilsvarer, begynner du med den største verdien: timer. Del 10 000 med 3600 (sekunder på en time) for å beregne antall timer. Ved å bruke heltallsdeling er svaret 2 timer (brøker slippes i heltallsdeling). For å beregne de resterende sekundene, reduser du 10.000 med 3.600 ganger 2 timer: 10.000 - (3.600 x 2) = 2.800 sekunder. Så du har 2 timer og 2800 sekunder.

For å konvertere 2800 sekunder til minutter, del 2800 med 60 (sekunder per minutt). Med heltallsdeling er svaret 46. Og 2800 - (60 x 46) = 40 sekunder. Det endelige svaret er 2 timer, 46 minutter og 40 sekunder.

Ovenstående beregning er vist 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 + "minutt (er)" + sekunder + "sekund (er)"); } public static void main (String [] args) {Elapsed1 elap = new Elapsed1 (); elap.calcHMS (10000); }} 

Resultatet fra programmet ovenfor er:

2 time (r) 46 minutt (er) 40 sekunder

Ovennevnte program beregner antall timer riktig, selv når forløpt tid er mindre enn en time. Hvis du for eksempel bruker programmet ovenfor for å beregne 1000 sekunder, er utdataene:

0 time (r) 16 minutt (er) 40 sekunder

For å vise et eksempel fra den virkelige verden, beregner følgende program forløpt tid basert på Apollo 11-flyet 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 forskjell = Math.abs (l2 - l1); returforskjell / 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 + "minutt (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 varighet ="); apollo.calcHM (eva); lang lunarStay = apollo.getElapsedSeconds (lunarLanding, lunarDeparture); System.out.print ("Lunar stay ="); apollo.calcHM (lunarStay); }} 

Resultatet fra programmet ovenfor er:

EVA-varighet = 2 time (r) 13 minutt (er)

Måneopphold = 21 time (r) 37 minutt (er)

Så langt har jeg gjort beregninger basert på enkle formler som: "1 minutt = 60 sekunder," "1 time = 60 minutter," og "1 dag = 24 timer."

Hva med "1 måned =? Dager" og "1 år =? Dager"?

Måneder kan bestå av 28, 29, 30 eller 31 dager; år kan være 365 eller 366 dager. Derfor oppstår det problemer når du prøver å beregne hele tidsenheter i måneder og år. Hvis du for eksempel bruker gjennomsnittlig antall dager i en måned (omtrent 30,4375), og du beregner antall forløpne måneder basert 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 beregningen vil resultere i 1 måned; den andre vil resultere i null måneder!

Så tenk nøye før du beregner forløpt tid i fulle enheter i måneder og år.

Forløpt tid, sak 2: Endring av tidsenhet

Definisjonen av tidsenhetsendring er relativt enkel: Hvis du teller dager, teller du ganske enkelt antall ganger datoen har endret seg. For eksempel, hvis noe starter den 15. og slutter den 17., har to dager gått. (Datoen ble endret først til 16. og deretter til 17.) Tilsvarende, hvis en prosess starter kl. 3:25 på ettermiddagen og avsluttes kl. 16:10, har 1 time gått fordi timen har endret seg en gang (fra 3 til 4).

Biblioteker beregner ofte tid på denne måten. For eksempel, hvis jeg låner en bok fra biblioteket mitt, trenger jeg ikke å ha boka i min besittelse i minst 24 timer for at biblioteket skal vurdere den lånt i en dag. I stedet registreres dagen jeg låner boka på kontoen min. Så snart datoen bytter til neste dag, har jeg lånt boka i en dag, selv om tiden ofte er mindre enn 24 timer.

Når man beregner forløpt tid i betydningen tidsenhetsendring, er det vanligvis ikke fornuftig å beregne mer enn en tidsenhet. Hvis jeg for eksempel låner en biblioteksbok klokken 21.00, og returnerer den neste dag klokka 12.00, kan jeg regne ut at jeg har lånt boka i en dag. Det er imidlertid liten mening å spørre: "En dag og hvor mange timer?" Siden boka ble lånt ut i totalt 15 timer, er svaret en dag og negativt ni timer? Derfor, for denne opplæringen, vil jeg beregne tidsenhetsendring for bare en tidsenhet.

Algoritme for beregning av tidsenhet for endring

Slik beregner du tidsenheten for endring mellom to datoer:

  1. Lag kopier av de to datoene. De klone () metoden kan lage kopier for deg.
  2. Bruk kopiene av datoene til å angi alle felt som er mindre enn endringsenheten til hvert felts minimumsverdi. Hvis du for eksempel teller forløpne dager, må du sette timer, minutter, sekunder og millisekunder til null. I dette tilfellet bruker du klar() metode for å sette tidsfelt til laveste verdi.
  3. Ta den tidligere datoen og legg til en i feltet du teller, og gjenta til de to datoene er like. Antall ganger du legger til en er svaret. Du kan bruke før() og etter() metoder, som returnerer en boolsk verdi, for å teste om en dato er før eller etter en annen dato.

Følgende klasse har metoder for å telle dager og måneder.

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