SQL Server สตริงการแปลงวันที่


186

ฉันต้องการแปลงสตริงเช่นนี้

'10/15/2008 10:06:32 PM'

เป็นค่า DATETIME ที่เทียบเท่าใน SQL Server

ใน Oracle ฉันจะพูดแบบนี้:

TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')

คำถามนี้บอกเป็นนัยว่าฉันต้องแยกสตริงออกเป็นหนึ่งในรูปแบบมาตรฐานแล้วแปลงโดยใช้หนึ่งในรหัสเหล่านั้น ที่ดูเหมือนน่าหัวเราะสำหรับการดำเนินการทางโลก มีวิธีที่ง่ายกว่านี้ไหม?


คำตอบ:


28

SQL Server (2005, 2000, 7.0) ไม่มีความยืดหยุ่นใด ๆ หรือแม้กระทั่งไม่ยืดหยุ่นวิธีการรับ datetime โครงสร้างโดยพลการในรูปแบบสตริงและแปลงเป็นชนิดข้อมูล datetime

โดย "ตามอำเภอใจ" ฉันหมายถึง "รูปแบบที่บุคคลที่เขียนแม้ว่าบางทีคุณหรือฉันหรือใครบางคนในอีกด้านหนึ่งของโลกจะถือว่าเป็นสัญชาตญาณและชัดเจน" ตรงไปตรงมาฉันไม่แน่ใจว่ามีอัลกอริทึมดังกล่าว


32
มีอัลกอริทึมดังกล่าว Oracle ได้ดำเนินการไปแล้วและการขาด SQL Server ที่เทียบเท่านั้นเป็นความเจ็บปวดอย่างต่อเนื่อง
matao

19
@matao ดังนั้นโปรดให้ความกระจ่างแก่เราว่า Oracle มีวิธีการอย่างไรในการตัดสินว่าผู้ใช้ที่พิมพ์9/6/12หมายถึง 6 กันยายน 2012, 9 มิถุนายน 2012, 6 ธันวาคม 2009 หรืออย่างอื่น
Aaron Bertrand

13
ไม่ต้องกังวลเลยที่นี่: techonthenet.com/oracle/functions/to_date.phpเห็นได้ชัดว่ามันต้องเป็นรูปแบบที่สอดคล้องกันที่คุณนักพัฒนาระบุ แต่มีความยืดหยุ่นมากกว่ากำมือรูปแบบ MS ที่มอบให้คุณซึ่งส่งผลให้เจ็บปวดในการแยกวิเคราะห์แบบกำหนดเอง .
matao

3
@JosphStyons ทราบถึงฟังก์ชัน TO_DATE ของ Oracle ดังที่แสดงในตัวอย่างของเขา เขาต้องการทราบว่ามีวิธีในการแปลงวันที่เป็นสตริงโดยไม่ต้องทราบรูปแบบ / โครงสร้างของสตริงหรือไม่ SQL ไม่ทำเช่นนั้นและแน่นอนว่า TO_DATE ของ Oracle จะไม่ทำเช่นนั้น
ฟิลิปตวัด

23
@PhilipKelley ฉันไม่เห็นว่า OP ต้องการทราบวิธีการทำโดยไม่ต้องทราบรูปแบบ เขาบอกอย่างชัดเจนว่าเขารู้รูปแบบและกำลังถามว่า SQL Server มีบางสิ่งที่เทียบเท่ากับ TO_DATE หรือไม่นั่นคือสิ่งที่ทำให้นักพัฒนาซอฟต์แวร์สามารถป้อนสตริงรูปแบบที่กำหนดเองได้
neverfox

306

ลองสิ่งนี้

Cast('7/7/2011' as datetime)

และ

Convert(varchar(30),'7/7/2011',102)

ดูCAST และ CONVERT (Transact-SQL)สำหรับรายละเอียดเพิ่มเติม


14
นี่เป็นวิธีที่เหมาะสมในการทำและควรทำเครื่องหมายเป็นคำตอบที่ถูกต้อง โปรดทราบว่าCast('2011-07-07' as datetime)สามารถใช้งานได้และกำจัดความคลุมเครือในการสั่งซื้อเดือนและวัน
Joe DeRose

สิ่งนี้จะไม่ทำงานเมื่อเดือนคือ> 12 การจัดรูปแบบคาดว่าจะเป็นรูปแบบ mm / dd / yyyy
Chakri

ใช้ Convert (varchar (30), '7/7/2011', 103) เมื่อทำการแปลงจาก dd / mm / yyyy
Matias Masso

