4.4 Locale and Parsing Failures
03/04/2026— ถ้าคุณอ่านนี้ คุณคิดว่ามันคือวันที่เท่าไหร่? คำตอบขึ้นอยู่กับว่าคุณอยู่ที่ไหนบนโลก
ปัญหา: วันที่เดียวกัน อ่านต่างกัน
Section titled “ปัญหา: วันที่เดียวกัน อ่านต่างกัน”| Format | ประเทศ | 03/04/2026 หมายถึง |
|---|---|---|
| MM/DD/YYYY | สหรัฐฯ | March 4, 2026 |
| DD/MM/YYYY | ไทย, ยุโรป, UK | 3 April, 2026 |
วันที่ต่างกัน 1 เดือน — จาก text เดียวกัน!
ปัญหานี้ไม่ใช่แค่ทฤษฎี: ถ้าคุณ import CSV ที่ผสมระหว่าง US format กับ Thai/EU format → ข้อมูลวันที่จะ ผิดเงียบๆ ไม่มี error
วิธีแก้: ISO 8601
Section titled “วิธีแก้: ISO 8601”ISO 8601 คือมาตรฐานสากลที่ ไม่มีความกำกวม:
YYYY-MM-DD2026-04-24- ปีมาก่อนเสมอ
- ใช้ขีด
-คั่น - ไม่มีใครสับสน
- Sort ตาม text = sort ตามวันที่ (bonus!)
กฎ: เก็บวันที่เป็น YYYY-MM-DD เสมอ — แปลง format ตอนแสดงผลเท่านั้น
ทดลองปัญหา locale:
- ไปที่ File → Settings → Locale
- เปลี่ยนเป็น “United States” → พิมพ์
03/04/2026→ จะถูกอ่านเป็น March 4 - เปลี่ยนเป็น “Thailand” → พิมพ์
03/04/2026→ จะถูกอ่านเป็น 3 April
วิธีแก้ใน Sheets:
=DATEVALUE("2026-04-24") → ISO 8601 ชัดเจนเสมอ=DATE(2026, 4, 24) → ระบุ ปี, เดือน, วัน แยกกัน (ปลอดภัยที่สุด)=TEXT(A1, "YYYY-MM-DD") → แปลงวันที่เป็น ISO formatเช็คว่า Sheets ตีความถูก:
=MONTH(A1) → ถ้าได้ 4 = April, ถ้าได้ 3 = March#include <stdio.h>#include <time.h>#include <string.h>
int main() { struct tm t = {0}; char *input;
// Parse ISO 8601 — ชัดเจนเสมอ input = "2026-04-24"; strptime(input, "%Y-%m-%d", &t); printf("ISO: month=%d, day=%d\n", t.tm_mon + 1, t.tm_mday); // month=4, day=24 ✓
// Parse US format (MM/DD/YYYY) memset(&t, 0, sizeof(t)); input = "03/04/2026"; strptime(input, "%m/%d/%Y", &t); printf("US: month=%d, day=%d\n", t.tm_mon + 1, t.tm_mday); // month=3, day=4
// Parse EU/Thai format (DD/MM/YYYY) memset(&t, 0, sizeof(t)); strptime(input, "%d/%m/%Y", &t); printf("EU/TH: month=%d, day=%d\n", t.tm_mon + 1, t.tm_mday); // month=4, day=3
// ข้อมูลเดียวกัน (03/04/2026) → parse ได้ 2 แบบ! // C ไม่มี auto-detect — programmer ต้องรู้ format ล่วงหน้า
// วิธีที่ปลอดภัย: output เป็น ISO เสมอ time_t now = time(NULL); struct tm *local = localtime(&now); char buf[20]; strftime(buf, sizeof(buf), "%Y-%m-%d", local); printf("Safe: %s\n", buf); // 2026-04-24
return 0;}import pandas as pd
# ปัญหา: pandas เดาผิดได้ambiguous = "03/04/2026"
# default: pandas เดาเป็น US (MM/DD)us = pd.to_datetime(ambiguous)print(f"Default: {us}") # 2026-03-04 (March 4)
# dayfirst=True: บอกให้อ่านเป็น DD/MM (EU/Thai)eu = pd.to_datetime(ambiguous, dayfirst=True)print(f"dayfirst: {eu}") # 2026-04-03 (April 3)
# ต่างกัน 1 เดือน!
# วิธีที่ปลอดภัยที่สุด: ระบุ format ชัดเจนexplicit = pd.to_datetime(ambiguous, format="%d/%m/%Y")print(f"Explicit: {explicit}") # 2026-04-03 (April 3)
# ISO 8601 — ไม่มีปัญหาiso = pd.to_datetime("2026-04-24")print(f"ISO: {iso}") # 2026-04-24 ✓ เสมอ
# ตัวอย่างจริง: column ที่มี mixed formatsdates = pd.Series([ "2026-01-15", # ISO "03/04/2026", # US หรือ EU? ไม่รู้! "15/06/2026", # DD/MM แน่นอน (เดือน 15 ไม่มี) "July 4, 2026", # text format])
# errors="coerce" จะแปลง format ที่ไม่ตรงเป็น NaTresult = pd.to_datetime(dates, format="%Y-%m-%d", errors="coerce")print(result)# 0 2026-01-15# 1 NaT ← ไม่ตรง format# 2 NaT# 3 NaT-- SQL ใช้ ISO 8601 เป็น default!SELECT DATE '2026-04-24'; -- ✓ ชัดเจนเสมอ
-- ถ้า input เป็น text ที่กำกวม-- PostgreSQL:SET datestyle = 'MDY'; -- US modeSELECT '03/04/2026'::DATE; -- 2026-03-04 (March 4)
SET datestyle = 'DMY'; -- EU/Thai modeSELECT '03/04/2026'::DATE; -- 2026-04-03 (April 3)-- ผลลัพธ์ต่างกัน!
-- วิธีที่ปลอดภัย: ใช้ TO_DATE กับ format ชัดเจนSELECT TO_DATE('03/04/2026', 'DD/MM/YYYY'); -- 2026-04-03 (April 3)SELECT TO_DATE('03/04/2026', 'MM/DD/YYYY'); -- 2026-03-04 (March 4)
-- กฎ: เก็บเป็น ISO เสมอ-- ถ้า input มา format อื่น → parse ด้วย TO_DATE + format ที่ถูกต้อง-- แล้วเก็บลง column type DATE (SQL จะเก็บเป็น internal format)
-- ตรวจสอบ datestyle ปัจจุบันSHOW datestyle;Checklist: ป้องกันปัญหา Locale
Section titled “Checklist: ป้องกันปัญหา Locale”- เก็บวันที่เป็น
YYYY-MM-DD(ISO 8601) เสมอ — ไม่ว่าจะใน CSV, database, หรือ API - ถ้า input มาจากคน → ถามหรือบังคับ format (เช่น date picker แทน text input)
- ถ้า input มาจาก CSV → ดูตัวอย่างก่อน: มีวันที่ > 12 ไหม (เช่น 25/03 → แน่ใจว่า DD/MM)
- ใน pandas → ใช้
format=parameter ระบุ format ชัดเจน แทนที่จะให้ pandas เดา - ใน SQL → ใช้
TO_DATE(text, format)แทนที่จะ cast ตรงๆ