Ελληνικά

Ένας περιεκτικός οδηγός για τη χρήση του Temporal API της JavaScript για ακριβείς και διαισθητικούς υπολογισμούς χρονικών διαστημάτων, καλύπτοντας τα πάντα, από τη βασική δημιουργία διάρκειας έως προχωρημένη αριθμητική και μορφοποίηση.

Διάρκεια Temporal JavaScript: Ελέγχοντας τους Υπολογισμούς Διαστήματος Χρόνου

Το Temporal API της JavaScript εισάγει έναν σύγχρονο και ισχυρό τρόπο διαχείρισης ημερομηνιών, ωρών και χρονικών διαστημάτων. Το αντικείμενο Temporal.Duration αντιπροσωπεύει ένα χρονικό διάστημα, παρέχοντας μια σαφή και διαισθητική προσέγγιση για την εκτέλεση υπολογισμών με χρονικά διαστήματα. Αυτό το άρθρο εμβαθύνει στις λεπτομέρειες του Temporal.Duration, δείχνοντας πώς να δημιουργείτε, να χειρίζεστε και να μορφοποιείτε διάρκειες για διάφορες περιπτώσεις χρήσης.

Τι είναι το Temporal.Duration;

Το Temporal.Duration αντιπροσωπεύει ένα χρονικό διάστημα, εκφράζοντάς το σε όρους ετών, μηνών, ημερών, ωρών, λεπτών, δευτερολέπτων και κλασμάτων του δευτερολέπτου (χιλιοστά του δευτερολέπτου, μικροδευτερόλεπτα, νανοδευτερόλεπτα). Σε αντίθεση με τα αντικείμενα Date που αντιπροσωπεύουν ένα συγκεκριμένο χρονικό σημείο, το Temporal.Duration αντιπροσωπεύει ένα χρονικό διάστημα. Συμμορφώνεται με τη μορφή διάρκειας ISO 8601 (π.χ., P1Y2M10DT2H30M αντιπροσωπεύει 1 έτος, 2 μήνες, 10 ημέρες, 2 ώρες και 30 λεπτά). Το Temporal API έχει σχεδιαστεί για να είναι πιο διαισθητικό και λιγότερο επιρρεπές σε σφάλματα από το παλαιότερο αντικείμενο Date.

Δημιουργία αντικειμένων Temporal.Duration

Υπάρχουν αρκετοί τρόποι για να δημιουργήσετε αντικείμενα Temporal.Duration:

1. Από ένα Plain Object

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

const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Έξοδος: P1Y2M10DT2H30M

Αυτό δημιουργεί μια διάρκεια 1 έτους, 2 μηνών, 10 ημερών, 2 ωρών και 30 λεπτών. Λάβετε υπόψη ότι τα ορίσματα αντιστοιχούν στην ακόλουθη σειρά: years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds.

2. Από μια συμβολοσειρά ISO 8601

Μπορείτε επίσης να δημιουργήσετε μια διάρκεια από μια συμβολοσειρά διάρκειας ISO 8601 χρησιμοποιώντας το Temporal.Duration.from():

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Έξοδος: P1Y2M10DT2H30M

Αυτό είναι ιδιαίτερα χρήσιμο όταν ασχολείστε με διάρκειες που είναι αποθηκευμένες σε μορφή συμβολοσειράς ή λαμβάνονται από εξωτερική πηγή.

3. Χρήση των μεθόδων add() και subtract() με Temporal.Instant, Temporal.ZonedDateTime, κ.λπ.

Όταν προσθέτετε ή αφαιρείτε Temporal.Duration από άλλους τύπους Temporal (όπως Temporal.Instant ή Temporal.ZonedDateTime), επιστρέφεται ένα Temporal.Duration που αντιπροσωπεύει τη διαφορά μεταξύ των δύο χρονικών στιγμών αν στη συνέχεια τα αφαιρέσετε. Για παράδειγμα:

const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // Έξοδος: PT5H

Πρόσβαση στα στοιχεία διάρκειας

Μπορείτε να αποκτήσετε πρόσβαση στα μεμονωμένα στοιχεία ενός αντικειμένου Temporal.Duration χρησιμοποιώντας τις ιδιότητές του:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years);      // Έξοδος: 1
console.log(duration.months);     // Έξοδος: 2
console.log(duration.days);       // Έξοδος: 10
console.log(duration.hours);      // Έξοδος: 2
console.log(duration.minutes);     // Έξοδος: 30
console.log(duration.seconds);     // Έξοδος: 0
console.log(duration.milliseconds); // Έξοδος: 0
console.log(duration.microseconds); // Έξοδος: 0
console.log(duration.nanoseconds);  // Έξοδος: 0

Εκτέλεση αριθμητικών πράξεων με διάρκειες

Τα αντικείμενα Temporal.Duration υποστηρίζουν την πρόσθεση και την αφαίρεση χρησιμοποιώντας τις μεθόδους add() και subtract(). Αυτές οι μέθοδοι επιστρέφουν ένα νέο αντικείμενο Temporal.Duration που αντιπροσωπεύει το αποτέλεσμα της λειτουργίας.