2
@Chakri หากวันที่ของคุณอยู่ในรูปแบบ dd / mm / yyyy SET DATEFORMAT dmyก่อนที่จะใช้คำค้นหาของคุณ
Nathan Griffiths

49

เรียกใช้ผ่านตัวประมวลผลคิวรีของคุณ มันจัดรูปแบบวันที่และ / หรือเวลาเช่นนี้และหนึ่งในนั้นควรให้สิ่งที่คุณต้องการ มันยากที่จะปรับตัว:

Declare @d datetime
select @d = getdate()

select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'

47

ใน SQL Server Denali คุณจะสามารถทำสิ่งที่ใกล้เคียงกับสิ่งที่คุณกำลังมองหา แต่คุณยังคงไม่สามารถผ่านสตริงวันที่แปลกประหลาดที่กำหนดโดยพลการใด ๆ และคาดว่า SQL Server จะรองรับ นี่คือตัวอย่างหนึ่งที่ใช้สิ่งที่คุณโพสต์ในคำตอบของคุณเอง ฟังก์ชัน FORMAT () และยังสามารถยอมรับโลแคลเป็นอาร์กิวเมนต์ตัวเลือก - มันขึ้นอยู่กับรูปแบบของ. Net ดังนั้นส่วนใหญ่ถ้าไม่ใช่ทุกรูปแบบโทเค็นที่คุณคาดว่าจะเห็นจะมี

DECLARE @d DATETIME = '2008-10-13 18:45:19';

-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');

-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

ฉันขอแนะนำให้คุณใช้การควบคุมมากขึ้นและทำให้บริสุทธิ์วันที่ของคุณอินพุต วันที่ให้ผู้คนพิมพ์วันที่โดยใช้รูปแบบใดก็ได้ที่พวกเขาต้องการลงในช่องว่างของแบบฟอร์ม freetext ควรจะเป็นทางที่อยู่ข้างหลังเราในตอนนี้ หากใครบางคนเข้าสู่ 8/9/2011 นั่นคือ 9 สิงหาคมหรือ 8 กันยายน? หากคุณทำให้พวกเขาเลือกวันที่ในการควบคุมปฏิทินแอพสามารถควบคุมรูปแบบได้ ไม่ว่าคุณจะพยายามคาดเดาพฤติกรรมของผู้ใช้มากแค่ไหนพวกเขาก็จะคิดวิธีที่จะป้อนวันที่ที่คุณไม่ได้วางแผนไว้

อย่างไรก็ตามจนถึง Denali ฉันคิดว่า @Ovidiu มีคำแนะนำที่ดีที่สุดจนถึงตอนนี้ ... สามารถทำได้เล็กน้อยโดยใช้ฟังก์ชัน CLR ของคุณเอง จากนั้นคุณสามารถเขียนเคส / สวิตช์สำหรับรูปแบบที่ไม่ได้มาตรฐานที่แปลกประหลาดมากเท่าที่คุณต้องการ


อัปเดตสำหรับ @dhergert :

SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');

ผล:

2008-10-15 22:06:32.000
2008-10-15 22:06:32.000

คุณยังต้องมีข้อมูลที่สำคัญอื่น ๆ ก่อน คุณไม่สามารถใช้ Native T-SQL เพื่อตรวจสอบว่า6/9/2012เป็น 9 มิถุนายนหรือ 6 กันยายน


1
ฉันคิดว่าคำถามคือวิธีการแปลงสตริงเป็นดาต้าไทม์ไม่ใช่ดาต้าไทม์เป็นสตริง
David Hergert

1
TRY_PARSE นั้นสมบูรณ์แบบ เราพบปัญหาในการแยกวิเคราะห์วันที่ 'Thu Sep 22 2016' ขอบคุณสำหรับการแบ่งปัน!
Simon

11

สำหรับปัญหานี้ทางออกที่ดีที่สุดที่ฉันใช้คือให้มีฟังก์ชัน CLR ใน Sql Server 2005 ที่ใช้หนึ่งในฟังก์ชัน DateTime.Parse หรือ ParseExact เพื่อส่งคืนค่า DateTime ด้วยรูปแบบที่ระบุ



8

ทำไมไม่ลอง

select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY]

รูปแบบวันที่สามารถดูได้ที่ตัวช่วยเซิร์ฟเวอร์ SQL> รูปแบบวันที่ของเซิร์ฟเวอร์ SQL


ตัวอย่างรหัสของคุณใช้ไม่ได้ "การแปลงล้มเหลวเมื่อแปลงวันที่และ / หรือเวลาจากสตริงอักขระ"
Césarเลออน

