Προγραμματισμός

Εργασία σε ώρα Java

Αυτό το άρθρο βασίζεται στις πληροφορίες που παρουσιάζονται στο άρθρο Υπολογισμός Java Dates (JavaWorld, 29 Δεκεμβρίου 2000). Εδώ έχω αναφέρει ορισμένα βασικά σημεία από αυτό το άρθρο που πρέπει να γνωρίζετε. Εάν αυτά τα σημεία δεν είναι σαφή για εσάς, σας συνιστούμε να διαβάσετε την ενότητα "Υπολογισμός ημερομηνιών Java" για περαιτέρω εξήγηση.

  1. Η Java υπολογίζει το χρόνο σε χιλιοστά του δευτερολέπτου πριν ή μετά την έναρξη της 1ης Ιανουαρίου 1970.
  2. ο Ημερομηνία κατασκευαστής της τάξης Ημερομηνία() επιστρέφει ένα αντικείμενο που αντιπροσωπεύει τη στιγμή δημιουργίας του αντικειμένου. Ημερομηνία'μικρό getTime () η μέθοδος επιστρέφει a μακρύς τιμή του οποίου ο αριθμός ισούται με τον αριθμό χιλιοστών του δευτερολέπτου πριν ή μετά την 1η Ιανουαρίου 1970.
  3. ο Μορφή ημερομηνίας η τάξη χρησιμοποιείται για τη μετατροπή Ημερομηνίαs έως Σειράs και αντίστροφα. Το στατικό getDateInstance () η μέθοδος επιστρέφει a Μορφή ημερομηνίας αντικείμενο στην προεπιλεγμένη μορφή. ο getDateInstance (DateFormat.FIELD) επιστρέφει a Μορφή ημερομηνίας αντικείμενο με καθορισμένη μορφή. ο μορφή (Ημερομηνία δ) η μέθοδος επιστρέφει a Σειρά που αντιπροσωπεύει την ημερομηνία, όπως "1 Ιανουαρίου 2002." Αντίθετα, το ανάλυση (συμβολοσειρά) η μέθοδος επιστρέφει a Ημερομηνία αντικείμενο βάσει της ημερομηνίας Σειρά το όρισμα αντιπροσωπεύει.
  4. Η εμφάνιση του Σειράεπέστρεψε από το μορφή() Η μέθοδος μπορεί να ποικίλλει ανάλογα με τις τοπικές ρυθμίσεις στον υπολογιστή όπου εκτελείται το πρόγραμμα.
  5. ο Γρηγοριανό ημερολόγιο η τάξη έχει δύο σημαντικούς κατασκευαστές: Γρηγοριανό ημερολόγιο(), που επιστρέφει ένα αντικείμενο που αντιπροσωπεύει τη στιγμή που δημιουργήθηκε, και το Ημερολόγιο Gregorian (int έτος, int μήνας, int ημερομηνία) ο κατασκευαστής χρησιμοποιείται για τη δημιουργία ενός αντικειμένου που αντιπροσωπεύει μια αυθαίρετη ημερομηνία. ο Γρηγοριανό ημερολόγιο της τάξης getTime () η μέθοδος επιστρέφει a Ημερομηνία αντικείμενο. ο προσθήκη (πεδίο int, int ποσό) Η μέθοδος υπολογίζει ημερομηνίες προσθέτοντας ή αφαιρώντας μονάδες χρόνου όπως ημέρες, μήνες ή χρόνια.

Gregorian Ημερολόγιο και ώρα

Δύο Γρηγοριανό ημερολόγιο Οι κατασκευαστές τάξης μπορούν να χρησιμοποιηθούν για την αντιμετώπιση του χρόνου. Το πρώτο δημιουργεί ένα αντικείμενο που αντιπροσωπεύει μια ημερομηνία, ώρα και λεπτό:

Ημερολόγιο Gregorian (int έτος, int μήνας, int ημερομηνία, int hour, int minute) 

Το δεύτερο δημιουργεί ένα αντικείμενο που αντιπροσωπεύει ημερομηνία, ώρα, λεπτό και δεύτερο:

Ημερολόγιο Gregorian (int έτος, int μήνα, int ημερομηνία, int hour, int minute, int second) 

Πρώτον, πρέπει να σημειώσω ότι κάθε κατασκευαστής απαιτεί πληροφορίες ημερομηνίας (έτος, μήνας και ημέρα) επιπλέον των πληροφοριών ώρας. Εάν θέλετε να μιλήσετε για τις 2:30 μ.μ., πρέπει να καθορίσετε την ημερομηνία.

Επίσης, το καθένα Γρηγοριανό ημερολόγιο Ο κατασκευαστής δημιουργεί ένα αντικείμενο που αντιπροσωπεύει μια χρονική στιγμή που υπολογίζεται στο πλησιέστερο χιλιοστό του δευτερολέπτου. Έτσι, εάν ο κατασκευαστής σας παίρνει ορίσματα μόνο για το έτος, τον μήνα και την ημερομηνία, τότε οι τιμές για ώρες, λεπτά, δευτερόλεπτα και χιλιοστά του δευτερολέπτου ορίζονται στο μηδέν. Ομοίως, εάν ο κατασκευαστής σας παίρνει ορίσματα για έτος, μήνα, ημερομηνία, ώρες και λεπτά, τότε τα δευτερόλεπτα και τα χιλιοστά του δευτερολέπτου τίθενται στο μηδέν.

DateFormat και ώρα

Για να δημιουργήσετε ένα Μορφή ημερομηνίας αντικείμενο για εμφάνιση ώρας και ημερομηνίας, μπορείτε να χρησιμοποιήσετε τη στατική μέθοδο getDateTimeInstance (int dateStyle, int timeStyle). Αυτή η μέθοδος καθορίζει τα στυλ ημερομηνίας και ώρας που θέλετε να χρησιμοποιήσετε. Εάν είστε ικανοποιημένοι με τα προεπιλεγμένα στυλ, μπορείτε να αντικαταστήσετε το μικρότερο getDateTimeInstance ().

Για να δημιουργήσετε ένα Μορφή ημερομηνίας Αντικείμενο για εμφάνιση μόνο την ώρα, μπορείτε να χρησιμοποιήσετε τη στατική μέθοδο getTimeInstance (int timeStyle).

Το παρακάτω πρόγραμμα δείχνει πώς το getDateTimeInstance () και getTimeInstance () οι μέθοδοι λειτουργούν:

εισαγωγή java.util. *; εισαγωγή java.text. *; δημόσια τάξη Apollo {public static void main (String [] args) {GregorianCalendar liftOffApollo11 ​​= new GregorianCalendar (1969, Calendar.JULY, 16, 9, 32); Ημερομηνία d = liftOffApollo11.getTime (); DateFormat df1 = DateFormat.getDateTimeInstance (DateFormat.MEDIUM, DateFormat.MEDIUM); DateFormat df2 = DateFormat.getTimeInstance (DateFormat.SHORT); Συμβολοσειρά s1 = df1.format (d); Συμβολοσειρά s2 = df2.format (d); System.out.println (s1); System.out.println (s2); }} 

Στον υπολογιστή μου, το παραπάνω πρόγραμμα εμφανίζει τα εξής:

16 Ιουλ 1969 9:32:00 ΠΜ

9:32 ΠΜ

(Η έξοδος μπορεί να διαφέρει ανάλογα με τις τοπικές ρυθμίσεις του υπολογιστή σας.)

Υπολογισμός του παρελθόντος χρόνου

Ίσως χρειαστεί μερικές φορές να υπολογίσετε το χρόνο που έχει παρέλθει. Για παράδειγμα, μπορεί να θέλετε να μάθετε τη διάρκεια μιας διαδικασίας κατασκευής, λαμβάνοντας υπόψη τους χρόνους έναρξης και λήξης. Μια εταιρεία ενοικίασης που ενοικιάζει αντικείμενα ανά ώρα ή ημέρα μπορεί επίσης να είναι χρήσιμη για τον υπολογισμό του χρόνου που έχει παρέλθει. Ομοίως, στον χρηματοοικονομικό κόσμο, είναι συχνά απαραίτητο να υπολογίζονται οι πληρωμές τόκων με την πάροδο του χρόνου.

