javascript - moment.js - UTC נותן תאריך שגוי
מדוע moment.js UTC תמיד מציג את התאריך השגוי. לדוגמה מהקונסולה של המפתח של כרום:
moment(('07-18-2013')).utc().format("YYYY-MM-DD").toString()
// or
moment.utc(new Date('07-18-2013')).format("YYYY-MM-DD").toString()
שניהם יחזירו "2013-07-17" למה זה מחזיר 17 במקום 18, כפי שהועבר.
אבל אם אני משתמש ב-momentjs בלי ה-utc:
moment(new Date('07-18-2013')).format("YYYY-MM-DD").toString()
אני מקבל חזרה "2013-07-18" שזה מה שאני גם מצפה לו כשמשתמש ב-moment.js UTC.
האם זה אומר שאי אפשר לקבל את התאריך הנכון כשמשתמשים ב-moment.js UTC?
תשובה #1
ברירת המחדל, MomentJS מפרש בזמן מקומי. אם ניתנת רק מחרוזת תאריך (ללא זמן), הזמן כברירת מחדל הוא חצות.
בקוד שלך, אתה יוצר תאריך מקומי ואז ממיר אותו לאזור הזמן UTC (למעשה, זה גורם לאובייקט הרגע לעבור למצב UTC), כך שכאשר הוא מעוצב, הוא מוזז (תלוי בזמן המקומי שלך) קדימה או אחורה.
אם אזור הזמן המקומי הוא UTC+N (כאשר N הוא מספר חיובי), ואם אתה מפרש מחרוזת המכילה רק תאריך, תקבל את התאריך הקודם.
הנה כמה דוגמאות להמחשה (הפרש הזמן המקומי שלי הוא UTC+3 במהלך שעון קיץ):
>>> moment('07-18-2013', 'MM-DD-YYYY').utc().format("YYYY-MM-DD HH:mm")
"2013-07-17 21:00"
>>> moment('07-18-2013 12:00', 'MM-DD-YYYY HH:mm').utc().format("YYYY-MM-DD HH:mm")
"2013-07-18 09:00"
>>> Date()
"Thu Jul 25 2013 14:28:45 GMT+0300 (Jerusalem Daylight Time)"
אם אתם רוצים שהמחרוזת של התאריך-שעון תפורש כ-UTC, עליכם להיות מפורשים לגבי זה:
>>> moment(new Date('07-18-2013 UTC')).utc().format("YYYY-MM-DD HH:mm")
"2013-07-18 00:00"
או, כפי שמזכיר מאט ג'ונסון בתשובתו, אתה יכול (ובעצם כנראה כדאי) לנתח את זה כתאריך UTC מלכתחילה באמצעות moment.utc() ולצרף את מחרוזת הפורמט כארגומנט שני כדי למנוע דו-משמעות.
>>> moment.utc('07-18-2013', 'MM-DD-YYYY').format("YYYY-MM-DD HH:mm")
"2013-07-18 00:00"
כדי ללכת בכיוון ההפוך ולהמיר תאריך UTC לתאריך מקומי, ניתן להשתמש במתודה local(), כך:
>>> moment.utc('07-18-2013', 'MM-DD-YYYY').local().format("YYYY-MM-DD HH:mm")
"2013-07-18 03:00"
תשובה #2
גם Date וגם moment יפענחו את מחרוזת הקלט באזור הזמן המקומי של הדפדפן כברירת מחדל. עם זאת, Date לפעמים לא עקבי בזה. אם המחרוזת היא במיוחד YYYY-MM-DD, תוך שימוש ב-מקפים, או אם היא YYYY-MM-DD HH:mm:ss, היא תפורש כ-זמן מקומי. בשונה מ-Date, moment תמיד יהיה עקבי באופן שבו הוא מפענח.
הדרך הנכונה לנתח רגע קלט כ-UTC בפורמט שנתת תהיה כך:
moment.utc('07-18-2013', 'MM-DD-YYYY')
התייחס למסמך זה.
אם אתה רוצה ואז לעצב זאת אחרת לפלט, היית עושה זאת כך:
moment.utc('07-18-2013', 'MM-DD-YYYY').format('YYYY-MM-DD')
אתה לא צריך לקרוא ל-toString במפורש.
שים לב שחשוב מאוד לספק את פורמט הקלט. בלעדיו, תאריך כמו 01-04-2013 עלול להיות מעובד כ-4 בינואר או 1 באפריל, בהתאם להגדרות התרבות של הדפדפן.