5
select convert(date,'10/15/2011 00:00:00',101)ควรจะเป็น รายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบและสาเหตุที่ 101 บนdocs.microsoft.com/en-us/sql/t-sql/functions/…
อีกผู้ใช้

1
มีคนแปดคนโหวตให้คำตอบนี้แล้วและมันก็ไม่ได้ผล ...
David Klempfner

4

ใช้เวลาสักครู่ในการคิดสิ่งนี้ดังนั้นในกรณีนี้อาจช่วยคนได้:

ใน SQL Server 2012 และดีกว่าคุณสามารถใช้ฟังก์ชันนี้:

SELECT DATEFROMPARTS(2013, 8, 19);

นี่คือวิธีที่ฉันสิ้นสุดการแยกส่วนของวันที่ที่จะใส่ลงในฟังก์ชั่นนี้:

select
DATEFROMPARTS(right(cms.projectedInstallDate,4),left(cms.ProjectedInstallDate,2),right( left(cms.ProjectedInstallDate,5),2)) as 'dateFromParts'
from MyTable

3

หน้านี้มีการอ้างอิงบางอย่างสำหรับการแปลงวันที่และเวลาที่ระบุทั้งหมดที่มีอยู่ในฟังก์ชัน CONVERT หากค่าของคุณไม่ตกอยู่ในรูปแบบที่ยอมรับได้ฉันคิดว่าสิ่งที่ดีที่สุดคือไปที่เส้นทาง ParseExact


ลิงก์เสีย
Michael Potter

3

ส่วนตัวถ้าคุณจัดการกับรูปแบบผนังโดยพลการหรือโดยสิ้นเชิงให้คุณรู้ว่าสิ่งที่พวกเขาก่อนเวลาหรือจะเป็นเพียงแค่ใช้ regexp เพื่อดึงส่วนของวันที่คุณต้องการและรูปแบบวันที่ / วันที่ถูกต้องและองค์ประกอบ


1

ฉันรู้ว่านี่เป็นโพสต์เก่าที่ชั่วร้ายที่มีคำตอบมากมาย แต่ผู้คนจำนวนมากคิดว่าพวกเขาต้องการแยกสิ่งต่าง ๆ ออกจากกันและนำพวกเขากลับมารวมกันหรือยืนยันว่าไม่มีทางที่จะแปลงโดยปริยาย .

ในการตรวจสอบและหวังว่าจะให้คำตอบง่ายๆแก่ผู้อื่นด้วยคำถามเดียวกัน OP ได้ถามถึงวิธีแปลง '10 / 15/2008 10:06:32 PM 'เป็น DATETIME ตอนนี้ SQL Server มีการพึ่งพาภาษาสำหรับการแปลงชั่วคราว แต่ถ้าภาษาอังกฤษหรืออะไรทำนองนี้กลายเป็นปัญหาง่าย ๆ ... เพียงแค่ทำการแปลงและไม่ต้องกังวลกับรูปแบบ ตัวอย่างเช่น (และคุณสามารถใช้ CONVERT หรือ CAST) ...

 SELECT UsingCONVERT = CONVERT(DATETIME,'10/15/2008 10:06:32 PM')
        ,UsingCAST   = CAST('10/15/2008 10:06:32 PM' AS DATETIME)
;

... และนั่นเป็นคำตอบที่ถูกต้องทั้งคู่

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่พวกเขาพูดในโฆษณาทางทีวี "แต่เดี๋ยวก่อน! อย่าสั่งเลย! โดยไม่มีค่าใช้จ่ายเพิ่มเติม

เรามาดูพลังที่แท้จริงของการแปลงชั่วคราวกับ DATETIME และตรวจสอบความผิดพลาดที่เรียกว่า DATETIME2 บางส่วน ลองดูรูปแบบที่แปลกประหลาดที่ DATETIME สามารถจัดการอัตโนมัติอย่างน่าอัศจรรย์และ DATETIME2 ไม่สามารถทำได้ เรียกใช้รหัสต่อไปนี้และดู ...

--===== Set the language for this example.
    SET LANGUAGE ENGLISH --Same a US-English
