Arbeiten in Java-Zeit

Dieser Artikel baut auf den Informationen auf, die in meinem Artikel zur Berechnung von Java-Daten ( JavaWorld, 29. Dezember 2000) enthalten sind. Hier habe ich einige wichtige Punkte aus diesem Artikel aufgelistet, die Ihnen vertraut sein sollten. Wenn Ihnen diese Punkte nicht klar sind, empfehlen wir Ihnen, zur weiteren Erläuterung "Berechnung von Java-Daten" zu lesen.

  1. Java rechnet mit einer Zeit in Millisekunden vor oder nach dem 1. Januar 1970.
  2. Der DateKonstruktor der Klasse Date()gibt ein Objekt zurück, das den Moment darstellt, in dem das Objekt erstellt wurde. DateDie getTime()Methode von 'gibt einen longWert zurück, dessen Anzahl der Anzahl der Millisekunden vor oder nach dem 1. Januar 1970 entspricht.
  3. Die DateFormatKlasse wird verwendet, um Dates in Strings umzuwandeln und umgekehrt. Die statische getDateInstance()Methode gibt ein DateFormatObjekt im Standardformat zurück. Das getDateInstance(DateFormat.FIELD)gibt ein DateFormatObjekt mit einem angegebenen Format zurück. Die format(Date d)Methode gibt ein zurück String, das das Datum darstellt, z. B. "1. Januar 2002". Umgekehrt gibt die parse(String s)Methode ein DateObjekt basierend auf dem Datum zurück, das das StringArgument darstellt.
  4. Das Erscheinungsbild von Strings, das von der format()Methode zurückgegeben wird, kann je nach den regionalen Einstellungen auf dem Computer variieren, auf dem das Programm ausgeführt wird.
  5. Die GregorianCalendarKlasse verfügt über zwei wichtige Konstruktoren: GregorianCalendar()Gibt ein Objekt zurück, das den Zeitpunkt der GregorianCalendar(int year, int month, int date)Erstellung darstellt , und den Konstruktor, mit dem ein Objekt erstellt wird, das ein beliebiges Datum darstellt. Die Methode der GregorianCalendarKlasse getTime()gibt ein DateObjekt zurück. Die add(int field, int amount)Methode berechnet Daten durch Addieren oder Subtrahieren von Zeiteinheiten wie Tagen, Monaten oder Jahren.

Gregorianischer Kalender und Zeit

Zwei GregorianCalendarKlassenkonstruktoren können verwendet werden, um mit der Zeit umzugehen. Der erste erstellt ein Objekt, das ein Datum, eine Stunde und eine Minute darstellt:

Gregorianischer Kalender (int Jahr, int Monat, int Datum, int Stunde, int Minute) 

Die Sekunde erstellt ein Objekt, das ein Datum, eine Stunde, eine Minute und eine Sekunde darstellt:

Gregorianischer Kalender (int Jahr, int Monat, int Datum, int Stunde, int Minute, int Sekunde) 

Zunächst sollte ich beachten, dass jeder Konstruktor zusätzlich zu den Zeitinformationen Datumsinformationen (Jahr, Monat und Tag) benötigt. Wenn Sie gegen 14:30 Uhr sprechen möchten, müssen Sie das Datum angeben.

Außerdem erstellt jeder GregorianCalendarKonstruktor ein Objekt, das einen auf die nächste Millisekunde berechneten Zeitpunkt darstellt. Wenn Ihr Konstruktor nur Argumente für Jahr, Monat und Datum akzeptiert, werden die Werte für Stunden, Minuten, Sekunden und Millisekunden auf Null gesetzt. Wenn Ihr Konstruktor Argumente für Jahr, Monat, Datum, Stunden und Minuten verwendet, werden Sekunden und Millisekunden auf Null gesetzt.

Datumsformat und Uhrzeit

