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 |
|
|
|
1 |
|
| |
2 |
|
| |
3 |
|
| יום בחודש על בסיס 1 |
4 |
|
| 0-בסיס: |
5 |
| שנים - 1900 | למשל |
6 |
|
|
|
7 |
|
| יום בשנה על בסיס 0; |
8 |
| בוליאני | אמת כאשר 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
ctimestring:
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לכל פריסת מחרוזת שצריך, מודע localePOSIX::mktime- כיוון הופכי: לקיחת רשימה בת 9 אלמנטים בחזרה לערך epochPOSIX::tzset- קריאה מחדש שלTZלאחר שינויו, חובה אם רוצים שהשינוי ייכנס לתוקף$ENV{TZ}- משתנה הסביבה ש־localtimeקורא כדי לבחור את האזור המקומי