Χωρίς μεταφόρτωση, 100% τοπικά, χωρίς λογαριασμό

Άρθρο

Unix timestamps και cron expressions εξηγούνται

Ένα Unix timestamp είναι απλώς ένας ακέραιος αριθμός. Μια cron expression είναι απλώς πέντε πεδία. Και τα δύο εμφανίζονται συνεχώς στη backend εργασία και και τα δύο μπερδεύουν τους ανθρώπους με προβλέψιμους τρόπους: το ένα λόγω ζωνών ώρας, το άλλο λόγω της μονάδας.

Τι είναι ένα Unix timestamp

Ένα Unix timestamp μετρά τον αριθμό δευτερολέπτων που έχουν παρέλθει από την 1970-01-01 00:00:00 UTC, ένα σημείο αναφοράς γνωστό ως η Unix epoch. Αυτός ο ορισμός έχει δύο σημαντικές συνέπειες. Πρώτον, η μέτρηση είναι σε UTC: δεν υπάρχει καμία ζώνη ώρας ενσωματωμένη στον ίδιο τον αριθμό. Το 1718400000 σημαίνει την ίδια στιγμή παντού στη Γη ανεξάρτητα από το πού βρίσκεται το μηχάνημα που το αποθηκεύει. Δεύτερον, η epoch ορίζεται σε δευτερόλεπτα, όχι σε άλλη μονάδα. Μια τιμή όπως το 1718400000 είναι πάντα δευτερόλεπτα από τα μεσάνυχτα 1 Ιανουαρίου 1970 UTC, εκτός αν ένα σύστημα ή πρωτόκολλο έχει κάνει ρητά διαφορετική επιλογή. Τα timestamps είναι εκ σχεδιασμού χωρίς ζώνη ώρας, κάτι που ακριβώς τα κάνει χρήσιμα για καταγραφή, βάσεις δεδομένων και επικοινωνία μεταξύ συστημάτων όπου τα ρολόγια σε διαφορετικές περιοχές πρέπει να αναφέρονται στην ίδια στιγμή αδιαμφισβήτητα.

Χρονολόγιο που δείχνει τη Unix epoch στις 1970-01-01 00:00:00 UTC στα αριστερά, ένα τρέχον timestamp στη μέση και το όριο υπερχείλισης 2038 στα δεξιά, σημειωμένο με το μέγιστο 32-bit υπογεγραμμένου ακέραιου.

Δευτερόλεπτα, χιλιοστά του δευτερολέπτου και το πρόβλημα του έτους 2038

Πολλά σύγχρονα runtimes και APIs χρησιμοποιούν χιλιοστά του δευτερολέπτου αντί για δευτερόλεπτα. Το Date.now() της JavaScript επιστρέφει χιλιοστά του δευτερολέπτου, οπότε το 1718400000000 είναι η ίδια στιγμή με την τιμή ακρίβειας δευτερολέπτου 1718400000. Όταν λαμβάνετε ένα άγνωστο timestamp, το μέγεθος σας λέει τη μονάδα: ένας αριθμός 10 ψηφίων είναι σχεδόν πάντα δευτερόλεπτα. Ένας αριθμός 13 ψηφίων είναι σχεδόν πάντα χιλιοστά του δευτερολέπτου. Το πρόβλημα του έτους 2038 προκύπτει από μια διαφορετική επιλογή: αποθήκευση timestamp ακρίβειας δευτερολέπτου σε έναν υπογεγραμμένο 32-bit ακέραιο. Η μέγιστη τιμή ενός υπογεγραμμένου 32-bit ακέραιου είναι 2147483647, που αντιστοιχεί στις 2038-01-19 03:14:07 UTC. Μετά από αυτό το δευτερόλεπτο, ο μετρητής υπερχειλίζει σε μεγάλο αρνητικό αριθμό και η ημερομηνία επιστρέφει στο 1901 σε συστήματα που δεν χειρίζονται το όριο. Η διόρθωση είναι να χρησιμοποιηθεί αποθήκευση 64-bit. Τα περισσότερα τρέχοντα λειτουργικά συστήματα και βάσεις δεδομένων το κάνουν ήδη, αλλά ενσωματωμένα συστήματα, δικτυακές συσκευές και παλιές μορφές αρχείων που καθόρισαν το πλάτος πεδίου δεκαετίες πριν παραμένουν σε κίνδυνο.

