บังเอิญผมได้ไปเห็นการใช้ date time format ใน Go แบบผิดๆอยู่บ่อยๆ ก็เลยอยากมาอธิบายเรื่องนี้สักเล็กน้อย
หลายคนอาจจะรู้อยู่แล้วว่าวิธีการจัดการ date time format ใน Go มันจะไม่เหมือนภาษาอื่นที่เขามักจะใช้อักษรแทนเช่น dd คือวันที่ MM คือเลขเดือน yyyy คือปี คศ 4 หลัก และในส่วนของเวลาก็ใช้ hh:mm อะไรแบบนี้ ใน Go จะใช้เลขเรียง 1 2 3 4 5 6 7 มาแทนเพื่อให้จำง่าย(ง่ายตรงไหน)
ซึ่งก็มีหลายคนชื่นชมวิธีคิดแบบนี้ และในขณะเดียวกัน ก็มีคนสรรเสริญไปในทางลบค่อนข้างมากเช่นกัน ซึ่งเหตุผลในส่วนคนที่ชื่นชมก็มองว่า ถ้าคุณจำ magic order ได้ คุณก็ไม่ต้องจำมันอีกต่อไป ซึ่ง Rob Pike เคยมาเฉลยว่า เขาคิดเรื่องนี้ได้ตอนกลับบ้าน แล้วนึกถึงวิธีที่ภาษาโคบอลใช้ ซึ่งเรียกว่า Cobol picture clauses ทั้งๆที่เขาเองก็ไม่เคยเขียน Cobol นะ ส่วนคนที่ไม่ชอบก็ติว่า ทีใน fmt ใช้ %s %d กันสนุกเลย แต่พอมา time format กลับเลี่ยงที่จะทำเหมือนชาวบ้านเขาที่ใช้ %d %Y หรือ ddyy ทำไม มันทำให้ต้องมาจำอะไรแปลกๆเพิ่มขึ้นอีก ก็นะ ส่วนตัวผม ก็ดันชอบการคิดอะไรใหม่ๆอยู่แล้ว แต่ก็ไม่เถียงว่ามันก็ต้องมานั่งจำกันใหม่จริงๆนั่นแหล่ะ เอาล่ะมาเล่าเรื่อง time format กันต่อ โดยตัวแทนแต่ละเลขเป็นดังนี้
1 = เดือน
2 = วัน
3 = ชั่วโมง
4 = นาที
5 = วินาที
6 = ปี
7 = time zone
เห็นไหมว่ามันจำง่่าย (ย้ำว่าง่ายตรงไหน) เช่น "01/02 03:04:05PM '06 -0700" นี่คือหน้าตาของ format นะครับ ไม่ใช่เวลาจริง ส่วนเวลาจริง ถ้าตัวเลขตามนี้เป๊ะมันหมายถึง
วันที่ 2 เดือน มกราคม ปี 2006 เวลา 15 นาฬิกา 4 นาที 5 วินาที ณ time zone ที่ -7 ซึ่งคือเวลาแถวๆประเทศเม็กซิโก ซึ่งตรงกับเวลา 22 นาฬิกา หรือ 4 ทุ่ม 4 นาที 5 วินาที ที่ตำแหน่ง UTC ที่ลอนดอน
ทีนี้ เนื่องจาก format ที่ใส่ -0700 เข้าไปนี่ อาจจะทำให้คนที่ไม่ได้อ่าน doc ตีความกันไปเองว่า ไอ้แถวๆนี้มันน่าจะสามารถใส่อย่างอื่นเข้าไปแทนได้เช่น +0700 หรือ +0000 แต่ความจริง นี่มันเป็น format ซึ่งท่าบังคับมันคือจะต้องเป็น -0700 ไปใส่เครื่องหมาย + ให้มันไม่ได้จ้า และเลขก็ต้องเป็นเลข 7 ซึ่งเป็นเลขเรียงอย่างที่กล่าวไปแล้วข้างต้น
Month = 1
สามารถใช้ได้ 4 รูปแบบ
- Jan กรณีต้องการเป็นอักษรย่อ 3 ตัว เช่นถ้า data เป็น Mar เราอยากจะ parse เข้ามาใส่ time.Time เราก็ต้องใช้ Jan แทนค่านั้นใน format
- January กรณีต้องการคำเต็มของเดือนเช่น ถ้า data เป็น March เราก็ต้องใช้ January เป็น format สำหรับ parse
- 01 กรณีที่ data เป็นเลข 2 หลักแทนเดือน
- 1 กรณีที่ data เป็นเลขที่ไม่ต้องการให้มี 0 นำหน้าสำหรับเดือนที่มี 1 digit เช่น เดือน มีนา ก็จะเป็นเลข 3 เลย
Day = 2
day จะพิเศษหน่อย เนื่องจากวันมีหลายความหมาย
วันในสัปดาห์เช่น จันทร์ อังคาร พุธ
วิธีใช้ สามารถใช้ได้ทั้ง
- "Mon"
- "Monday"
จะมาใช้ "mon" แบบนี้ไม่ได้นะ
วันในเดือนก็คือวันที่
สามารถใช้ได้ 3 รูปแบบคือ
- "2"
- "02"
- "_2" ตัวนี้ถ้าเราจัด format ออกมาจะได้รูปแบบ 2 digits แต่ถ้าเป็นเดือนหลักเดียว มันจะเว้นวรรคให้เช่นถ้าเดือน 3 จะได้ " 3" แต่ถ้าเดือน 10 จะได้ "10" แบบนี้
วันที่ของปี ซึ่งมีได้ 365 หรือ 366 วัน
มี 2 รูปแบบคือ
- "002"
- "__2" ก็เหมือนวันของเดือน โดยจะเว้นวรรคและแสดงให้ครบ 3 digits
Hour = 3
15" "3" "03" (PM or AM)
มี 3 รูปแบบคือ
- "15"
- "3" หรือ "3 PM"
- "03" หรือ "03 PM"
การใส่ PM จะช่วยเพิ่มรายละเอียดให้การบอกเวลาแบบ 12 hour clock ให้รู้ว่าเป็นเวลาก่อนเที่ยง(ante merīdiem หรือ “before midday”) หรือหลังเที่ยง(post merīdiem หรือ "before midday") ซึ่งจะไม่สามารถใช้ AM แทนได้นะ อย่าสับสน นี่คือการจัด format เด้อ มันบังคับให้ใช้ได้แค่ "PM"
Minute = 4
มี 2 รูปแบบ
- "4"
- "04"
Second = 5
มี 2 รูปแบบ
- "5"
- "05"
Year = 6
มี 2 รูปแบบ
- "2006"
- "06"
Time zone = 7
ก่อนอื่นต้องทำความเข้าใจเรื่อง Time zone ก่อนว่าเราจะใช้มาตรฐาน UTC (Universal Time Coordinated) ซึ่งเป็นเวลาสากลเชิงพิกัด โดยจะใช้พิกัดเส้นลองจิจูด ที่ 0° เป็นจุดอ้างอิงว่าเป็น UTC-0 ซึ่งที่ตำแหน่งนั้น มันเป็นเส้นที่ตัดผ่านหอดูดาวหลวงกรีนิช ที่ลอนดอน ซึ่งแต่เดิมจะใช้เวลาจากหอดูดาวนี้ เป็นมาตรฐานเทียบเวลา เรียกว่า GTM (Greenwich Mean Time) แต่นั่นจะถือเป็นมาตรฐานเก่ากว่านะครับ เนื่องจากเป็นเวลาที่อ้างอิงตามหลักดาราศาสตร์ ปัจจุบันให้เปลี่ยนไปใช้ UTC ซึ่งอ้างอิงตามตำแหน่งพิกัดเส้นลองจิจูดแทน
และยังมี MST (Mountain Standard Time) ซึ่งเป็นเวลาอ้างอิงเวลามาตรฐานกับเวลาที่เทือกเขาร็อกกี้ ซึ่งจะเท่ากับ UTC-7 พอดี ทำให้เราก็จะสามารถใช้ MST มาเป็นหนึ่งใน Format ของเราได้ด้วย
มาดู format ของ time zone แบบเบื้องต้นที่ต้องการ parse time zone ในรูปแบบใช้เครื่องหมาย +/- ตามปกติกัน จะใช้รูปแบบนี้ คือต้องเป็น เครื่องหมายลบ "-" เท่านั้น และเลขต้องป็นเลข 7 เท่านั้น ซึ่งพอเอาไป parse เวลาจริง ถ้ามันจะมาเป็น +0800 ก็จะไปตรงกับ format "-0700" แต่ถ้าข้อมูลมาเป็น "+08" ก็ใช้ format "-07" เป็นต้น
"-0700" ±hhmm
"-07:00" ±hh:mm
"-07" ±hh
"-070000" ±hhmmss
"-07:00:00" ±hh:mm:ss
ต่อมาเป็นแบบ ISO 8601
"Z0700" Z or ±hhmm
"Z07:00" Z or ±hh:mm
"Z07" Z or ±hh
"Z070000" Z or ±hhmmss
"Z07:00:00" Z or ±hh:mm:ss
ตัว Z หรือจะเรียกว่า Zulu ก็ได้ไม่ผิด เป็นสัญลักษณ์ที่ใช้วางไว้หลังเวลาวิธีใช้ก็แค่ใช้แทนเครื่องหมายลบ เท่านั้น เวลาแสดง format ก็จะมาในรูปแบบ +/- เหมือนเดิม
MST ก็คือ time zone format เวลาที่เราต้องการ parse ตัว time zone ที่เป็นแบบระบุ time zone เช่น EST หรือ PST และแม้แต่จะ custom เองก็ได้เช่นกันผ่าน time.FixedZone
เล่าไว้เท่านี้นะครับ สามารถอ่านให้ละเอียดมากกว่านี้ที่ https://pkg.go.dev/time และเพิ่มความเข้าใจผ่านการทดลองด้วยตัวเองดูจะดีกว่านะครับ
Top comments (0)