Ως προγραμματιστής λογισμικού, δεν μπορείτε να ξεφύγετε από το χειρισμό ημερομηνιών. Σχεδόν κάθε εφαρμογή που δημιουργεί ένας προγραμματιστής θα έχει κάποιο στοιχείο όπου η ημερομηνία / ώρα πρέπει να ληφθεί από το χρήστη, να αποθηκευτεί σε μια βάση δεδομένων και να εμφανιστεί πίσω στον χρήστη.
Ρωτήστε οποιονδήποτε προγραμματιστή σχετικά με την εμπειρία του χειρισμού ημερομηνιών και ζωνών ώρας και πιθανότατα θα μοιραστούν μερικές ιστορίες πολέμου. Ο χειρισμός των πεδίων ημερομηνίας και ώρας σίγουρα δεν είναι επιστήμη πυραύλων, αλλά μπορεί συχνά να είναι κουραστικός και επιρρεπής σε λάθη.
Υπάρχουν εκατοντάδες άρθρα σχετικά με το θέμα εκεί έξω, ωστόσο, τα περισσότερα είτε είναι πολύ ακαδημαϊκά, εστιάζοντας σε λεπτομέρειες, ή είναι πολύ ανομοιογενείς, παρέχοντας σύντομα αποσπάσματα κώδικα χωρίς να τους συνοδεύουν πολλές εξηγήσεις. Αυτός ο σε βάθος οδηγός για το χειρισμό DateTime θα σας βοηθήσει να κατανοήσετε τις έννοιες προγραμματισμού και τις βέλτιστες πρακτικές που σχετίζονται με την ώρα και την ημερομηνία χωρίς να χρειάζεται να περιηγηθείτε σε μια σειρά πληροφοριών σχετικά με αυτό το θέμα.
Σε αυτό το άρθρο, θα σας βοηθήσω να σκεφτείτε ξεκάθαρα τα πεδία ημερομηνίας και ώρας και θα προτείνω ορισμένες βέλτιστες πρακτικές που μπορούν να σας βοηθήσουν να αποφύγετε την ημερομηνία / ώρα. Εδώ θα διερευνήσουμε μερικές από τις βασικές έννοιες που είναι απαραίτητες για τον σωστό χειρισμό τιμών ημερομηνίας και ώρας, μορφές που είναι βολικές για την αποθήκευση τιμών DateTime και τη μεταφορά τους μέσω API και πολλά άλλα.
Για αρχάριους, η σωστή απάντηση για τον κωδικό παραγωγής είναι σχεδόν πάντα να χρησιμοποιείτε μια σωστή βιβλιοθήκη αντί να κυλήσετε τη δική σας. Οι πιθανές δυσκολίες με τον υπολογισμό DateTime που συζητούνται σε αυτό το άρθρο είναι μόνο η κορυφή του παγόβουνου, αλλά εξακολουθούν να είναι χρήσιμες να γνωρίζετε, με ή χωρίς βιβλιοθήκη.
Οι βιβλιοθήκες ημερομηνιών βοηθούν με πολλούς τρόπους να κάνουν τη ζωή σας ευκολότερη. Απλοποιούν σε μεγάλο βαθμό την ανάλυση ημερομηνίας, την αριθμητική και τη λογική λειτουργία ημερομηνίας και τη μορφοποίηση ημερομηνιών. Μπορείτε να βρείτε μια αξιόπιστη βιβλιοθήκη ημερομηνιών τόσο για το μπροστινό όσο και για το πίσω μέρος για να κάνετε το μεγαλύτερο μέρος της βαριάς ανύψωσης για εσάς.
Ωστόσο, συχνά χρησιμοποιούμε βιβλιοθήκες ημερομηνιών χωρίς να σκεφτόμαστε πώς λειτουργεί η ημερομηνία / ώρα. Η ημερομηνία / ώρα είναι μια περίπλοκη έννοια. Τα σφάλματα που προκύπτουν λόγω της εσφαλμένης κατανόησής τους μπορεί να είναι εξαιρετικά δύσκολο να κατανοηθούν και να διορθωθούν, ακόμη και με τη βοήθεια βιβλιοθηκών ημερομηνιών. Ως προγραμματιστής, πρέπει να κατανοήσετε τα βασικά και να είστε σε θέση να εκτιμήσετε τα προβλήματα που επιλύουν οι βιβλιοθήκες ημερομηνίας για να αξιοποιήσετε στο έπακρο.
Επίσης, οι βιβλιοθήκες ημερομηνίας / ώρας μπορούν να σας οδηγήσουν μόνο μέχρι τώρα. Όλες οι βιβλιοθήκες ημερομηνιών λειτουργούν δίνοντάς σας πρόσβαση σε βολικές δομές δεδομένων για να αντιπροσωπεύσετε ένα DateTime. Εάν στέλνετε και λαμβάνετε δεδομένα μέσω REST API, θα χρειαστεί τελικά να μετατρέψετε την ημερομηνία σε συμβολοσειρά και αντίστροφα, επειδή το JSON δεν διαθέτει εγγενή δομή δεδομένων για να αντιπροσωπεύει το DateTime. Οι έννοιες που έχω περιγράψει εδώ θα σας βοηθήσουν να αποφύγετε ορισμένα από τα κοινά ζητήματα που μπορεί να προκύψουν κατά την πραγματοποίηση αυτών των μετασχηματισμών από ημερομηνία σε σειρά και συμβολοσειρά σε ημερομηνία.
Σημείωση: Ακόμα κι αν έχω χρησιμοποιήσει JavaScript Όπως η γλώσσα προγραμματισμού που αναφέρεται σε αυτό το άρθρο, αυτές είναι γενικές έννοιες που ισχύουν, σε μεγάλο βαθμό, σχεδόν σε όλες τις γλώσσες προγραμματισμού και τις βιβλιοθήκες ημερομηνιών τους. Επομένως, ακόμη και αν δεν έχετε γράψει ποτέ μια γραμμή JavaScript, μη διστάσετε να συνεχίσετε να διαβάζετε, καθώς δεν αναλαμβάνω καμία προηγούμενη γνώση της JavaScript στο άρθρο.
Το DateTime είναι μια πολύ συγκεκριμένη χρονική στιγμή. Ας το σκεφτούμε. Καθώς γράφω αυτό το άρθρο, το ρολόι στον φορητό υπολογιστή μου δείχνει 21 Ιουλίου 1:29 μ.μ. Αυτό ονομάζουμε «τοπική ώρα», την ώρα που βλέπω στα ρολόγια τοίχου γύρω μου και στο ρολόι χειρός μου.
Δώστε ή αφιερώστε λίγα λεπτά, αν ζητήσω από τον φίλο μου να με συναντήσει σε ένα κοντινό καφενείο στις 3 μ.μ., μπορώ να περιμένω να την δω εκεί περίπου εκείνη την ώρα. Ομοίως, δεν θα υπήρχε σύγχυση αν, αντίθετα, είπα, «ας συναντηθούμε σε μιάμιση ώρα». Συχνά μιλάμε για τον χρόνο με αυτόν τον τρόπο με ανθρώπους που ζουν στην ίδια πόλη ή ζώνη ώρας.
Ας σκεφτούμε ένα διαφορετικό σενάριο: Θέλω να πω σε έναν φίλο που ζει στην Ουψάλα της Σουηδίας ότι θέλω να του μιλήσω στις 5 μ.μ. Του στέλνω ένα μήνυμα, 'Γεια σου Αντόν, ας μιλήσουμε στις 5 μ.μ.' Έλαβα αμέσως την απάντηση, 'Ο χρόνος σου ή ο χρόνος μου;'
Ο Anton μου λέει ότι ζει στη ζώνη ώρας της Κεντρικής Ευρώπης που είναι UTC + 01: 00. Ζω στο UTC + 05: 45. Αυτό σημαίνει ότι όταν είναι 5 μ.μ. όπου ζω, είναι 5 μ.μ. - 05:45 = 11:15 π.μ. UTC, που μεταφράζεται σε 11:15 π.μ. UTC + 01:00 = 12:15 μ.μ. στην Ουψάλα, ιδανικό και για τα δύο από εμάς.
Επίσης, να γνωρίζετε τη διαφορά μεταξύ ζώνης ώρας (ώρα Κεντρικής Ευρώπης) και μετατόπισης ζώνης ώρας (UTC + 05: 45). Οι χώρες μπορούν να αποφασίσουν να αλλάξουν τις αντισταθμίσεις ζώνης ώρας τους για θερινή ώρα και για πολιτικούς λόγους. Σχεδόν κάθε χρόνο υπάρχει μια αλλαγή στους κανόνες σε τουλάχιστον μία χώρα, που σημαίνει ότι οποιοσδήποτε κώδικας με αυτούς τους κανόνες πρέπει να διατηρείται ενημερωμένος. Αξίζει να λάβετε υπόψη τι εξαρτάται από τη βάση κώδικα για αυτό για κάθε επίπεδο της εφαρμογής σας.
Αυτός είναι ένας άλλος καλός λόγος που προτείνουμε ότι μόνο η διεπαφή αφορά τις ζώνες ώρας στις περισσότερες περιπτώσεις. Όταν δεν συμβαίνει αυτό, τι συμβαίνει όταν οι κανόνες που χρησιμοποιεί η μηχανή βάσης δεδομένων σας δεν ταιριάζουν με εκείνους του μπροστινού ή του πίσω μέρους σας;
Αυτό το πρόβλημα της διαχείρισης δύο διαφορετικών εκδόσεων του χρόνου, σε σχέση με τον χρήστη και σε σχέση με ένα καθολικά αποδεκτό πρότυπο, είναι δύσκολο, ακόμη περισσότερο στον κόσμο του προγραμματισμού όπου η ακρίβεια είναι βασική και ακόμη και ένα δευτερόλεπτο μπορεί να κάνει τεράστια διαφορά. Το πρώτο βήμα για την επίλυση αυτών των ζητημάτων είναι η αποθήκευση DateTime σε UTC.
Η τυποποίηση της ώρας είναι υπέροχη, επειδή πρέπει να αποθηκεύσω μόνο την ώρα UTC και εφόσον γνωρίζω τη ζώνη ώρας του χρήστη, μπορώ πάντα να μετατρέπω την ώρα τους. Αντίθετα, εάν γνωρίζω την τοπική ώρα ενός χρήστη και γνωρίζω τη ζώνη ώρας του, μπορώ να το μετατρέψω σε UTC.
Αλλά οι ημερομηνίες και οι ώρες μπορούν να καθοριστούν σε πολλές διαφορετικές μορφές. Για την ημερομηνία, μπορείτε να γράψετε «30 Ιουλίου» ή «30 Ιουλίου» ή «7/30» (ή 30/7, ανάλογα με το πού ζείτε). Προς το παρόν, θα μπορούσατε να γράψετε «9:30 μ.μ.» ή «2130».
Επιστήμονες σε όλο τον κόσμο συγκεντρώθηκαν για να αντιμετωπίσουν αυτό το πρόβλημα και αποφάσισαν μια μορφή για να περιγράψουν το χρόνο που πραγματικά τους αρέσει στους προγραμματιστές επειδή είναι σύντομο και ακριβές. Μας αρέσει να το ονομάζουμε 'Μορφή ημερομηνίας ISO', η οποία είναι μια απλοποιημένη έκδοση της εκτεταμένης μορφής ISO-8601 και μοιάζει με αυτό:
Για 00:00 ή UTC, χρησιμοποιούμε το 'Z' αντ 'αυτού, που σημαίνει ώρα Zulu, άλλο όνομα για UTC.
Πριν ξεκινήσουμε με τις βέλτιστες πρακτικές, θα μάθουμε για τη χειραγώγηση ημερομηνιών χρησιμοποιώντας JavaScript για να κατανοήσουμε τη σύνταξη και τις γενικές έννοιες. Παρόλο που χρησιμοποιούμε JavaScript, μπορείτε εύκολα να προσαρμόσετε αυτές τις πληροφορίες στην αγαπημένη σας γλώσσα προγραμματισμού.
Θα χρησιμοποιήσουμε αριθμητική ημερομηνίας για την επίλυση κοινών προβλημάτων που σχετίζονται με την ημερομηνία που συναντούν οι περισσότεροι προγραμματιστές.
Ο στόχος μου είναι να σας κάνω άνετα να δημιουργήσετε ένα αντικείμενο ημερομηνίας από μια συμβολοσειρά και να εξαγάγετε στοιχεία από ένα. Αυτό είναι κάτι που μπορεί να σας βοηθήσει μια βιβλιοθήκη ημερομηνιών, αλλά είναι πάντα καλύτερο να κατανοείτε πώς γίνεται πίσω από τα παρασκήνια.
Μόλις λερώσουμε τα χέρια μας με ημερομηνία / ώρα, είναι πιο εύκολο να σκεφτούμε τα προβλήματα που αντιμετωπίζουμε, να εξαγάγουμε τις βέλτιστες πρακτικές και να προχωρήσουμε. Εάν θέλετε να προχωρήσετε στις βέλτιστες πρακτικές, μη διστάσετε να το κάνετε, αλλά σας συνιστώ ανεπιφύλακτα να διαβάσετε τουλάχιστον την ενότητα αριθμητικής ημερομηνίας παρακάτω.
Οι γλώσσες προγραμματισμού περιέχουν χρήσιμες κατασκευές για να κάνουν τη ζωή μας ευκολότερη. Η JavaScript Date
αντικείμενο είναι ένα τέτοιο πράγμα. Προσφέρει βολικές μεθόδους για να λάβετε την τρέχουσα ημερομηνία και ώρα, να αποθηκεύσετε μια ημερομηνία σε μια μεταβλητή, να εκτελέσετε αριθμητική ημερομηνίας και να μορφοποιήσετε την ημερομηνία με βάση τις τοπικές ρυθμίσεις του χρήστη.
Λόγω των διαφορών μεταξύ των εφαρμογών του προγράμματος περιήγησης και του λανθασμένου χειρισμού της θερινής ώρας (DST), δεν συνιστάται το αντικείμενο Ημερομηνία για εφαρμογές κρίσιμης σημασίας και πιθανότατα θα πρέπει να χρησιμοποιείτε μια βιβλιοθήκη DateTime όπως Luxon, date-fns ή dayjs . (Ό, τι κι αν χρησιμοποιείτε, αποφύγετε το κάποτε δημοφιλές Moment.js - συχνά απλά ονομάζεται moment
, όπως εμφανίζεται στον κώδικα - καθώς έχει πλέον καταργηθεί.)
Αλλά για εκπαιδευτικούς σκοπούς, θα χρησιμοποιήσουμε τις μεθόδους που παρέχει το αντικείμενο Date () για να μάθουμε πώς χειρίζεται το JavaScript το DateTime.
const currentDate = new Date();
Εάν δεν μεταβιβάσετε τίποτα στον κατασκευαστή ημερομηνιών, το αντικείμενο ημερομηνίας που επιστρέφεται περιέχει την τρέχουσα ημερομηνία και ώρα.
Στη συνέχεια, μπορείτε να το μορφοποιήσετε για να εξαγάγετε μόνο το τμήμα ημερομηνίας ως εξής:
const currentDate = new Date(); const currentDayOfMonth = currentDate.getDate(); const currentMonth = currentDate.getMonth(); // Be careful! January is 0, not 1 const currentYear = currentDate.getFullYear(); const dateString = currentDayOfMonth + '-' + (currentMonth + 1) + '-' + currentYear; // '27-11-2020'
Σημείωση: Η παγίδα 'Ιανουάριος είναι 0' είναι κοινή αλλά όχι καθολική. Αξίζει να κάνετε διπλό έλεγχο της τεκμηρίωσης οποιασδήποτε γλώσσας (ή μορφής διαμόρφωσης: π.χ., το cron βασίζεται κυρίως στο 1) προτού ξεκινήσετε να το χρησιμοποιείτε.
Αν θέλετε να λάβετε την τρέχουσα σφραγίδα ώρας, μπορείτε να δημιουργήσετε ένα νέο αντικείμενο ημερομηνίας και να χρησιμοποιήσετε τη μέθοδο getTime ().
const currentDate = new Date(); const timestamp = currentDate.getTime();
Στο JavaScript, μια χρονική σήμανση είναι ο αριθμός των χιλιοστών του δευτερολέπτου που έχουν περάσει από την 1η Ιανουαρίου 1970.
Εάν δεν σκοπεύετε να υποστηρίξετε Η μετατροπή μιας συμβολοσειράς σε ένα αντικείμενο ημερομηνίας JavaScript γίνεται με διαφορετικούς τρόπους. Ο κατασκευαστής του αντικειμένου Date δέχεται μια μεγάλη ποικιλία μορφών ημερομηνίας: Λάβετε υπόψη ότι δεν χρειάζεται να συμπεριλάβετε την ημέρα της εβδομάδας, επειδή η JS μπορεί να καθορίσει την ημέρα της εβδομάδας για οποιαδήποτε ημερομηνία. Μπορείτε επίσης να περάσετε το έτος, μήνα, ημέρα, ώρες, λεπτά και δευτερόλεπτα ως ξεχωριστά ορίσματα: Φυσικά, μπορείτε πάντα να χρησιμοποιήσετε τη μορφή ημερομηνίας ISO: Ωστόσο, μπορεί να αντιμετωπίσετε προβλήματα όταν δεν παρέχετε ρητά τη ζώνη ώρας! Ένα από αυτά θα σας δώσει 25 Ιουλίου 2016 00:00:00 τοπική ώρα. Εάν χρησιμοποιείτε τη μορφή ISO, ακόμη και αν δώσετε μόνο την ημερομηνία και όχι τη ζώνη ώρας και ώρας, θα αποδεχτεί αυτόματα τη ζώνη ώρας ως UTC. Αυτό σημαίνει ότι: Ευτυχώς, το σύγχρονο JavaScript έχει μερικές βολικές λειτουργίες διεθνοποίησης ενσωματωμένες στο πρότυπο Για αυτό θα χρειαστούμε δύο αντικείμενα: a Αν, αντίθετα, θέλαμε τη μορφή της Ολλανδίας (D / M / YYYY), θα μεταφέραμε έναν διαφορετικό κωδικό πολιτισμού στο Ή μια μακρύτερη μορφή της αμερικανικής μορφής, με το όνομα του μήνα να είναι γραμμένο: Τώρα, αν θέλαμε μια σωστή κανονική μορφή την ημέρα του μήνα - δηλαδή, '14ο' αντί για '14' - αυτό δυστυχώς χρειάζεται λίγο λύση, επειδή Δυστυχώς, Εάν πρέπει να υποστηρίξετε παλαιότερα προγράμματα περιήγησης όπως το IE πριν από την έκδοση 11, η μορφοποίηση ημερομηνίας σε JavaScript είναι πιο δύσκολη, επειδή δεν υπήρχαν τυπικές λειτουργίες μορφοποίησης ημερομηνίας όπως Στην PHP για παράδειγμα, η συνάρτηση Μπορείτε να χρησιμοποιήσετε ένα διαφορετικός συνδυασμός γραμμάτων πριν από το Εάν είστε βέβαιοι για τη μορφή που θέλετε να χρησιμοποιήσετε, είναι καλύτερο να εξαγάγετε μεμονωμένα bit χρησιμοποιώντας τις συναρτήσεις JavaScript που καλύψαμε παραπάνω και να δημιουργήσετε μόνοι σας μια συμβολοσειρά. Μπορούμε να πάρουμε την ημερομηνία σε μορφή MM / DD / YYYY ως Το πρόβλημα με αυτήν τη λύση είναι ότι μπορεί να δώσει μια ασυνεπή διάρκεια στις ημερομηνίες, επειδή μερικοί μήνες και ημέρες του μήνα είναι μονοψήφιο και άλλοι διψήφιοι. Αυτό μπορεί να είναι προβληματικό, για παράδειγμα, εάν προβάλλετε την ημερομηνία σε μια στήλη πίνακα, επειδή οι ημερομηνίες δεν ευθυγραμμίζονται. Μπορούμε να το αντιμετωπίσουμε χρησιμοποιώντας μια λειτουργία «pad» που προσθέτει το αρχικό 0. Τώρα, λαμβάνουμε τη σωστή ημερομηνία σε μορφή MM / DD / YYYY χρησιμοποιώντας: Αν θέλουμε DD-MM-YYYY αντ 'αυτού, η διαδικασία είναι παρόμοια: Ας ξεκινήσουμε και προσπαθήστε να εκτυπώσετε την ημερομηνία σε μορφή 'Ημερομηνία μήνα, έτος'. Χρειαζόμαστε μια αντιστοίχιση μηνιαίων ευρετηρίων με ονόματα: Μερικοί άνθρωποι θέλουν να εμφανίσουν την ημερομηνία ως την 1η Ιανουαρίου 2013. Κανένα πρόβλημα, το μόνο που χρειαζόμαστε είναι μια λειτουργία βοηθού Είναι εύκολο να προσδιορίσετε την ημέρα της εβδομάδας από το αντικείμενο ημερομηνίας, οπότε ας το προσθέσουμε σε: Το μεγαλύτερο σημείο εδώ είναι, μόλις λάβετε τους αριθμούς που εξάγονται από την ημερομηνία, η μορφοποίηση σχετίζεται κυρίως με χορδές. Μόλις ξέρετε πώς να αναλύσετε μια ημερομηνία και να τη μορφοποιήσετε, η αλλαγή μιας ημερομηνίας από τη μία μορφή στην άλλη είναι απλώς θέμα συνδυασμού των δύο. Για παράδειγμα, εάν έχετε ημερομηνία με τη μορφή 21 Ιουλίου 2013 και θέλετε να αλλάξετε τη μορφή σε 21-07-2013, μπορεί να επιτευχθεί ως εξής: Οι μέθοδοι μορφοποίησης ημερομηνίας που συζητήσαμε παραπάνω πρέπει να λειτουργούν στις περισσότερες εφαρμογές, αλλά αν θέλετε πραγματικά να εντοπίσετε τη μορφοποίηση της ημερομηνίας, σας προτείνω να χρησιμοποιήσετε το … Μας δίνει κάτι σαν Η αλλαγή της τοπικής ρύθμισης σε «en-US» δίνει αντ 'αυτού «26 Ιουλίου 2016». Παρατηρήστε πώς άλλαξε η μορφοποίηση, αλλά οι επιλογές εμφάνισης παρέμειναν οι ίδιες - μια πολύ χρήσιμη λειτουργία. Όπως φαίνεται στην προηγούμενη ενότητα, η νεότερη τεχνική που βασίζεται σε Με Αν ήθελα αντ 'αυτού ολόκληρος μήνας «Ιούλιος», το μόνο που κάνω είναι να αλλάξω την παράμετρο του μήνα στις επιλογές «long». Το JavaScript χειρίζεται τα πάντα για μένα. Για en-US, έχω τώρα 26 Ιουλίου 2016. Σημείωση: Εάν θέλετε το πρόγραμμα περιήγησης να χρησιμοποιεί αυτόματα τις τοπικές ρυθμίσεις του χρήστη, μπορείτε να μεταβιβάσετε το 'undefined' ως την πρώτη παράμετρο. Αν θέλετε να εμφανίσετε την αριθμητική έκδοση της ημερομηνίας και δεν θέλετε να συζητήσετε με MM / DD / YYYY έναντι DD / MM / YYYY για διαφορετικές τοποθεσίες, προτείνω την ακόλουθη απλή λύση: Στον υπολογιστή μου, αυτό εξάγει Αυτό εξάγει Μπορείτε επίσης να χρησιμοποιήσετε κάποιες άλλες σχετικές λειτουργίες για να εντοπίσετε τον τρόπο εμφάνισης τόσο της ώρας όσο και της ημερομηνίας: Ακολουθεί ένα παράδειγμα προσθήκης 20 ημερών σε μια Ημερομηνία JavaScript (δηλαδή, υπολογίζοντας την ημερομηνία 20 ημέρες μετά από μια γνωστή ημερομηνία): Το αρχικό αντικείμενο ημερομηνίας αντιπροσωπεύει τώρα μια ημερομηνία 20 ημέρες μετά τις 20 Ιουλίου και Για τον υπολογισμό των σχετικών χρονικών γραμματοσήμων με ακριβέστερη διαφορά από ολόκληρες τις ημέρες, μπορείτε να χρησιμοποιήσετε το Όπως με όλα τα άλλα που σχετίζονται με την ημερομηνία, η σύγκριση των ημερομηνιών έχει τα δικά της gotchas. Πρώτον, πρέπει να δημιουργήσουμε αντικείμενα ημερομηνίας. Ευτυχώς, = όλη η δουλειά. Έτσι, η σύγκριση της 19ης Ιουλίου 2014 και της 18ης Ιουλίου 2014 είναι τόσο εύκολη όσο: Ο έλεγχος για ισότητα είναι πιο δύσκολος, καθώς δύο αντικείμενα ημερομηνίας που αντιπροσωπεύουν την ίδια ημερομηνία εξακολουθούν να είναι δύο διαφορετικά αντικείμενα ημερομηνίας και δεν θα είναι ίδια. Η σύγκριση συμβολοσειρών ημερομηνιών είναι κακή ιδέα, επειδή, για παράδειγμα, '20 Ιουλίου 2014' και '20 Ιουλίου 2014' αντιπροσωπεύουν την ίδια ημερομηνία αλλά έχουν διαφορετικές αναπαραστάσεις συμβολοσειρών. Το παρακάτω απόσπασμα απεικονίζει το πρώτο σημείο: Αυτό θα εμφανίσει Αυτή η συγκεκριμένη περίπτωση μπορεί να διορθωθεί συγκρίνοντας τα ακέραια ισοδύναμα των ημερομηνιών (τα χρονικά τους γραμματόσημα) ως εξής: Έχω δει αυτό το παράδειγμα σε πολλά μέρη, αλλά δεν μου αρέσει γιατί δεν δημιουργείτε συνήθως ένα αντικείμενο ημερομηνίας από άλλο αντικείμενο ημερομηνίας. Πιστεύω λοιπόν ότι το παράδειγμα είναι σημαντικό μόνο από ακαδημαϊκή άποψη. Επίσης, αυτό απαιτεί και τα δύο αντικείμενα ημερομηνίας να αναφέρονται στο ίδιο ακριβώς δευτερόλεπτο, ενώ ίσως θέλετε να γνωρίζετε μόνο εάν αναφέρονται στην ίδια ημέρα ή ώρα ή λεπτό. Ας δούμε ένα πιο πρακτικό παράδειγμα. Προσπαθείτε να συγκρίνετε εάν τα γενέθλια που έχει εισαγάγει ο χρήστης είναι ίδια με την τυχερή ημερομηνία που λαμβάνετε από ένα API. Και οι δύο αντιπροσώπευαν την ίδια ημερομηνία, αλλά δυστυχώς ο χρήστης σας δεν θα πάρει τα εκατομμύρια δολάρια. Αυτό είναι το πρόβλημα: Το JavaScript υποθέτει πάντα τη ζώνη ώρας ως εκείνη που το παρέχει το πρόγραμμα περιήγησης, εκτός αν ορίζεται ρητώς διαφορετικά. Αυτό σημαίνει, για μένα, Δεν είναι δυνατή η αλλαγή μόνο της ζώνης ώρας ενός υπάρχοντος αντικειμένου ημερομηνίας, οπότε ο στόχος μας είναι τώρα να δημιουργήσουμε ένα νέο αντικείμενο ημερομηνίας αλλά με UTC αντί για τοπική ζώνη ώρας. Θα αγνοήσουμε τη ζώνη ώρας του χρήστη και θα χρησιμοποιήσουμε το UTC κατά τη δημιουργία του αντικειμένου ημερομηνίας. Υπάρχουν δύο τρόποι για να το κάνετε: Αυτό λειτουργεί επίσης εάν δεν καθορίσετε την ώρα, καθώς θα οριστεί ως τα μεσάνυχτα (δηλαδή, 00: 00: 00Z): Θυμηθείτε: Εάν ο κατασκευαστής ημερομηνιών περάσει μια συμβολοσειρά σε σωστή μορφή ημερομηνίας ISO YYYY-MM-DD, προϋποθέτει UTC αυτόματα. Ένα κοινό σενάριο που θα συναντήσετε είναι να βρείτε τη διαφορά μεταξύ δύο ημερομηνιών. Συζητάμε δύο περιπτώσεις χρήσης: Μετατρέψτε και τις δύο ημερομηνίες σε χρονική σήμανση UTC, βρείτε τη διαφορά σε χιλιοστά του δευτερολέπτου και βρείτε τις αντίστοιχες ημέρες. Σημείωση: Έχουμε μια μη τυπική μορφή. Διαβάστε το έγγραφο API για να προσδιορίσετε εάν αυτό σημαίνει 12 Οκτωβρίου ή 10 Δεκεμβρίου. Αλλάξτε ανάλογα τη μορφή ISO. Ξέρω ότι υπάρχουν πιο περιεκτικοί τρόποι για να γράψω αυτόν τον κώδικα, αλλά μου αρέσει να τον γράφω με αυτόν τον τρόπο λόγω της απόλυτης σαφήνειας της λογικής. Τώρα που αισθανόμαστε άνετα με την αριθμητική ημερομηνίας, είμαστε σε θέση να κατανοήσουμε τις βέλτιστες πρακτικές που πρέπει να ακολουθήσουμε και τους λόγους για τους οποίους ακολουθούμε. Εάν λαμβάνετε την ημερομηνία και την ώρα από τον χρήστη, πιθανότατα αναζητάτε τον τοπικό DateTime. Είδαμε στην αριθμητική ενότητα ημερομηνία ότι το Για να αφαιρέσετε οποιαδήποτε σύγχυση, προτείνω πάντα τη δημιουργία ημερομηνίας χρησιμοποιώντας Το δροσερό είναι ότι μπορείτε να χρησιμοποιήσετε τις παραλλαγές που σας επιτρέπουν να παραλείψετε οποιαδήποτε από τις τέσσερις τελευταίες παραμέτρους εάν είναι μηδέν. δηλαδή, Για παράδειγμα, εάν χρησιμοποιείτε ένα εργαλείο επιλογής ημερομηνίας και ώρας που σας δίνει την ημερομηνία 2012-10-12 και ώρα 12:30, μπορείτε να εξαγάγετε τα μέρη και να δημιουργήσετε ένα νέο αντικείμενο ημερομηνίας ως εξής: Προσπαθήστε να αποφύγετε τη δημιουργία μιας ημερομηνίας από μια συμβολοσειρά, εκτός εάν είναι σε μορφή ημερομηνίας ISO. Αντ 'αυτού, χρησιμοποιήστε τη μέθοδο Ημερομηνία (έτος, μήνας, ημερομηνία, ώρες, λεπτά, δευτερόλεπτα, μικροδευτερόλεπτα). Εάν λαμβάνετε μόνο την ημερομηνία, για παράδειγμα την ημερομηνία γέννησης ενός χρήστη, είναι καλύτερο να μετατρέψετε τη μορφή σε έγκυρη μορφή ημερομηνίας ISO για να εξαλείψετε τυχόν πληροφορίες ζώνης ώρας που μπορεί να προκαλέσουν μετατόπιση της ημερομηνίας προς τα εμπρός ή προς τα πίσω όταν μετατραπούν σε UTC. Για παράδειγμα: Σε περίπτωση που ξεχάσατε, εάν δημιουργήσετε ένα Να αποθηκεύετε πάντα το DateTime σε UTC. Πάντα στέλνετε μια συμβολοσειρά ημερομηνίας ISO ή μια σφραγίδα ώρας στο πίσω μέρος. Γενιές προγραμματιστών υπολογιστών έχουν συνειδητοποιήσει αυτήν την απλή αλήθεια μετά από πικρές εμπειρίες προσπαθώντας να δείξουν τη σωστή τοπική ώρα στον χρήστη. Η αποθήκευση της τοπικής ώρας στο πίσω μέρος είναι κακή ιδέα, είναι καλύτερα να αφήσετε το πρόγραμμα περιήγησης να χειριστεί τη μετατροπή σε τοπική ώρα στο μπροστινό μέρος. Επίσης, θα πρέπει να είναι προφανές ότι δεν πρέπει ποτέ να στείλετε μια συμβολοσειρά DateTime όπως '20 Ιουλίου 1989 12:10 μ.μ.' στο πίσω μέρος. Ακόμα κι αν στείλετε και τη ζώνη ώρας, αυξάνετε την προσπάθεια για άλλους προγραμματιστές να κατανοήσουν τις προθέσεις σας και να αναλύσετε και να αποθηκεύσετε την ημερομηνία σωστά. Χρησιμοποιήστε το «Μερικές φορές είναι είναι σημαντικό να γνωρίζετε τη ζώνη ώρας στην οποία συνέβη ένα συμβάν και η μετατροπή σε μία ζώνη ώρας εξαλείφει αμετάκλητα αυτές τις πληροφορίες. 'Αν κάνετε μια προώθηση μάρκετινγκ και θέλετε να μάθετε ποιοι πελάτες έκαναν παραγγελίες κατά τη διάρκεια του μεσημεριανού γεύματος, μια παραγγελία που φαίνεται να έχει υποβληθεί το μεσημέρι GMT δεν είναι πολύ χρήσιμη όταν πραγματοποιήθηκε πραγματικά για πρωινό στη Νέα Υόρκη.' Εάν συναντήσετε τέτοιου είδους καταστάσεις, θα ήταν πιο σοφό να εξοικονομήσετε και την τοπική ώρα. Ως συνήθως, θα θέλαμε να δημιουργήσουμε την ημερομηνία σε μορφή ISO, αλλά πρέπει πρώτα να βρούμε τη μετατόπιση της ζώνης ώρας. Το αντικείμενο Ημερομηνία Για τη ζώνη ώρας μου +05: 45, λαμβάνω -345, αυτό δεν είναι μόνο το αντίθετο σημάδι, αλλά ένας αριθμός όπως το -345 μπορεί να προβληματίζει εντελώς έναν προγραμματιστή back-end. Έτσι το μετατρέπουμε σε +05: 45. Τώρα λαμβάνουμε τις υπόλοιπες τιμές και δημιουργούμε μια έγκυρη συμβολοσειρά ISO που αντιπροσωπεύει το τοπικό DateTime. Εάν θέλετε, μπορείτε να τυλίξετε τις UTC και τις τοπικές ημερομηνίες σε ένα αντικείμενο. Τώρα, στο πίσω μέρος, εάν θέλετε να μάθετε εάν το συμβάν συνέβη πριν από το μεσημέρι τοπική ώρα, μπορείτε να αναλύσετε την ημερομηνία και απλά να χρησιμοποιήσετε το Δεν χρησιμοποιήσαμε το Μερικές φορές, ακόμη και με την τοπική ζώνη ώρας που είναι αποθηκευμένη, θα θέλετε να εμφανίζονται οι ημερομηνίες σε μια συγκεκριμένη ζώνη ώρας. Για παράδειγμα, οι ώρες για συμβάντα μπορεί να έχουν μεγαλύτερη σημασία στη ζώνη ώρας του τρέχοντος χρήστη, εάν είναι εικονικές ή στη ζώνη ώρας όπου θα πραγματοποιηθούν φυσικά, εάν δεν είναι. Σε κάθε περίπτωση, αξίζει να το κοιτάξετε εκ των προτέρων καθιερωμένες λύσεις για μορφοποίηση με ρητά ονόματα ζώνης ώρας. Διαμορφώστε πάντα τους διακομιστές και τις βάσεις δεδομένων σας για να χρησιμοποιήσετε τη ζώνη ώρας UTC. (Σημειώστε ότι είναι UTC και GMT όχι το ίδιο πράγμα —Το GMT, για παράδειγμα, μπορεί να σημαίνει μετάβαση σε BST κατά τη διάρκεια του καλοκαιριού, ενώ το UTC δεν θα το κάνει ποτέ.) Έχουμε ήδη δει πόσο μπορούν να είναι οι μετατροπές ζώνης ώρας πόνου, ειδικά όταν είναι ακούσιες. Πάντα η αποστολή UTC DateTime και η διαμόρφωση των διακομιστών σας ώστε να βρίσκονται στη ζώνη ώρας UTC μπορούν να κάνουν τη ζωή σας πιο εύκολη. Ο κωδικός υποστήριξης θα είναι πολύ πιο απλός και καθαρότερος, καθώς δεν χρειάζεται να κάνετε μετατροπές ζώνης ώρας. Τα δεδομένα DateTime που προέρχονται από διακομιστές σε όλο τον κόσμο μπορούν να συγκριθούν και να ταξινομηθούν χωρίς κόπο. Ο κώδικας στο πίσω μέρος θα πρέπει να μπορεί να υποθέσει ότι η ζώνη ώρας του διακομιστή είναι UTC (αλλά πρέπει να υπάρχει έλεγχος για να είναι σίγουρος). Ένας απλός έλεγχος διαμόρφωσης εξοικονομεί την ανάγκη να σκεφτόμαστε και να κωδικοποιούμε τις μετατροπές κάθε φορά που γράφεται νέος κωδικός DateTime. Ο χειρισμός ημερομηνίας είναι ένα δύσκολο πρόβλημα. Οι έννοιες πίσω από τα πρακτικά παραδείγματα σε αυτό το άρθρο ισχύουν πέρα από το JavaScript, και είναι μόνο η αρχή όσον αφορά τον σωστό χειρισμό δεδομένων και υπολογισμών DateTime. Επιπλέον, κάθε βιβλιοθήκη βοηθών θα συνοδεύεται το δικό του σετ αποχρώσεων. Η κατώτατη γραμμή είναι: Χρησιμοποιήστε το ISO στο πίσω μέρος και αφήστε το μπροστινό μέρος για να μορφοποιήσετε τα πράγματα σωστά για τον χρήστη. Οι επαγγελματίες προγραμματιστές θα γνωρίζουν μερικές από τις αποχρώσεις και θα χρησιμοποιούν (πολύ πιο αποφασιστικά) καλά υποστηριζόμενες βιβλιοθήκες DateTime τόσο στο πίσω μέρος όσο και στο μπροστινό μέρος. Οι ενσωματωμένες λειτουργίες από την πλευρά της βάσης δεδομένων είναι μια άλλη ιστορία, αλλά ελπίζουμε ότι αυτό το άρθρο δίνει αρκετό υπόβαθρο για να πάρει σοφότερες αποφάσεις και σε αυτό το πλαίσιο.Ανάλυση ημερομηνίας
Date.now()
const date1 = new Date('Wed, 27 July 2016 13:30:00'); const date2 = new Date('Wed, 27 July 2016 07:45:00 UTC'); const date3 = new Date('27 July 2016 13:30:00 UTC+05:45');
const date = new Date(2016, 6, 27, 13, 30, 0);
const date = new Date('2016-07-27T07:45:00Z');
const date1 = new Date('25 July 2016'); const date2 = new Date('July 25, 2016');
Μορφοποίηση ημερομηνίας
new Date('25 July 2016').getTime() !== new Date('2016-07-25').getTime() new Date('2016-07-25').getTime() === new Date('2016-07-25T00:00:00Z').getTime()
namespace που κάνουν τη μορφοποίηση ημερομηνίας μια απλή λειτουργία.Intl
και ένα Date
, αρχικοποιήθηκε με τις προτιμήσεις εξόδου μας. Ας υποθέσουμε ότι θα θέλαμε να χρησιμοποιήσουμε την αμερικανική (Μ / Η / ΕΕΕΕ) μορφή, θα μοιάζει με:Intl.DateTimeFormat
const firstValentineOfTheDecade = new Date(2020, 1, 14); // 1 for February const enUSFormatter = new Intl.DateTimeFormat('en-US'); console.log(enUSFormatter.format(firstValentineOfTheDecade)); // 2/14/2020
κατασκευαστής:DateTimeFormat
const nlBEFormatter = new Intl.DateTimeFormat('nl-BE'); console.log(nlBEFormatter.format(firstValentineOfTheDecade)); // 14/2/2020
const longEnUSFormatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', }); console.log(longEnUSFormatter.format(firstValentineOfTheDecade)); // February 14, 2020
οι έγκυρες τιμές είναι μόνο αυτής της γραφής είναι day
ή 'numeric'
. Δανεισμός Έκδοση Flavio Copes του Ο κωδικός Mathias Bynens να αξιοποιήσει ένα άλλο μέρος του '2-digit'
για αυτό, μπορούμε να προσαρμόσουμε την έξοδο της ημέρας του μήνα μέσω Intl
:formatToParts()
const pluralRules = new Intl.PluralRules('en-US', { type: 'ordinal' }) const suffixes = { 'one': 'st', 'two': 'nd', 'few': 'rd', 'other': 'th' } const convertToOrdinal = (number) => `${number}${suffixes[pluralRules.select(number)]}` // At this point: // convertToOrdinal('1') === '1st' // convertToOrdinal('2') === '2nd' // etc. const extractValueAndCustomizeDayOfMonth = (part) => { if (part.type === 'day') { return convertToOrdinal(part.value); } return part.value; }; console.log( longEnUSFormatter.formatToParts(firstValentineOfTheDecade) .map(extractValueAndCustomizeDayOfMonth) .join('') ); // February 14th, 2020
δεν υποστηρίζεται καθόλου από τον Internet Explorer (IE) από αυτήν τη γραφή, αλλά όλες οι άλλες τεχνολογίες επιτραπέζιων υπολογιστών, κινητών και back-end (δηλ. Node.js) έχουν υποστήριξη . Για εκείνους που πρέπει να υποστηρίξουν το IE και χρειάζονται απολύτως τακτικά, το sidenote παρακάτω (ή καλύτερα, μια σωστή βιβλιοθήκη ημερομηνιών) παρέχει μια απάντηση.formatToParts
σε Python ή PHP.strftime
σας δίνει strftime('Today is %b %d %Y %X', mktime(5,10,0,12,30,99))
.Today is Dec 30 1999 05:10:00
για να λάβετε την ημερομηνία σε διαφορετικές μορφές. (Προσεκτικά, κάθε γλώσσα δεν αποδίδει το ίδιο νόημα σε κάθε γράμμα - ιδιαίτερα, τα 'M' και 'm' μπορούν να ανταλλάσσονται για λεπτά και μήνες.)%
var currentDate = new Date(); var date = currentDate.getDate(); var month = currentDate.getMonth(); var year = currentDate.getFullYear();
var monthDateYear = (month+1) + '/' + date + '/' + year;
function pad(n) { return n<10 ? '0'+n : n; }
var mmddyyyy = pad(month + 1) + '/' + pad(date) + '/' + year;
var ddmmyyyy = pad(date) + '-' + pad(month + 1) + '-' + year;
var monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; var dateWithFullMonthName = monthNames[month] + ' ' + pad(date) + ', ' + year;
που επιστρέφει 1η για 1, 12η για 12 και 103η για 103, κ.λπ., και τα υπόλοιπα είναι απλά:ordinal
var ordinalDate = ordinal(date) + ' ' + monthNames[month] + ', ' + year;
Αλλαγή της μορφής ημερομηνίας
var daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; ordinalDateWithDayOfWeek = daysOfWeek[currentDate.getDay()] + ', ' + ordinalDate;
Χρήση των λειτουργιών εντοπισμού του αντικειμένου ημερομηνίας JavaScript
const myDate = new Date('Jul 21, 2013'); const dayOfMonth = myDate.getDate(); const month = myDate.getMonth(); const year = myDate.getFullYear(); function pad(n) { return n<10 ? '0'+n : n } const ddmmyyyy = pad(dayOfMonth) + '-' + pad(month + 1) + '-' + year; // '21-07-2013'
του αντικειμένου Date
μέθοδος:toLocaleDateString()
const today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric', });
.26 Jul 2016
λειτουργεί πολύ παρόμοια με αυτήν, αλλά σας επιτρέπει να επαναχρησιμοποιήσετε ένα αντικείμενο μορφοποίησης, ώστε να χρειάζεται να ορίσετε επιλογές μόνο μία φορά.Intl.DateTimeFormat
, είναι καλή συνήθεια να περνάτε πάντα τις επιλογές μορφοποίησης, ακόμη και αν η έξοδος φαίνεται ωραία στον υπολογιστή σας. Αυτό μπορεί να προστατεύσει τη διεπαφή χρήστη από το σπάσιμο σε απροσδόκητες τοποθεσίες με πολύ μεγάλα ονόματα μηνών ή να φαίνεται αμήχανη λόγω μικρών.toLocaleDateString()
const today = new Date().toLocaleDateString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', });
. Εάν θέλετε να βεβαιωθείτε ότι ο μήνας και η ημερομηνία έχουν δύο ψηφία, απλώς αλλάξτε τις επιλογές:7/26/2016
const today = new Date().toLocaleDateString(undefined, { day: '2-digit', month: '2-digit', year: 'numeric', });
. Ακριβώς αυτό που θέλαμε!
Κώδικας Παραγωγή Περιγραφή 07/26/2016
'4:21:38 ΠΜ' Εμφάνιση τοπικής μεταφρασμένης έκδοσης μόνο του χρόνου now.toLocaleTimeString()
'04: 21: 38 ΠΜ ' Εμφάνιση τοπικής ώρας βάσει των παρεχόμενων επιλογών now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
'22/7/2016, 4:21:38 ΠΜ' Εμφάνιση ημερομηνίας και ώρας για τις τοπικές ρυθμίσεις του χρήστη now.toLocaleString()
'22/7/2016, 04:21 ΠΜ' Εμφάνιση τοπικής ημερομηνίας και ώρας βάσει των παρεχόμενων επιλογών Υπολογισμός σχετικών ημερομηνιών και ωρών
now.toLocaleString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', });
const myDate = new Date('July 20, 2016 15:00:00'); const nextDayOfMonth = myDate.getDate() + 20; myDate.setDate(nextDayOfMonth); const newDate = myDate.toLocaleString();
περιέχει μια τοπική συμβολοσειρά που αντιπροσωπεύει αυτήν την ημερομηνία. Στο πρόγραμμα περιήγησής μου, newDate
περιέχει '8/9/2016, 3:00:00 μ.μ.'newDate
και Date.getTime()
για να εργαστείτε με ακέραιους αριθμούς που αντιπροσωπεύουν τον αριθμό των χιλιοστών του δευτερολέπτου από μια συγκεκριμένη εποχή, δηλαδή την 1η Ιανουαρίου 1970. Για παράδειγμα, αν θέλετε να μάθετε πότε είναι 17 ώρες μετά από αυτήν τη στιγμή:Date.setTime()
Σύγκριση ημερομηνιών
const msSinceEpoch = (new Date()).getTime(); const seventeenHoursLater = new Date(msSinceEpoch + 17 * 60 * 60 * 1000);
const date1 = new Date('July 19, 2014'); const date2 = new Date('July 28, 2014'); if(date1 > date2) { console.log('First date is more recent'); } else { console.log('Second date is more recent'); }
const date1 = new Date('June 10, 2003'); const date2 = new Date(date1); const equalOrNot = date1 == date2 ? 'equal' : 'not equal'; console.log(equalOrNot);
.not equal
date1.getTime() == date2.getTime()
const userEnteredString = '12/20/1989'; // MM/DD/YYYY format const dateStringFromAPI = '1989-12-20T00:00:00Z'; const dateFromUserEnteredString = new Date(userEnteredString) const dateFromAPIString = new Date(dateStringFromAPI); if (dateFromUserEnteredString.getTime() == dateFromAPIString.getTime()) { transferOneMillionDollarsToUserAccount(); } else { doNothing(); }
θα δημιουργήσει μια ημερομηνία 1989-12-20T00: 00: 00 + 5: 45 ή 1989-12-19T18: 15: 00Z, η οποία δεν είναι η ίδια με 1989-12-20T00: 00: 00Z όσον αφορά τη χρονική σήμανση.
new Date ('12/20/1989')
const userEnteredDate = '12/20/1989'; const parts = userEnteredDate.split('/'); const userEnteredDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const userEnteredDateObj = new Date(userEnteredDateISO + 'T00:00:00Z'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true
const userEnteredDate = new Date('1989-12-20'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true
Βρίσκοντας τη διαφορά μεταξύ δύο ημερομηνιών
Εύρεση του αριθμού των ημερών μεταξύ δύο ημερομηνιών
const userEnteredDate = new Date('12/20/1989'); const userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateTimeStamp == dateFromAPI.getTime(); // true ...
Εύρεση της ηλικίας του χρήστη από την ημερομηνία γέννησής τους
const dateFromAPI = '2016-02-10T00:00:00Z'; const now = new Date(); const datefromAPITimeStamp = (new Date(dateFromAPI)).getTime(); const nowTimeStamp = now.getTime(); const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp); // Math.round is used instead of Math.floor to account for certain DST cases // Number of milliseconds per day = // 24 hrs/day * 60 minutes/hour * 60 seconds/minute * 1000 ms/second const daysDiff = Math.round(microSecondsDiff / (1000 * 60 * 60 * 24)); console.log(daysDiff);
const birthDateFromAPI = '12/10/1989';
Προτάσεις για αποφυγή Date Hell
Λήψη DateTime από το χρήστη
const parts = birthDateFromAPI.split('/'); const birthDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const birthDate = new Date(birthDateISO); const today = new Date(); let age = today.getFullYear() - birthDate.getFullYear(); if(today.getMonth()
Date
μορφή ακόμη και αν έχετε ήδη την ημερομηνία σε έγκυρη μορφή με δυνατότητα ανάλυσης. Εάν όλοι οι προγραμματιστές της ομάδας σας ακολουθήσουν αυτόν τον απλό κανόνα, θα είναι εξαιρετικά εύκολο να διατηρήσετε τον κώδικα μακροπρόθεσμα, καθώς είναι τόσο σαφής όσο μπορείτε με το new Date(year, month, day, hours, minutes, seconds, milliseconds)
κατασκευαστής.Date
είναι το ίδιο με new Date(2012, 10, 12)
επειδή οι μη καθορισμένες παράμετροι είναι μηδενικές.new Date(2012, 10, 12, 0, 0, 0, 0)
Λήψη μόνο της ημερομηνίας
const dateFromPicker = '2012-10-12'; const timeFromPicker = '12:30'; const dateParts = dateFromPicker.split('-'); const timeParts = timeFromPicker.split(':'); const localDate = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1]);
const dateFromPicker = '12/20/2012'; const dateParts = dateFromPicker.split('/'); const ISODate = dateParts[2] + '-' + dateParts[0] + '-' + dateParts[1]; const birthDate = new Date(ISODate).toISOString();
αντικείμενο με την εισαγωγή σε έγκυρη μορφή ημερομηνίας ISO (ΕΕΕΕ-ΜΜ-ΗΗ), θα προεπιλεγεί σε UTC αντί να προεπιλεγεί στη ζώνη ώρας του προγράμματος περιήγησης.Αποθήκευση της ημερομηνίας
Date
ή toISOString()
μεθόδους του αντικειμένου Date για να μετατρέψετε το τοπικό DateTime σε UTC.toJSON()
Εμφάνιση της ημερομηνίας και της ώρας
const dateFromUI = '12-13-2012'; const timeFromUI = '10:20'; const dateParts = dateFromUI.split('-'); const timeParts = timeFromUI.split(':'); const date = new Date(dateParts[2], dateParts[0]-1, dateParts[1], timeParts[0], timeParts[1]); const dateISO = date.toISOString(); $.post('http://example.com/', {date: dateISO}, ...)
αντικείμενο.Date
ή toLocaleString()
και toLocaleDateString()
μεθόδους ή μια βιβλιοθήκη ημερομηνιών για να εμφανιστεί η τοπική ώρα.toLocaleTimeString()
Πότε πρέπει να αποθηκεύσετε την τοπική ώρα;
const dateFromAPI = '2016-01-02T12:30:00Z'; const localDate = new Date(dateFromAPI); const localDateString = localDate.toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric', }); const localTimeString = localDate.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
Η συνάρτηση μας λέει τον αριθμό των λεπτών που όταν προστίθενται σε μια δεδομένη τοπική ώρα δίνει την ισοδύναμη ώρα UTC. Προτείνω να το μετατρέψετε σε μορφή (+ -) hh: mm γιατί καθιστά πιο προφανές ότι είναι μια μετατόπιση ζώνης ώρας.getTimeZoneOffset()
const now = new Date(); const tz = now.gettime zoneOffset();
const sign = tz > 0 ? '-' : '+'; const hours = pad(Math.floor(Math.abs(tz)/60)); const minutes = pad(Math.abs(tz)%60); const tzOffset = sign + hours + ':' + minutes;
const localDateTime = now.getFullYear() + '-' + pad(now.getMonth()+1) + '-' + pad(now.getDate()) + 'T' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
const eventDate = { utc: now.toISOString(), local: localDateTime, tzOffset: tzOffset, }
λειτουργία.getHours()
const localDateString = eventDate.local; const localDate = new Date(localDateString); if(localDate.getHours() <12) { console.log('Event happened before noon local time'); }
εδώ, αλλά εξακολουθούμε να το αποθηκεύουμε γιατί ίσως χρειαστεί στο μέλλον για σκοπούς εντοπισμού σφαλμάτων. Θα μπορούσατε στην πραγματικότητα να στείλετε απλώς τη μετατόπιση ζώνης ώρας και την ώρα UTC μόνο. Αλλά μου αρέσει επίσης να αποθηκεύω την τοπική ώρα γιατί τελικά θα πρέπει να αποθηκεύσετε την ημερομηνία σε μια βάση δεδομένων και η αποθήκευση της τοπικής ώρας χωριστά σας επιτρέπει να κάνετε απευθείας ερωτήσεις βάσει ενός πεδίου αντί να χρειάζεται να κάνετε υπολογισμούς για να λάβετε την τοπική ημερομηνία.Διαμόρφωση διακομιστή και βάσης δεδομένων
Είναι ώρα για καλύτερο χειρισμό ημερομηνιών