Um ein DateFormatObjekt zur Anzeige von Uhrzeit und Datum zu erstellen , können Sie die statische Methode verwenden getDateTimeInstance(int dateStyle, int timeStyle). Diese Methode gibt die Datums- und Zeitstile an, die Sie verwenden möchten. Wenn Sie mit den Standardstilen zufrieden sind, können Sie die kürzeren ersetzen getDateTimeInstance().

Um ein DateFormatObjekt zu erstellen , das nur die Uhrzeit anzeigt, können Sie die statische Methode verwenden getTimeInstance(int timeStyle).

Das folgende Programm zeigt, wie die getDateTimeInstance()und getTimeInstance()Methoden funktionieren:

import java.util. *; import java.text. *; öffentliche Klasse Apollo {public static void main (String [] args) {GregorianCalendar liftOffApollo11 ​​= neuer 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); String s1 = df1.format (d); String s2 = df2.format (d); System.out.println (s1); System.out.println (s2); }}

Auf meinem Computer zeigt das obige Programm Folgendes an:

16. Juli 1969, 9:32:00 Uhr

9:32 Uhr

(Die Ausgabe kann je nach den regionalen Einstellungen Ihres Computers variieren.)

Verstrichene Zeit berechnen

Möglicherweise müssen Sie manchmal die verstrichene Zeit berechnen. Beispielsweise möchten Sie möglicherweise die Dauer eines Herstellungsprozesses anhand der Start- und Endzeiten kennen. Ein Vermieter, der Artikel stunden- oder tageweise mietet, kann es auch nützlich finden, die verstrichene Zeit zu berechnen. In ähnlicher Weise ist es in der Finanzwelt häufig erforderlich, Zinszahlungen über die verstrichene Zeit zu berechnen.

Um das Problem zu verkomplizieren, berechnen Menschen die verstrichene Zeit auf mindestens zwei Arten. Sie können sagen, dass ein Tag vergangen ist, an dem 24 Stunden vergangen sind oder wenn sich der Kalender von einem Tag zum nächsten ändert. Ich werde jetzt diese beiden Denkweisen diskutieren.

Verstrichene Zeit, Fall 1: Volle Einheiten

In diesem Fall ist ein Tag nicht vergangen, bis 24 Stunden vergangen sind, eine Stunde ist nicht vergangen, bis 60 Minuten vergangen sind, eine Minute ist nicht vergangen, bis 60 Sekunden vergangen sind und so weiter. Bei dieser Methode würden 23 Stunden verstrichene Zeit null Tage bedeuten.

Um die verstrichene Zeit auf diese Weise zu berechnen, berechnen Sie zunächst die verstrichenen Millisekunden. Konvertieren Sie dazu zunächst jedes Datum in die Anzahl der Millisekunden seit Beginn des 1. Januar 1970. Anschließend subtrahieren Sie den ersten Millisekundenwert vom zweiten Millisekundenwert. Hier ist eine Beispielberechnung:

import java.util. *; öffentliche Klasse ElapsedMillis {public static void main (String [] args) {GregorianCalendar gc1 = neuer GregorianCalendar (1995, 11, 1, 3, 2, 1); GregorianCalendar gc2 = neuer GregorianCalendar (1995, 11, 1, 3, 2, 2); // Die beiden oben genannten Daten liegen eine Sekunde auseinander. Datum d1 = gc1.getTime (); Datum d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); lange Differenz = l2 - l1; System.out.println ("Verstrichene Millisekunden:" + Differenz); }}

Das obige Programm druckt Folgendes:

Verstrichene Millisekunden: 1000

Dieses Programm sorgt auch für einige Verwirrung. Die GregorianCalendarKlasse getTime()gibt ein DateObjekt zurück, während die Methode der DateKlasse getTime()eine longZahl zurückgibt, die die Millisekunden vor oder nach dem 1. Januar 1970 darstellt. Obwohl die Methoden denselben Namen haben, sind ihre Rückgabetypen unterschiedlich!

Sie können Millisekunden in Sekunden konvertieren, indem Sie eine einfache Ganzzahldivision verwenden, wie im folgenden Codefragment:

lange Millisekunden = 1999; lange Sekunden = 1999/1000;

Durch diese Art der Konvertierung von Millisekunden in Sekunden werden Brüche eliminiert, sodass 1.999 Millisekunden 1 Sekunde entsprechen, während 2.000 Millisekunden 2 Sekunden entsprechen.

Um größere Einheiten - wie Tage, Stunden und Minuten - mit einer Anzahl von Sekunden zu berechnen, können Sie den folgenden Prozess verwenden:

  1. Berechnen Sie die größte Einheit und reduzieren Sie die Anzahl der Sekunden entsprechend
  2. Berechnen Sie die nächstgrößere Einheit und reduzieren Sie die Anzahl der Sekunden entsprechend
  3. Wiederholen, bis nur noch Sekunden übrig sind

Wenn Ihre verstrichene Zeit beispielsweise 10.000 Sekunden beträgt und Sie wissen möchten, wie vielen Stunden, Minuten und Sekunden dieser Wert entspricht, beginnen Sie mit dem größten Wert: Stunden. Teilen Sie 10.000 durch 3.600 (Sekunden in einer Stunde), um die Anzahl der Stunden zu berechnen. Bei Verwendung der Ganzzahldivision beträgt die Antwort 2 Stunden (Brüche werden in der Ganzzahldivision gelöscht). Um die verbleibenden Sekunden zu berechnen, reduzieren Sie 10.000 um 3.600 mal 2 Stunden: 10.000 - (3.600 x 2) = 2.800 Sekunden. Sie haben also 2 Stunden und 2.800 Sekunden.

Teilen Sie 2.800 Sekunden durch 60 (Sekunden pro Minute), um 2.800 Sekunden in Minuten umzuwandeln. Bei ganzzahliger Division lautet die Antwort 46. Und 2.800 - (60 x 46) = 40 Sekunden. Die endgültige Antwort lautet 2 Stunden, 46 Minuten und 40 Sekunden.

Die obige Berechnung wird im folgenden Java-Programm gezeigt:

import java.util. *; öffentliche Klasse Elapsed1 {public void calcHMS (int timeInSeconds) {int Stunden, Minuten, Sekunden; Stunden = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (Stunden * 3600); Minuten = timeInSeconds / 60; timeInSeconds = timeInSeconds - (Minuten * 60); Sekunden = timeInSeconds; System.out.println (Stunden + "Stunde (n)" + Minuten + "Minute (n)" + Sekunden + "Sekunde (n)"); } public static void main (String [] args) {Elapsed1 elap = new Elapsed1 (); elap.calcHMS (10000); }}

Die Ausgabe des obigen Programms ist:

2 Stunde (n) 46 Minute (n) 40 Sekunde (n)

Das obige Programm berechnet die Anzahl der Stunden korrekt, selbst wenn die verstrichene Zeit weniger als eine Stunde beträgt. Wenn Sie beispielsweise das obige Programm verwenden, um 1.000 Sekunden zu berechnen, lautet die Ausgabe:

0 Stunde (n) 16 Minute (n) 40 Sekunde (n)

Um ein Beispiel aus der Praxis zu zeigen, berechnet das folgende Programm die verstrichene Zeit basierend auf dem Apollo 11-Flug zum Mond:

import java.util.*; public class LunarLanding { public long getElapsedSeconds(GregorianCalendar gc1, GregorianCalendar gc2) { Date d1 = gc1.getTime(); Date d2 = gc2.getTime(); long l1 = d1.getTime(); long l2 = d2.getTime(); long difference = Math.abs(l2 - l1); return difference / 1000; } public void calcHM(long timeInSeconds) { long hours, minutes, seconds; hours = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (hours * 3600); minutes = timeInSeconds / 60; System.out.println(hours + " hour(s) " + minutes + " minute(s)" ); } public static void main(String[] args) { GregorianCalendar lunarLanding = new GregorianCalendar(1969, Calendar.JULY, 20, 16, 17); GregorianCalendar lunarDeparture = new GregorianCalendar(1969, Calendar.JULY, 21, 13, 54); GregorianCalendar startEVA = new GregorianCalendar(1969, Calendar.JULY, 20, 22, 56); GregorianCalendar endEVA = new GregorianCalendar(1969, Calendar.JULY, 21, 1, 9); LunarLanding apollo = new LunarLanding(); long eva = apollo.getElapsedSeconds(startEVA, endEVA); System.out.print("EVA duration = "); apollo.calcHM(eva); long lunarStay = apollo.getElapsedSeconds(lunarLanding, lunarDeparture); System.out.print("Lunar stay = "); apollo.calcHM(lunarStay); } } 

Output from the above program is:

EVA duration = 2 hour(s) 13 minute(s)

Lunar stay = 21 hour(s) 37 minute(s)

So far, I have made calculations based on simple formulas like: "1 minute = 60 seconds," "1 hour = 60 minutes," and "1 day = 24 hours."

What about "1 month = ? days" and "1 year = ? days"?

Months can consist of 28, 29, 30, or 31 days; years can be 365 or 366 days. Therefore, problems arise when you try to calculate full units of time for months and years. For example, if you use the average number of days in a month (approximately 30.4375), and you calculate the number of elapsed months based on the following two intervals:

  • July 1, 2:00 a.m. to July 31, 10:00 p.m.
  • February 1, 2:00 a.m. to February 29, 10:00 p.m.

the first calculation will result in 1 month; the second will result in zero months!

So, think very carefully before you calculate elapsed time in full units for months and years.

Elapsed time, case 2: Time unit change

The definition of time unit change is relatively simple: If you are counting days, you simply count the number of times the date has changed. For example, if something starts on the 15th and ends on the 17th, 2 days have passed. (The date changed first to the 16th, then to the 17th.) Similarly, if a process starts at 3:25 in the afternoon and finishes at 4:10 p.m., 1 hour has passed because the hour has changed once (from 3 to 4).

Libraries often calculate time in this manner. For example, if I borrow a book from my library, I don't need to have the book in my possession for a minimum of 24 hours for the library to consider it borrowed for one day. Instead, the day that I borrow the book is recorded on my account. As soon as the date switches to the next day, I have borrowed the book for one day, even though the amount of time is often less than 24 hours.

When calculating elapsed time in the sense of time unit change, it doesn't usually make sense to calculate more than one unit of time. For example, if I borrow a library book at 9:00 p.m., and return it the next day at noon, I can calculate that I've borrowed the book for one day. However, there is little sense in asking, "One day and how many hours?" Since the book was loaned for a total of 15 hours, is the answer one day and negative nine hours? Therefore, for this tutorial, I will calculate time unit change for only one unit of time.

Algorithm for calculating time unit of change

This is how you calculate time unit of change between two dates:

  1. Make copies of the two dates. The clone() method can make copies for you.
  2. Stellen Sie anhand der Kopien der Daten alle Felder, die kleiner als die Änderungseinheit sind, auf den Mindestwert jedes Felds ein. Wenn Sie beispielsweise verstrichene Tage zählen, setzen Sie Stunden, Minuten, Sekunden und Millisekunden auf Null. Verwenden Sie in diesem Fall die clear()Methode, um Zeitfelder auf ihren niedrigsten Wert zu setzen.
  3. Nehmen Sie das frühere Datum und fügen Sie eins zu dem Feld hinzu, das Sie zählen. Wiederholen Sie diesen Vorgang, bis die beiden Daten gleich sind. Die Häufigkeit, mit der Sie eine hinzufügen, ist die Antwort. Mit den Methoden before()und after(), die einen booleschen Wert zurückgeben, können Sie testen, ob ein Datum vor oder nach einem anderen Datum liegt.

Die folgende Klasse enthält Methoden zum Zählen von Tagen und Monaten.