Χρόνος

localtime#

Μετατρέπει έναν χρόνο epoch σε αναλυτικό ημερολογιακό χρόνο στην τοπική ζώνη ώρας.

Η localtime παίρνει μια τιμή Unix epoch - δευτερόλεπτα από την 1970-01-01 UTC, τη μορφή που επιστρέφει η time - και την αναλύει σε έτος, μήνα, ημέρα, ώρα, λεπτό, δευτερόλεπτο, ημέρα εβδομάδας, ημέρα έτους και σημαία θερινής ώρας, όλα εκφρασμένα στην τοπική ζώνη ώρας. Η ζώνη ώρας διαβάζεται από τη μεταβλητή περιβάλλοντος TZ αν είναι ορισμένη, αλλιώς από την προεπιλογή του συστήματος (συνήθως /etc/localtime). Για τη συντρόφισσά της σε UTC που αγνοεί το TZ, δείτε την gmtime.

Σύνοψη#

localtime EXPR
localtime

Τι επιστρέφεται#

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

Περιβάλλον λίστας - μια λίστα 9 στοιχείων, όλα αριθμητικά, παρμένα απευθείας από το C struct tm:

#     0     1     2      3      4     5      6      7      8
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
                                                   localtime(time);

Δείκτης

Όνομα

Εύρος

Σημειώσεις

0

$sec

0..60

το 60 είναι δυνατό για leap seconds

1

$min

0..59

2

$hour

0..23

3

$mday

1..31

ημέρα του μήνα με αρχή το 1

4

$mon

0..11

με αρχή το 0: 0 = Ιανουάριος, 11 = Δεκέμβριος

5

$year

έτη - 1900

π.χ. 129 για το 2029

6

$wday

0..6

0 = Κυριακή, 3 = Τετάρτη

7

$yday

0..365

ημέρα του έτους με αρχή το 0· 365 σε δίσεκτο έτος

8

$isdst

λογική τιμή

αληθές όταν ισχύει το DST για την τοπική TZ

Το $mon με αρχή το 0 και το $year με βάση το 1900 αποτελούν μακροχρόνιες κληρονομιές από τη C· τα περισσότερα σφάλματα που γράφονται γύρω από την localtime προέρχονται από τη λήθη ακριβώς ενός από αυτά. Η διόρθωση για το $year είναι += 1900:

my @t = localtime;
my $full_year = $t[5] + 1900;

Βαθμωτό περιβάλλον - η οικεία αγγλική συμβολοσειρά ctime(3), πάντοτε 24 χαρακτήρες, πάντοτε στα αγγλικά ανεξάρτητα από τις τοπικές ρυθμίσεις:

my $now_string = localtime;      # "Thu Oct 13 04:54:34 1994"

Για συμβολοσειρά με επίγνωση τοπικών ρυθμίσεων ή προσαρμοσμένη μορφή, μην προσπαθήσετε να αναλύσετε τη βαθμωτή μορφή. Περάστε μέσα από τη μορφή λίστας και την POSIX::strftime:

use POSIX qw(strftime);
my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;

Καθολική κατάσταση που επηρεάζει#

  • TZ στο %ENV - επιλέγει την τοπική ζώνη ώρας. Ένα πρόγραμμα που θέλει να ερμηνεύσει μια χρονοσήμανση σε συγκεκριμένη ζώνη ορίζει το $ENV{TZ} και καλεί την POSIX::tzset πριν από την localtime (δείτε Οριακές περιπτώσεις για την επιφύλαξη).

  • Το zoneinfo του συστήματος (/etc/localtime, /usr/share/zoneinfo/...) όταν το TZ δεν είναι ορισμένο - διαβάζεται οκνηρά από τη βιβλιοθήκη C, όχι απευθείας από την Perl.

  • Οι αλλαγές στο %ENV που αφορούν το TZ δεν ενεργοποιούνται πάντα στην επόμενη κλήση· δείτε Οριακές περιπτώσεις.

Η localtime δεν επηρεάζει το $_ ούτε καμία καθολική σχετική με έξοδο.

Παραδείγματα#

Τρέχουσα ημερομηνία πραγματικού χρόνου σε αναγνώσιμη από ανθρώπους συμβολοσειρά:

my $now = localtime;             # "Wed Apr 23 14:07:12 2025"

Τρέχουσα ημερομηνία ως λίστα 9 στοιχείων - προσέξτε τις δύο μετατοπίσεις:

my ($s,$m,$h,$md,$mo,$y,$wd,$yd,$dst) = localtime;
printf "%04d-%02d-%02d %02d:%02d:%02d\n",
       $y+1900, $mo+1, $md, $h, $m, $s;    # "2025-04-23 14:07:12"

Όνομα μήνα από το $mon με χρήση πίνακα αναζήτησης - αυτός είναι ο καθιερωμένος τρόπος, επειδή το $mon έχει αρχή το 0 ακριβώς για να ευρετηριάζει πίνακα:

my @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my ($mday, $mon) = (localtime)[3,4];
print "$abbr[$mon] $mday";       # e.g. "Apr 23"

Formatting with POSIX::strftime

  • the right answer whenever you need anything other than the bare English ctime string:

use POSIX qw(strftime);
my @now = localtime;
my $stamp = strftime "%Y-%m-%d %H:%M:%S", @now;   # "2025-04-23 14:07:12"

Ερμηνεία μιας αποθηκευμένης epoch σε συγκεκριμένη ζώνη. Ορίστε το TZ, καλέστε την POSIX::tzset, και κατόπιν την localtime:

use POSIX qw(tzset);
local $ENV{TZ} = "Europe/Berlin";
tzset();
my $wall = localtime(1_700_000_000);   # "Tue Nov 14 23:13:20 2023"

Παγίδα περιβάλλοντος - η localtime μέσα σε print LIST βρίσκεται σε περιβάλλον λίστας, οπότε λαμβάνετε εννέα αριθμούς συνενωμένους χωρίς κενά. Χρησιμοποιήστε scalar για να εξαναγκάσετε τη μορφή συμβολοσειράς:

print localtime, "\n";           # e.g. "12724232312505230"
print scalar localtime, "\n";    # "Wed Apr 23 14:07:12 2025"

Οριακές περιπτώσεις#

  • Χωρίς όρισμα: η localtime χωρίς όρισμα χρησιμοποιεί την time - την τρέχουσα στιγμή πραγματικού χρόνου.

  • Αρνητική epoch: ημερομηνίες πριν από την 1970-01-01 UTC γίνονται δεκτές σε συστήματα με προσημασμένο time_t. Η φορητότητα πολύ απομακρυσμένων χρόνων στο παρελθόν ή στο μέλλον εξαρτάται από τη βιβλιοθήκη C της πλατφόρμας.

  • Παγίδα του $year: το $year + 1900 δίνει το πλήρες έτος. Το "19$year" ήταν σφάλμα Y2K και εξακολουθεί να είναι λάθος· γράψτε 1900 + $year.

  • Παγίδα του $mon: το $mon έχει αρχή το 0. Η έξοδος της localtime που τροφοδοτεί οτιδήποτε έχει αρχή το 1 (περιλαμβανομένης της POSIX::mktime) δεν χρειάζεται προσαρμογή - η mktime αναμένει την ίδια σύμβαση με αρχή το 0. Εξωτερικά συστήματα (βάσεις δεδομένων, συμβολοσειρές ISO-8601) συνήθως θέλουν $mon + 1.

  • Το $isdst είναι ενδεικτικό, όχι άμεσα συγκρίσιμο μεταξύ ζωνών. Το 1 σημαίνει «η τοπική ζώνη εφαρμόζει αυτή τη στιγμή τη μετατόπιση DST»· το 0 σημαίνει «τυπική ώρα»· το -1 εμφανίζεται περιστασιακά όταν οι κανόνες της ζώνης δεν μπορούν να αποφασίσουν (π.χ. η ώρα που δεν υπάρχει σε μέρα που ο δείκτης πηγαίνει μπροστά την άνοιξη).

  • Επιφύλαξη επαναφόρτωσης του TZ: οι περισσότερες βιβλιοθήκες C (συμπεριλαμβανομένης της glibc) αποθηκεύουν στη μνήμη τους τους αναλυμένους κανόνες ζώνης κατά την πρώτη αναζήτηση. Μια μεταγενέστερη εκχώρηση στο $ENV{TZ} δεν υιοθετείται αυτόματα - καλέστε την POSIX::tzset μετά από κάθε αλλαγή, αλλιώς θα συνεχίσει να χρησιμοποιείται η παλιά ζώνη.

  • Η βαθμωτή συμβολοσειρά είναι πάντοτε αγγλική και δεν επηρεάζεται από το LC_TIME ή οποιαδήποτε άλλη ρύθμιση τοπικών. Για συμβολοσειρά τοπικοποιημένη, περάστε μέσα από την POSIX::strftime με το LC_TIME ορισμένο στις επιθυμητές τοπικές ρυθμίσεις.

  • Ασφάλεια νημάτων: σε συστήματα όπου η κλήση C localtime(3) δεν είναι επαναεισερχόμενη, ταυτόχρονα νήματα που μεταβάλλουν το TZ μπορούν να εμφανίσουν race. Στην πράξη η pperl και η σύγχρονη glibc χρησιμοποιούν εσωτερικά την επαναεισερχόμενη localtime_r, αλλά το TZ παραμένει καθολικό σε επίπεδο διεργασίας.

  • Leap seconds: το $sec μπορεί νόμιμα να είναι 60 σε συστήματα με υποστήριξη leap seconds. Τα περισσότερα συστήματα τα διαχέουν (smear) ή τα αγνοούν, και ποτέ δεν θα το δείτε· κώδικας που δεν πρέπει να σπάει στο 60 το χειρίζεται ήδη.

  • Πλάτος των %a / %b στην POSIX::strftime: τα συντομευμένα ονόματα ημερών και μηνών δεν εγγυώνται τρεις χαρακτήρες σε κάθε locale. Κώδικας που υποθέτει σταθερό πλάτος στήλης θα ευθυγραμμιστεί λάθος στα γερμανικά, στα γαλλικά και σε πολλά άλλα.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • gmtime - η ίδια ανάλυση σε UTC· δεν συμβουλεύεται το TZ και είναι η σωστή επιλογή όταν θέλετε τιμή ανεξάρτητη από ζώνη ώρας

  • time - η πηγή epoch που η localtime λαμβάνει συχνότερα ως όρισμα

  • POSIX::strftime - μορφοποιήστε μια λίστα localtime σε όποια διάταξη συμβολοσειράς χρειάζεστε, με επίγνωση τοπικών ρυθμίσεων

  • POSIX::mktime - αντίστροφη κατεύθυνση: μετατρέπει μια λίστα 9 στοιχείων πίσω σε τιμή epoch

  • POSIX::tzset - επανάγνωση του TZ μετά την αλλαγή του, υποχρεωτική αν θέλετε η αλλαγή να τεθεί σε ισχύ

  • $ENV{TZ} - η μεταβλητή περιβάλλοντος που διαβάζει η localtime για να επιλέξει την τοπική ζώνη