זמן

localtime#

ממיר זמן epoch לזמן לוח שנה מפורק באזור הזמן המקומי.

localtime לוקח ערך Unix epoch - שניות מאז 1970-01-01 UTC, הצורה ש־time מחזיר - ומפרק אותו לשנה, חודש, יום, שעה, דקה, שנייה, יום בשבוע, יום בשנה, ודגל daylight-saving, הכול מבוטא באזור הזמן המקומי. אזור הזמן נקרא ממשתנה הסביבה TZ אם הוא הוגדר, אחרת מברירת המחדל של המערכת (בדרך כלל /etc/localtime). עבור המקבילה ב־UTC המתעלמת מ־TZ, ראו gmtime.

תקציר#

localtime EXPR
localtime

מה מקבלים בחזרה#

צורת ההחזרה תלויה בהקשר, ו־localtime הוא אחד ממעט הפנימיים שבהם אותו ביטוי בהקשר רשימה ובהקשר סקלרי מפיק תשובות שונות לחלוטין.

הקשר רשימה - רשימה בת 9 אלמנטים, כולם מספריים, נלקחת ישירות מתוך struct tm של C:

#     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 אפשרי עבור שניות מעוברות

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 תווים, תמיד באנגלית ללא תלות ב־locale:

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

למחרוזת מודעת locale או מותאמת אישית, אל תנסו לפרק את הצורה הסקלרית. עברו דרך צורת הרשימה ו־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 (ראו מקרי קצה להסתייגות).

  • מידע אזור מערכתי (/etc/localtime, /usr/share/zoneinfo/...) כאשר TZ אינו מוגדר - נקרא בעצלתיים על־ידי ספריית ה־C, לא על־ידי Perl ישירות.

  • שינויי %ENV ל־TZ אינם תמיד נכנסים לתוקף בקריאה הבאה; ראו מקרי קצה.

localtime אינו נוגע ב־$_ או בכל גלובלי הקשור לפלט.

דוגמאות#

התאריך הנוכחי לפי wall-clock במחרוזת קריאה־לבני־אדם:

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 - רגע ה־wall-clock הנוכחי.

  • 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 או מהגדרת locale אחרת. למחרוזת מותאמת לאזור, עברו דרך POSIX::strftime עם LC_TIME מוגדר ל־locale הרצוי.

  • בטיחות thread: במערכות שבהן הקריאה localtime(3) של C אינה reentrant, threads מקבילים שמשנים את TZ יכולים להיות בתחרות. בפועל pperl ו־glibc מודרני משתמשים ב־localtime_r ה־reentrant פנימית, אבל TZ עדיין גלובלי בגודל תהליך.

  • שניות מעוברות: $sec יכול להיות באופן חוקי 60 במערכות עם תמיכה בשניות מעוברות. רוב המערכות ממרחות או מתעלמות מהן ולעולם לא תראו אותן; קוד שלא יכול להישבר על 60 כבר מטפל בכך.

  • רוחב %a / %b תחת POSIX::strftime: שמות יום בשבוע וחודש המקוצרים אינם מובטחים להיות שלושה תווים בכל locale. קוד המניח רוחב עמודה קבוע יסטה ביישור בגרמנית, צרפתית, ורבות אחרות.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • gmtime - אותו פירוק ב־UTC; אינו מתייעץ עם TZ והוא הבחירה הנכונה כשרוצים ערך בלתי־תלוי באזור זמן

  • time - מקור ה־epoch ש־localtime מקבל לרוב כארגומנט שלו

  • POSIX::strftime - פרמוט רשימת localtime לכל פריסת מחרוזת שצריך, מודע locale

  • POSIX::mktime - כיוון הופכי: לקיחת רשימה בת 9 אלמנטים בחזרה לערך epoch

  • POSIX::tzset - קריאה מחדש של TZ לאחר שינויו, חובה אם רוצים שהשינוי ייכנס לתוקף

  • $ENV{TZ} - משתנה הסביבה ש־localtime קורא כדי לבחור את האזור המקומי