Για να περιπλέξει το ζήτημα, οι άνθρωποι υπολογίζουν το χρόνο που έχει παρέλθει με τουλάχιστον δύο τρόπους. Μπορείτε να πείτε ότι έχει περάσει μια μέρα όταν έχουν παρέλθει 24 ώρες ή όταν το ημερολόγιο αλλάζει από τη μία μέρα στην άλλη. Θα συζητήσω τώρα αυτούς τους δύο τρόπους σκέψης.

Χρόνος που πέρασε, περίπτωση 1: Πλήρεις μονάδες

Σε αυτήν την περίπτωση, μια ημέρα δεν έχει παρέλθει έως ότου περάσουν 24 ώρες, μια ώρα δεν έχει παρέλθει έως ότου περάσουν 60 λεπτά, ένα λεπτό δεν έχει παρέλθει έως ότου περάσουν 60 δευτερόλεπτα και ούτω καθεξής. Σύμφωνα με αυτήν τη μέθοδο, 23 ώρες του παρελθόντος χρόνου θα μεταφραστούν σε μηδέν ημέρες.

Για να υπολογίσετε τον χρόνο που έχει παρέλθει με αυτόν τον τρόπο, ξεκινάτε υπολογίζοντας τα χιλιοστά του δευτερολέπτου που έχουν παρέλθει. Για να το κάνετε αυτό, μετατρέψτε πρώτα κάθε ημερομηνία στον αριθμό χιλιοστών του δευτερολέπτου από την αρχή της 1ης Ιανουαρίου 1970. Στη συνέχεια, αφαιρέστε την πρώτη τιμή χιλιοστών του δευτερολέπτου από τη δεύτερη τιμή χιλιοστών του δευτερολέπτου. Ακολουθεί ένα δείγμα υπολογισμού:

εισαγωγή java.util. *; δημόσια τάξη ElapsedMillis {public static void main (String [] args) {GregorianCalendar gc1 = new GregorianCalendar (1995, 11, 1, 3, 2, 1); GregorianCalendar gc2 = νέο GregorianCalendar (1995, 11, 1, 3, 2, 2); // οι παραπάνω δύο ημερομηνίες ξεχωρίζουν το ένα δευτερόλεπτο Ημερομηνία d1 = gc1.getTime (); Ημερομηνία d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); μεγάλη διαφορά = l2 - l1; System.out.println ("Παρελθόν χιλιοστά του δευτερολέπτου:" + διαφορά); }} 

Το παραπάνω πρόγραμμα εκτυπώνει τα εξής:

Παρελθόν χιλιοστά του δευτερολέπτου: 1000

Αυτό το πρόγραμμα προκαλεί επίσης κάποια σύγχυση. ο Γρηγοριανό ημερολόγιο της τάξης getTime () επιστρέφει a Ημερομηνία αντικείμενο, ενώ το Ημερομηνία της τάξης getTime () η μέθοδος επιστρέφει a μακρύς αριθμός που αντιπροσωπεύει τα χιλιοστά του δευτερολέπτου πριν ή μετά τις αρχές της 1ης Ιανουαρίου 1970. Έτσι, παρόλο που οι μέθοδοι έχουν το ίδιο όνομα, οι τύποι επιστροφής τους είναι διαφορετικοί!

Μπορείτε να μετατρέψετε χιλιοστά του δευτερολέπτου σε δευτερόλεπτα χρησιμοποιώντας απλή ακέραια διαίρεση, όπως στο ακόλουθο τμήμα κώδικα:

μεγάλα χιλιοστά του δευτερολέπτου = 1999; μεγάλα δευτερόλεπτα = 1999/1000; 

Αυτός ο τρόπος μετατροπής χιλιοστών του δευτερολέπτου σε δευτερόλεπτα εξαλείφει τα κλάσματα, έτσι 1.999 χιλιοστά του δευτερολέπτου ισούται με 1 δευτερόλεπτο, ενώ 2.000 χιλιοστά του δευτερολέπτου ισούται με 2 δευτερόλεπτα.

Για να υπολογίσετε μεγαλύτερες μονάδες - όπως ημέρες, ώρες και λεπτά - με δεδομένο αριθμό δευτερολέπτων, μπορείτε να χρησιμοποιήσετε την ακόλουθη διαδικασία:

  1. Υπολογίστε τη μεγαλύτερη μονάδα, μειώνοντας ανάλογα τον αριθμό των δευτερολέπτων
  2. Υπολογίστε την επόμενη μεγαλύτερη μονάδα, μειώνοντας ανάλογα τον αριθμό των δευτερολέπτων
  3. Επαναλάβετε έως ότου απομένουν μόνο δευτερόλεπτα

Για παράδειγμα, εάν ο χρόνος που έχει παρέλθει είναι 10.000 δευτερόλεπτα και θέλετε να μάθετε πόσες ώρες, λεπτά και δευτερόλεπτα αντιστοιχεί στην τιμή, ξεκινάτε με τη μεγαλύτερη τιμή: ώρες. Διαιρέστε 10.000 με 3.600 (δευτερόλεπτα σε μια ώρα) για να υπολογίσετε τον αριθμό των ωρών. Χρησιμοποιώντας ακέραια διαίρεση, η απάντηση είναι 2 ώρες (τα κλάσματα πέφτουν σε ακέραια διαίρεση). Για να υπολογίσετε τα υπόλοιπα δευτερόλεπτα, μειώστε 10.000 κατά 3.600 φορές 2 ώρες: 10.000 - (3.600 x 2) = 2.800 δευτερόλεπτα. Έχετε λοιπόν 2 ώρες και 2.800 δευτερόλεπτα.

Για να μετατρέψετε 2.800 δευτερόλεπτα σε λεπτά, διαιρέστε τα 2.800 με 60 (δευτερόλεπτα ανά λεπτό). Με ακέραια διαίρεση, η απάντηση είναι 46. Και 2.800 - (60 x 46) = 40 δευτερόλεπτα. Η τελική απάντηση είναι 2 ώρες, 46 λεπτά και 40 δευτερόλεπτα.

Ο παραπάνω υπολογισμός εμφανίζεται στο ακόλουθο πρόγραμμα Java:

εισαγωγή java.util. *; δημόσια τάξη Elapsed1 {public void calcHMS (int timeInSeconds) {int ώρες, λεπτά, δευτερόλεπτα. ώρες = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (ώρες * 3600); λεπτά = timeInSeconds / 60; timeInSeconds = timeInSeconds - (λεπτά * 60); δευτερόλεπτα = timeInSeconds; System.out.println (ώρες + "ώρες)" λεπτά "+ λεπτά" + δευτερόλεπτα + "δευτερόλεπτα (ες)"); } δημόσιος στατικός κενός κενός (String [] args) {Elapsed1 elap = new Elapsed1 (); elap.calcHMS (10000); }} 

Η έξοδος από το παραπάνω πρόγραμμα είναι:

2 ώρες 46 λεπτά 40 δευτερόλεπτα

Το παραπάνω πρόγραμμα υπολογίζει σωστά τον αριθμό των ωρών, ακόμα και όταν ο χρόνος που έχει παρέλθει είναι μικρότερος από μία ώρα. Για παράδειγμα, εάν χρησιμοποιείτε το παραπάνω πρόγραμμα για τον υπολογισμό 1.000 δευτερολέπτων, η έξοδος είναι:

0 ώρες 16 λεπτά 40 δευτερόλεπτα

Για να δείξει ένα πραγματικό παράδειγμα, το ακόλουθο πρόγραμμα υπολογίζει το χρόνο που έχει παρέλθει με βάση την πτήση Apollo 11 προς το φεγγάρι:

εισαγωγή java.util. *; δημόσια τάξη LunarLanding {public long getElapsedSeconds (GregorianCalendar gc1, GregorianCalendar gc2) {Date d1 = gc1.getTime (); Ημερομηνία d2 = gc2.getTime (); long l1 = d1.getTime (); long l2 = d2.getTime (); μεγάλη διαφορά = Math.abs (l2 - l1); διαφορά επιστροφής / 1000; } public void calcHM (long timeInSeconds) {μεγάλες ώρες, λεπτά, δευτερόλεπτα. ώρες = timeInSeconds / 3600; timeInSeconds = timeInSeconds - (ώρες * 3600); λεπτά = timeInSeconds / 60; System.out.println (ώρες + "ώρες)" λεπτά "+ λεπτά"); } public static void main (String [] args) {GregorianCalendar lunarLanding = νέο GregorianCalendar (1969, Ημερολόγιο.ΙΟΥΛΙΟΣ, 20, 16, 17); GregorianCalendar lunarDeparture = νέο GregorianCalendar (1969, Ημερολόγιο. ΙΟΥΛΙΟΣ, 21, 13, 54); GregorianCalendar startEVA = νέο GregorianCalendar (1969, Calendar.JULY, 20, 22, 56); GregorianCalendar endEVA = νέο GregorianCalendar (1969, Calendar.JULY, 21, 1, 9); LunarLanding apollo = νέο LunarLanding (); long eva = apollo.getElapsedSeconds (startEVA, endEVA); System.out.print ("διάρκεια EVA ="); apollo.calcHM (eva); long lunarStay = apollo.getElapsedSeconds (σεληνιακή προσγείωση, lunarDeparture); System.out.print ("Σεληνιακή διαμονή ="); apollo.calcHM (lunarStay); }} 

Η έξοδος από το παραπάνω πρόγραμμα είναι:

Διάρκεια EVA = 2 ώρες 13 λεπτά

Σεληνιακή διαμονή = 21 ώρες 37 λεπτά

Μέχρι στιγμής, έχω κάνει υπολογισμούς βάσει απλών τύπων όπως: "1 λεπτό = 60 δευτερόλεπτα", "1 ώρα = 60 λεπτά" και "1 ημέρα = 24 ώρες."

Τι γίνεται με το "1 μήνα =? Ημέρες" και το "1 έτος =? Ημέρες";

Οι μήνες μπορούν να αποτελούνται από 28, 29, 30 ή 31 ημέρες. χρόνια μπορεί να είναι 365 ή 366 ημέρες. Επομένως, προκύπτουν προβλήματα όταν προσπαθείτε να υπολογίσετε ολόκληρες μονάδες χρόνου για μήνες και χρόνια. Για παράδειγμα, εάν χρησιμοποιείτε τον μέσο αριθμό ημερών σε ένα μήνα (περίπου 30,4375) και υπολογίζετε τον αριθμό των μηνών που έχουν παρέλθει με βάση τα ακόλουθα δύο διαστήματα:

  • 1 Ιουλίου, 2:00 π.μ. έως 31 Ιουλίου, 10:00 μ.μ.
  • 1 Φεβρουαρίου, 2:00 π.μ. έως 29 Φεβρουαρίου, 10:00 μ.μ.

Ο πρώτος υπολογισμός θα έχει ως αποτέλεσμα 1 μήνα. το δεύτερο θα οδηγήσει σε μηδέν μήνες!

Λοιπόν, σκεφτείτε πολύ προσεκτικά πριν υπολογίσετε το χρόνο που έχει παρέλθει σε πλήρεις μονάδες για μήνες και χρόνια.

Χρόνος που πέρασε, περίπτωση 2: Αλλαγή μονάδας χρόνου

Ο ορισμός της αλλαγής μονάδας ώρας είναι σχετικά απλός: Εάν μετράτε ημέρες, απλά μετράτε τον αριθμό των φορών που έχει αλλάξει η ημερομηνία. Για παράδειγμα, εάν κάτι ξεκινήσει στις 15 και λήγει στις 17, έχουν περάσει 2 ημέρες. (Η ημερομηνία άλλαξε πρώτα στις 16, στη συνέχεια στις 17). Ομοίως, εάν μια διαδικασία ξεκινά στις 3:25 το απόγευμα και τελειώσει στις 4:10 μ.μ., έχει περάσει 1 ώρα επειδή η ώρα έχει αλλάξει μία φορά (από 3 σε 4).

Οι βιβλιοθήκες υπολογίζουν συχνά τον χρόνο με αυτόν τον τρόπο. Για παράδειγμα, εάν δανείζομαι ένα βιβλίο από τη βιβλιοθήκη μου, δεν χρειάζεται να έχω το βιβλίο στη διάθεσή μου για τουλάχιστον 24 ώρες για να θεωρήσει τη βιβλιοθήκη ότι δανείστηκε για μία ημέρα. Αντ 'αυτού, η ημέρα που δανείζομαι το βιβλίο καταγράφεται στον λογαριασμό μου. Μόλις η ημερομηνία αλλάξει στην επόμενη μέρα, έχω δανειστεί το βιβλίο για μια μέρα, παρόλο που το χρονικό διάστημα είναι συχνά μικρότερο από 24 ώρες.

Κατά τον υπολογισμό του παρελθόντος χρόνου με την έννοια της αλλαγής μονάδας χρόνου, συνήθως δεν έχει νόημα να υπολογίζετε περισσότερες από μία μονάδες χρόνου. Για παράδειγμα, εάν δανείζομαι ένα βιβλίο βιβλιοθήκης στις 9:00 μ.μ. και το επιστρέψω την επόμενη μέρα το μεσημέρι, μπορώ να υπολογίσω ότι έχω δανειστεί το βιβλίο για μία μέρα. Ωστόσο, δεν έχει νόημα να ρωτάς, "Μια μέρα και πόσες ώρες;" Δεδομένου ότι το βιβλίο δανείστηκε για συνολικά 15 ώρες, είναι η απάντηση μια μέρα και αρνητική εννέα ώρες; Επομένως, για αυτό το σεμινάριο, θα υπολογίσω την αλλαγή μονάδας χρόνου για μία μόνο μονάδα χρόνου.

Αλγόριθμος για τον υπολογισμό της μονάδας χρόνου αλλαγής

Έτσι υπολογίζετε τη μονάδα ώρας αλλαγής μεταξύ δύο ημερομηνιών:

  1. Δημιουργήστε αντίγραφα των δύο ημερομηνιών. ο κλώνος () μέθοδος μπορεί να δημιουργήσει αντίγραφα για εσάς.
  2. Χρησιμοποιώντας τα αντίγραφα των ημερομηνιών, ορίστε όλα τα πεδία που είναι μικρότερα από τη μονάδα αλλαγής στην ελάχιστη τιμή κάθε πεδίου. Για παράδειγμα, εάν μετράτε τις ημέρες που έχουν περάσει, ορίστε ώρες, λεπτά, δευτερόλεπτα και χιλιοστά του δευτερολέπτου στο μηδέν. Σε αυτήν την περίπτωση, χρησιμοποιήστε το Σαφή() μέθοδος για να ορίσετε τα πεδία χρόνου στη χαμηλότερη τιμή τους.
  3. Πάρτε την προηγούμενη ημερομηνία και προσθέστε μία στο πεδίο που μετράτε, επαναλαμβάνοντας έως ότου οι δύο ημερομηνίες είναι ίσες. Ο αριθμός των φορών που προσθέτετε μία είναι η απάντηση. Μπορείτε να χρησιμοποιήσετε το πριν() και μετά() μεθόδους, οι οποίες επιστρέφουν μια δυαδική τιμή, για να ελέγξουν εάν μια ημερομηνία είναι πριν ή μετά από άλλη ημερομηνία.

Η ακόλουθη τάξη έχει μεθόδους μέτρησης ημερών και μηνών.