Μετατροπή epoch σε ανθρώπινη ημερομηνία: το βήμα της ζώνης ώρας

Η μετατροπή μιας τιμής epoch σε αναγνώσιμη ημερομηνία απαιτεί δύο βήματα: ανάκτηση των συνιστωσών ημερομηνίας UTC από τον ακέραιο, στη συνέχεια εφαρμογή απόκλισης UTC για λήψη τοπικής ώρας. Το ίδιο το timestamp είναι UTC. Όταν ρωτάτε τι ημερομηνία αντιπροσωπεύει το 1718325000, η σωστή απάντηση είναι 2024-06-14 στις 00:30 σε UTC. Στη Νέα Υόρκη (UTC-4 το καλοκαίρι), αυτό το ίδιο δευτερόλεπτο εμπίπτει στις 2024-06-13 στις 20:30, το προηγούμενο βράδυ: η ημερομηνία αλλάζει, όχι μόνο η ώρα. Αυτό είναι το βήμα που παράγει λάθος αποτελέσματα όταν παραλείπεται: ένας προγραμματιστής καταγράφει το ακατέργαστο timestamp σε UTC, ένα εργαλείο αναφοράς το αποδίδει σε τοπική ώρα χωρίς μετατροπή και η ημερομηνία φαίνεται να είναι λανθασμένη κατά ώρες ή ολόκληρη ημέρα. Το εργαλείο timestamp-converter στο Sunasty χειρίζεται αυτό ρητά: εισάγετε μια τιμή epoch και εμφανίζει την ημερομηνία και ώρα UTC δίπλα στη δική σας τοπική ημερομηνία και ώρα της συσκευής σας, ώστε μια αλλαγή ημέρας όπως αυτή να είναι ορατή με μια ματιά. Η μετατροπή εκτελείται εξ ολοκλήρου στο πρόγραμμα περιήγησης και τίποτα από αυτά που επικολλάτε δεν αποστέλλεται πουθενά.

Δύο πλέγματα ημερολογίου δίπλα-δίπλα για την ίδια τιμή epoch: το πλέγμα UTC επισημαίνει μία ημερολογιακή ημέρα και το πλέγμα Νέας Υόρκης (UTC-4) επισημαίνει την προηγούμενη ημέρα, δείχνοντας πώς η τοπική ημερομηνία μετακινείται προς τα πίσω λόγω της διαφοράς ώρας.

Σύνταξη cron: πέντε πεδία, εύρη, βήματα και λίστες

Μια cron expression προγραμματίζει επαναλαμβανόμενες εργασίες σε συστήματα τύπου Unix. Η τυπική σύνταξη έχει πέντε πεδία διαχωρισμένα με κενά: λεπτό (0-59), ώρα (0-23), ημέρα-μήνα (1-31), μήνας (1-12), ημέρα-εβδομάδας (0-7, όπου και το 0 και το 7 αντιπροσωπεύουν την Κυριακή). Ένας αστερίσκος (*) σε ένα πεδίο σημαίνει «κάθε έγκυρη τιμή». Η έκφραση 30 8 * * 1-5 εκτελείται στις 08:30 Δευτέρα έως Παρασκευή. Τα εύρη χρησιμοποιούν παύλα: 1-5 καλύπτει τιμές 1, 2, 3, 4, 5. Οι λίστες χρησιμοποιούν κόμματα: 1,15 σημαίνει 1η και 15η. Τα βήματα χρησιμοποιούν κάθετο: */15 στο πεδίο λεπτού σημαίνει κάθε 15 λεπτά (0, 15, 30, 45). Αυτοί οι συνδυαστές μπορούν να εμφανιστούν μαζί: 0-30/10 σημαίνει 0, 10, 20, 30. Ένα πράγμα που δεν έχει η cron είναι ένα πεδίο ζώνης ώρας. Ο daemon διαβάζει το ρολόι του μηχανήματος στο οποίο λειτουργεί, που ρυθμίζεται στην τοπική ζώνη ώρας του διακομιστή. Αν ο διακομιστής λειτουργεί σε UTC αλλά ένας προγραμματιστής περιμένει τοπική ώρα, το πρόγραμμα εκτελείται στη λάθος ώρα ρολογιού. Ο πρακτικός κανόνας είναι να αντιμετωπίζετε τα προγράμματα cron ως εκφράσεις τοπικής-ώρας-διακομιστή και να τεκμηριώνετε τη ζώνη ώρας του διακομιστή δίπλα στη γραμμή cron.