;
--===== Use a table constructor as if it were a table for this example.
 SELECT *
        ,DateTimeCONVERT  = TRY_CONVERT(DATETIME,StringDT)
        ,DateTimeCAST     = TRY_CAST(StringDT AS DATETIME)
        ,DateTime2CONVERT = TRY_CONVERT(DATETIME2,StringDT)
        ,DateTime2CAST    = TRY_CAST(StringDT AS DATETIME2)
   FROM (
         VALUES
         ('Same Format As In The OP'    ,'12/16/2001 01:51:01 PM')
        ,('Almost Normal'               ,'16 December, 2001 1:51:01 PM')
        ,('More Normal'                 ,'December 16, 2001 01:51:01 PM')
        ,('Time Up Front + Spaces'      ,'   13:51:01  16 December   2001')
        ,('Totally Whacky Format #01'   ,'  16  13:51:01  December   2001')
        ,('Totally Whacky Format #02'   ,'  16    December 13:51:01  2001  ')
        ,('Totally Whacky Format #03'   ,'  16    December 01:51:01  PM 2001  ')
        ,('Totally Whacky Format #04'   ,' 2001 16    December 01:51:01  PM ')
        ,('Totally Whacky Format #05'   ,' 2001    December 01:51:01  PM  16  ')
        ,('Totally Whacky Format #06'   ,' 2001 16    December  01:51:01 PM  ')
        ,('Totally Whacky Format #07'   ,' 2001 16    December  13:51:01 PM  ')
        ,('Totally Whacky Format #08'   ,' 2001 16  13:51:01 PM  December    ')
        ,('Totally Whacky Format #09'   ,'   13:51:01   PM  2001.12/16 ')
        ,('Totally Whacky Format #10'   ,'   13:51:01   PM  2001.December/16 ')
        ,('Totally Whacky Format #11'   ,'   13:51:01   PM  2001.Dec/16 ')
        ,('Totally Whacky Format #12'   ,'   13:51:01   PM  2001.Dec.16 ')
        ,('Totally Whacky Format #13'   ,'   13:51:01   PM  2001/Dec.16')
        ,('Totally Whacky Format #14'   ,'   13:51:01   PM  2001 . 12/16 ')
        ,('Totally Whacky Format #15'   ,'   13:51:01   PM  2001 . December / 16 ')
        ,('Totally Whacky Format #16'   ,'   13:51:01   PM  2001 . Dec /   16 ')
        ,('Totally Whacky Format #17'   ,'   13:51:01   PM  2001 . Dec .   16 ')
        ,('Totally Whacky Format #18'   ,'   13:51:01   PM  2001 / Dec .   16')
        ,('Totally Whacky Format #19'   ,'   13:51:01   PM  2001 . Dec -   16 ')
        ,('Totally Whacky Format #20'   ,'   13:51:01   PM  2001 - Dec -   16 ')
        ,('Totally Whacky Format #21'   ,'   13:51:01   PM  2001 - Dec .   16')
        ,('Totally Whacky Format #22'   ,'   13:51:01   PM  2001 - Dec /   16 ')
        ,('Totally Whacky Format #23'   ,'   13:51:01   PM  2001 / Dec -   16')
        ,('Just the year'               ,' 2001      ')
        ,('YYYYMM'                      ,' 200112      ')
        ,('YYYY MMM'                    ,'2001 Dec')
        ,('YYYY-MMM'                    ,'2001-Dec')
        ,('YYYY    .     MMM'           ,'2001    .     Dec')
        ,('YYYY    /     MMM'           ,'2001    /     Dec')
        ,('YYYY    -     MMM'           ,'2001    /     Dec')
        ,('Forgot The Spaces #1'        ,'2001December26')
        ,('Forgot The Spaces #2'        ,'2001Dec26')
        ,('Forgot The Spaces #3'        ,'26December2001')
        ,('Forgot The Spaces #4'        ,'26Dec2001')
        ,('Forgot The Spaces #5'        ,'26Dec2001 13:51:01')
        ,('Forgot The Spaces #6'        ,'26Dec2001 13:51:01PM')
        ,('Oddly, this doesn''t work'   ,'2001-12')
        ,('Oddly, this doesn''t work'   ,'12-2001')
        ) v (Description,StringDT)
;