const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");

const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Έξοδος: P1Y5M4D

const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Έξοδος: P10M26D

Μπορείτε επίσης να συνδέσετε αυτές τις μεθόδους για πιο σύνθετους υπολογισμούς:

const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // Έξοδος: P1DT11H30M

Η μέθοδος negated() επιστρέφει ένα νέο αντικείμενο Temporal.Duration με όλα τα στοιχεία αρνητικά:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Έξοδος: -P1Y2M10DT2H30M

Η μέθοδος abs() επιστρέφει ένα νέο αντικείμενο Temporal.Duration με όλα τα στοιχεία ως θετικές τιμές (απόλυτες τιμές):

const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Έξοδος: P1Y2M10DT2H30M

Η μέθοδος with() σάς επιτρέπει να δημιουργήσετε ένα νέο στιγμιότυπο Temporal.Duration με ορισμένες, ή όλες, τις ιδιότητες να αλλάζουν σε νέες τιμές. Εάν μια τιμή δεν καθορίζεται στο αντικείμενο ορίσματος, τότε θα χρησιμοποιηθεί η αρχική τιμή της διάρκειας. Για παράδειγμα:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // Έξοδος: P2Y2M5DT2H30M

Κανονικοποίηση Διάρκειας

Οι διάρκειες μερικές φορές μπορούν να εκφραστούν σε μη κανονικοποιημένη μορφή (π.χ., P1Y12M, η οποία θα μπορούσε να απλοποιηθεί σε P2Y). Η μέθοδος normalized() προσπαθεί να απλοποιήσει μια διάρκεια στην πιο συμπαγή μορφή της. Ωστόσο, απαιτεί μια ημερομηνία αναφοράς για να χειριστεί τις περιπλοκότητες των διαφορετικών μηκών μήνα. Για σωστή κανονικοποίηση, θα χρειαστείτε ένα στιγμιότυπο Temporal.PlainDate, Temporal.ZonedDateTime ή Temporal.Instant.

Για παράδειγμα, η κανονικοποίηση μιας διάρκειας που περιλαμβάνει μήνες και ημέρες απαιτεί μια ημερομηνία αναφοράς:

const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // Έξοδος: P2M1D

Σε αυτό το παράδειγμα, η διάρκεια P1M32D κανονικοποιείται σε σχέση με την 1η Ιανουαρίου 2024, με αποτέλεσμα P2M1D επειδή ο Ιανουάριος έχει 31 ημέρες.

Εάν ασχολείστε μόνο με τα χρονικά στοιχεία (ώρες, λεπτά, δευτερόλεπτα κ.λπ.), μπορείτε να κανονικοποιήσετε χωρίς ημερομηνία αναφοράς:

const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //or omit relativeTo argument
console.log(normalizedDuration.toString()); // Έξοδος: P1DT2H1M

Σύγκριση διαρκειών

Μπορείτε να συγκρίνετε διαρκειες χρησιμοποιώντας τη μέθοδο compare(). Αυτή η μέθοδος επιστρέφει:

const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");

const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Έξοδος: 1

Πρακτικά Παραδείγματα

1. Υπολογισμός του χρόνου μέχρι ένα συμβάν

Ας υποθέσουμε ότι θέλετε να υπολογίσετε τον χρόνο που απομένει μέχρι ένα συγκεκριμένο συμβάν. Χρησιμοποιώντας το Temporal.Now.zonedDateTimeISO() για να λάβετε την τρέχουσα ώρα και αφαιρώντας την ημερομηνία του συμβάντος. Εάν η ημερομηνία του συμβάντος έχει παρέλθει, η έξοδος θα είναι αρνητική.

const eventDate = Temporal.ZonedDateTime.from({ timeZone: 'America/Los_Angeles', year: 2024, month: 12, day: 25, hour: 9, minute: 0, second: 0 });
const now = Temporal.Now.zonedDateTimeISO('America/Los_Angeles');

const durationUntilEvent = eventDate.since(now);

console.log(durationUntilEvent.toString()); // Έξοδος: π.χ., P262DT14H30M (ανάλογα με την τρέχουσα ημερομηνία και ώρα)

2. Παρακολούθηση των διάρκειων εργασιών του έργου

Στη διαχείριση έργων, μπορείτε να χρησιμοποιήσετε το Temporal.Duration για να παρακολουθείτε την εκτιμώμενη ή πραγματική διάρκεια των εργασιών.

const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // 8 ώρες
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // 16 ώρες