Χρήση του timestamp-converter τοπικά

Το timestamp-converter στο Sunasty μετατρέπει και στις δύο κατευθύνσεις: epoch σε ανθρώπινη ημερομηνία και ανθρώπινη ημερομηνία πίσω σε epoch. Μπορείτε να εισάγετε τιμή ακρίβειας δευτερολέπτου ή τιμή ακρίβειας χιλιοστού δευτερολέπτου. Το εργαλείο εντοπίζει τη μονάδα από το μέγεθος. Εμφανίζει το αποτέλεσμα σε UTC και στην τοπική ζώνη ώρας της συσκευής σας δίπλα-δίπλα, μαζί με τις ακατέργαστες τιμές σε δευτερόλεπτα και χιλιοστά δευτερολέπτου έτοιμες για αντιγραφή. Ένα κουμπί Now συμπληρώνει το τρέχον timestamp με ένα κλικ, κάτι που είναι ένας γρήγορος τρόπος να ελέγξετε την τρέχουσα Unix time χωρίς να ανοίξετε terminal. Δεν υπάρχει ξεχωριστός επιλογέας ζώνης ώρας: η στήλη τοπικής ώρας αντικατοπτρίζει πάντα όποια ζώνη ώρας έχει ρυθμισμένη αυτή τη στιγμή το πρόγραμμα περιήγησής σας. Όλα αυτά εκτελούνται στο πρόγραμμα περιήγησης. Η τιμή που επικολλάτε στο πεδίο διαβάζεται από JavaScript στο πρόγραμμα-πελάτη και δεν εγκαταλείπει ποτέ τη συσκευή.

Εργαλεία αυτού του άρθρου

Συχνές ερωτήσεις

Γιατί η JavaScript χρησιμοποιεί χιλιοστά του δευτερολέπτου αντί για δευτερόλεπτα;

Το αντικείμενο Date της JavaScript σχεδιάστηκε για να λειτουργεί με ακρίβεια υπο-δευτερολέπτου από την αρχή, και τα χιλιοστά του δευτερολέπτου δίνουν χίλιες φορές μεγαλύτερη ανάλυση από τα δευτερόλεπτα χωρίς να απαιτείται δεκαδικό σημείο. Το αντάλλαγμα είναι ότι οι τιμές είναι μεγαλύτερες, γι' αυτό το Date.now() παράγει αριθμό 13 ψηφίων ενώ τα περισσότερα server-side timestamps είναι 10 ψηφίων.

Πρέπει κάθε διακομιστής που εκτελεί cron να είναι σε UTC;

Όχι, αλλά η λειτουργία διακομιστών σε UTC είναι κοινή πρακτική ακριβώς επειδή αφαιρεί την αμφισημία. Όταν ένας διακομιστής είναι σε UTC, μια έκφραση cron όπως 0 2 * * * σημαίνει 02:00 UTC και αυτή η ώρα είναι σταθερή καθ' όλη τη διάρκεια του έτους. Σε διακομιστή σε ζώνη που εφαρμόζει θερινή ώρα, η ίδια εργασία εκτελείται σε διαφορετική UTC στιγμή το καλοκαίρι και τον χειμώνα και μπορεί να εκτελεστεί δύο φορές ή να παραλειφθεί μία φορά στο όριο αλλαγής ρολογιού.

Ποιος είναι ο ασφαλής τύπος αποθήκευσης για timestamps μετά το 2038;

Ένας υπογεγραμμένος 64-bit ακέραιος αποθηκεύει timestamps ακρίβειας δευτερολέπτου μέχρι το έτος 292277026596, κάτι που εκτείνεται πολύ πέρα από οποιαδήποτε πρακτική ανησυχία. Τα περισσότερα τρέχοντα συστήματα βάσεων δεδομένων αποθηκεύουν timestamps ως 64-bit τιμές εξ ορισμού. Αν εργάζεστε με παλαιό σχήμα ή δυαδική μορφή αρχείου που χρησιμοποιεί 32-bit πεδία, η μετεγκατάσταση σε αποθήκευση 64-bit πριν το όριο 2038 είναι η σωστή διόρθωση.