ดังนั้นใช่ ... เซิร์ฟเวอร์ SQL มีวิธีการที่ยืดหยุ่นในการจัดการรูปแบบชั่วคราวที่แปลกและไม่จำเป็นต้องมีการจัดการพิเศษ เราไม่จำเป็นต้องลบ "PM" ที่เพิ่มไปยังเวลา 24 ชั่วโมงด้วยซ้ำ มันคือ "PFM" (Magic Freakin 'Pure)

สิ่งที่จะแตกต่างกันเล็กน้อยขึ้นอยู่กับภาษาที่คุณเลือกสำหรับเซิร์ฟเวอร์ของคุณ แต่จำนวนมากจะได้รับการจัดการอย่างใดอย่างหนึ่ง

และการแปลง "auto-magic" เหล่านี้ไม่ใช่สิ่งใหม่ พวกมันกลับไปไกลจริงๆ


คำตอบใหม่ที่ชั่วร้ายสำหรับคำถามเก่าที่ชั่วร้าย ขอบคุณ!
JosephStyons

ขอบคุณสำหรับความคิดเห็น @JosephStyons
Jeff Moden

0

หากคุณต้องการให้ SQL Server ลองและคิดออกใช้ CAST CAST (ทุกครั้งที่มี 'AS datetime) อย่างไรก็ตามนั่นเป็นแนวคิดที่ไม่ดีโดยทั่วไป มีปัญหาเกี่ยวกับวันสากลที่จะเกิดขึ้น ดังที่คุณได้พบเพื่อหลีกเลี่ยงปัญหาเหล่านั้นคุณต้องการใช้รูปแบบมาตรฐาน ODBC ของวันที่ นั่นคือรูปแบบหมายเลข 120, 20 คือรูปแบบสำหรับสองหลักปี ฉันไม่คิดว่า SQL Server มีฟังก์ชั่นในตัวที่ให้คุณจัดเตรียมรูปแบบที่ผู้ใช้กำหนด คุณสามารถเขียนของคุณเองและอาจพบถ้าคุณค้นหาออนไลน์


หากคุณมีวันที่ต่างประเทศในคอลัมน์เดียวฉันตกลงอย่างแน่นอนว่าการใช้หมายเลขรูปแบบเป็นความคิดที่ดี หากคุณมีวันที่ระหว่างประเทศและวันที่สหรัฐอเมริการวมกันอยู่ในคอลัมน์เดียวไม่มีทางที่จะตัดสินความแตกต่างระหว่างสิ่งต่าง ๆ เช่น 7/6/2000 และ 6/7/2000 เว้นแต่ว่าคุณจะมีคอลัมน์น้องสาวที่อธิบายรูปแบบ นั่นเป็นสาเหตุที่คุณภาพของข้อมูล ณ ต้นทางนั้นต้องเป็นอย่างนั้น หากคุณรู้ว่าคุณมีวันที่ในสหรัฐอเมริกาทั้งหมดให้แปลงโดยปริยายทำสิ่งที่พวกเขา หากพวกเขาล้มเหลวคุณก็รู้ว่าต้องมีการแก้ไขบางอย่างในคอลัมน์
Jeff Moden

0

แปลงสตริงเป็นวันที่และเวลาใน MSSQL โดยปริยาย

create table tmp 
(
  ENTRYDATETIME datetime
);

insert into tmp (ENTRYDATETIME) values (getdate());
insert into tmp (ENTRYDATETIME) values ('20190101');  --convert string 'yyyymmdd' to datetime


select * from tmp where ENTRYDATETIME > '20190925'  --yyyymmdd 
select * from tmp where ENTRYDATETIME > '20190925 12:11:09.555'--yyyymmdd HH:MIN:SS:MS



สวัสดีและยินดีต้อนรับสู่ stackoverflow และขอบคุณสำหรับการตอบรับ ในขณะที่รหัสนี้อาจตอบคำถามคุณสามารถลองเพิ่มคำอธิบายสำหรับปัญหาที่คุณแก้ไขและวิธีที่คุณแก้ไขได้ไหม สิ่งนี้จะช่วยให้ผู้อ่านในอนาคตเข้าใจคำตอบของคุณดีขึ้นและเรียนรู้จากมัน
พลูเทียน

-4
dateadd(day,0,'10/15/2008 10:06:32 PM')

3
ยินดีต้อนรับสู่ StackOverflow! โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายสำหรับรหัสของคุณ คำถามนี้อายุเกือบสิบเอ็ดปีแล้วและมีคำตอบที่อธิบายได้ดีมากมายแล้ว หากไม่มีคำอธิบายในคำตอบของคุณจะมีคุณภาพต่ำกว่ามากเมื่อเทียบกับคนอื่น ๆ และมักจะถูกลดระดับหรือลบออก การเพิ่มคำอธิบายนั้นจะช่วยพิสูจน์ว่าคำตอบของคุณอยู่ที่นี่
Das_Geek

ใช่ แต่โพสต์ "อธิบายอย่างดี" แม้กระทั่งโพสต์ที่โพสต์ไว้นั้นซับซ้อนเกินไป โพสต์ที่นี่เป็นจริงหนึ่งในดีกว่าโดยมีหรือไม่มีคำอธิบาย
เจฟฟ์ Moden
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.