const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Total estimated duration: ${totalEstimatedDuration.toString()}`); // Έξοδος: Total estimated duration: P1DT

3. Υπολογισμός της ηλικίας

Ενώ ο υπολογισμός της ηλικίας με ακρίβεια απαιτεί την εξέταση των δίσεκτων ετών και των ζωνών ώρας, το Temporal.Duration μπορεί να παρέχει μια εύλογη εκτίμηση:

const birthDate = Temporal.PlainDate.from("1990-05-15");
const currentDate = Temporal.PlainDate.from("2024-01-20");

const ageDuration = currentDate.since(birthDate, { smallestUnit: 'years' });
console.log(`Estimated age: ${ageDuration.years} years`); // Έξοδος: Estimated age: 33 years

4. Εμφάνιση διαρκειών αναγνώσιμων από τον άνθρωπο

Συχνά, πρέπει να εμφανίσετε τις διάρκειες σε μια αναγνώσιμη από τον άνθρωπο μορφή. Ενώ το Temporal.Duration δεν διαθέτει ενσωματωμένες λειτουργίες μορφοποίησης, μπορείτε να δημιουργήσετε προσαρμοσμένη λογική μορφοποίησης:

function formatDuration(duration) {
  const parts = [];
  if (duration.years) parts.push(`${duration.years} year${duration.years > 1 ? 's' : ''}`);
  if (duration.months) parts.push(`${duration.months} month${duration.months > 1 ? 's' : ''}`);
  if (duration.days) parts.push(`${duration.days} day${duration.days > 1 ? 's' : ''}`);
  if (duration.hours) parts.push(`${duration.hours} hour${duration.hours > 1 ? 's' : ''}`);
  if (duration.minutes) parts.push(`${duration.minutes} minute${duration.minutes > 1 ? 's' : ''}`);
  if (duration.seconds) parts.push(`${duration.seconds} second${duration.seconds > 1 ? 's' : ''}`);

  return parts.join(', ');
}

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // Έξοδος: 1 year, 2 months, 10 days, 2 hours, 30 minutes

Σύνθετη χρήση και ζητήματα

1. Χειρισμός ζώνης ώρας

Όταν ασχολείστε με χρονικά διαστήματα που διασχίζουν όρια ζώνης ώρας ή μεταβάσεις θερινής ώρας, είναι ζωτικής σημασίας να χρησιμοποιήσετε Temporal.ZonedDateTime για να εξασφαλίσετε ακριβείς υπολογισμούς. Η χρήση Temporal.PlainDate και Temporal.PlainTime θα αποφύγει τυχόν μετατροπές ζώνης ώρας.

2. Μικρότερη μονάδα και στρογγυλοποίηση

Οι μέθοδοι `since()` και `until()` συχνά δέχονται επιλογές για τον καθορισμό της μικρότερης μονάδας για τη διάρκεια που προκύπτει. Για παράδειγμα, υπολογίζοντας τον χρόνο *μέχρι* ένα συμβάν και περιορίζοντας τα αποτελέσματα σε ημέρες.

const eventDate = Temporal.PlainDate.from("2024-12-25");
const now = Temporal.PlainDate.from("2024-01-20");

const durationUntilEvent = now.until(eventDate, { smallestUnit: 'days' });

console.log(durationUntilEvent.toString()); //example output PT340D

3. Δευτερόλεπτα άλματος

Το Temporal δεν λαμβάνει υπόψη τα δευτερόλεπτα άλματος εγγενώς. Εάν απαιτείτε ακραία ακρίβεια, θα πρέπει να χειριστείτε τα δευτερόλεπτα άλματος ξεχωριστά.

4. Ζώνες ώρας IANA

Το Temporal API βασίζεται στη βάση δεδομένων ζώνης ώρας IANA (Internet Assigned Numbers Authority). Βεβαιωθείτε ότι το περιβάλλον σας έχει μια ενημερωμένη έκδοση της βάσης δεδομένων IANA για να χειρίζεστε με ακρίβεια τις μετατροπές ζώνης ώρας.

Βέλτιστες πρακτικές

Συνηθισμένα λάθη

Πραγματικές περιπτώσεις χρήσης σε διαφορετικούς πολιτισμούς

Το Temporal API μπορεί να είναι ιδιαίτερα επωφελές σε παγκόσμιες εφαρμογές όπου οι διαφορές ζώνης ώρας και οι πολιτισμικές αποχρώσεις είναι σημαντικές. Ακολουθούν ορισμένα παραδείγματα:

Συμπέρασμα

Το Temporal.Duration παρέχει έναν ισχυρό και διαισθητικό τρόπο για να εργαστείτε με χρονικά διαστήματα στη JavaScript. Κατανοώντας τα χαρακτηριστικά και τις βέλτιστες πρακτικές του, μπορείτε να εκτελέσετε με σιγουριά ακριβείς και αξιόπιστους υπολογισμούς διάρκειας στις εφαρμογές σας. Η υιοθέτηση του Temporal API οδηγεί σε καθαρότερο, πιο συντηρήσιμο κώδικα και μειώνει τον κίνδυνο σφαλμάτων που σχετίζονται με την παλαιότερη διαχείριση ημερομηνίας και ώρας.

Καθώς εμβαθύνετε στο Temporal API, θυμηθείτε να συμβουλευτείτε την επίσημη τεκμηρίωση και να πειραματιστείτε με διαφορετικά σενάρια για να κατανοήσετε πλήρως τις δυνατότητές του. Με τον σύγχρονο σχεδιασμό του και τα ολοκληρωμένα χαρακτηριστικά του, το Temporal είναι έτοιμο να φέρει επανάσταση στον τρόπο με τον οποίο χειριζόμαστε ημερομηνίες, ώρες και διάρκειες στη JavaScript.