DateTime ToString (“ MM / dd / yyyy HH: mm: ss.fff”) ได้ผลลัพธ์เช่น“ 09/14/2013 07.20.31.371”


133

ฉันมีแอป WP8 ซึ่งจะส่งเวลาปัจจุบันไปยังบริการเว็บ

ฉันได้รับสตริงวันที่และเวลาโดยการโทร

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")

สำหรับผู้ใช้ส่วนใหญ่มันใช้งานได้ดีและให้สตริงที่ถูกต้องเช่น"09/10/2013 04:04:31.415". แต่สำหรับผู้ใช้บางคนสตริงผลลัพธ์เป็นสิ่ง"09/14/2013 07.20.31.371"ที่ทำให้เกิดปัญหาในบริการเว็บของฉัน

เป็นเพราะรูปแบบวัฒนธรรมบางอย่างหรือไม่? ฉันจะแน่ใจได้อย่างไรว่าสตริงผลลัพธ์ถูกคั่นด้วยเครื่องหมายจุดคู่แทนจุด


2
ความแตกต่างเพียงอย่างเดียวคือโคลอนเทียบกับจุด
Eldorado

คำตอบ:


248

เป็นเพราะรูปแบบวัฒนธรรมบางอย่างหรือไม่?

ใช่. ผู้ใช้ของคุณต้องอยู่ในวัฒนธรรมที่ตัวคั่นเวลาเป็นจุด ทั้งสอง ":" และ "/" จะถูกตีความในทางวัฒนธรรมที่มีความอ่อนไหวในวันที่กำหนดเองและรูปแบบเวลา

ฉันจะแน่ใจได้อย่างไรว่าสตริงผลลัพธ์ถูกคั่นด้วยเครื่องหมายจุดคู่แทนจุด

ฉันขอแนะนำให้ระบุCultureInfo.InvariantCulture:

string text = dateTime.ToString("MM/dd/yyyy HH:mm:ss.fff",
                                CultureInfo.InvariantCulture);

หรือคุณสามารถอ้างอิงตัวคั่นเวลาและวันที่:

string text = dateTime.ToString("MM'/'dd'/'yyyy HH':'mm':'ss.fff");

... แต่นั่นจะให้ผลลัพธ์ที่ "น่าสนใจ" ที่คุณอาจไม่คาดคิดหากคุณให้ผู้ใช้ทำงานในวัฒนธรรมที่ระบบปฏิทินเริ่มต้นไม่ใช่ปฏิทินเกรกอเรียน ตัวอย่างเช่นใช้รหัสต่อไปนี้:

using System;
using System.Globalization;
using System.Threading;

class Test
{
    static void Main()        
    {
        DateTime now = DateTime.Now;
        CultureInfo culture = new CultureInfo("ar-SA"); // Saudi Arabia
        Thread.CurrentThread.CurrentCulture = culture;
        Console.WriteLine(now.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
    }
} 

ที่สร้างผลลัพธ์ (ในวันที่ 18 กันยายน 2013) ของ:

11/12/1434 15:04:31.750

ฉันเดาว่าบริการเว็บของคุณจะต้องประหลาดใจแน่ ๆ !

ฉันขอแนะนำไม่เพียง แต่ใช้วัฒนธรรมที่ไม่แปรเปลี่ยนเท่านั้น แต่ยังเปลี่ยนเป็นรูปแบบวันที่ ISO-8601 ด้วย:

string text = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

นี่เป็นรูปแบบที่ยอมรับกันทั่วโลกมากขึ้นนอกจากนี้ยังสามารถจัดเรียงได้และทำให้ลำดับเดือนและวันชัดเจน (ในขณะที่ 06/07/2013 สามารถตีความได้ว่าเป็นวันที่ 7 มิถุนายนหรือ 6 กรกฎาคมขึ้นอยู่กับวัฒนธรรมของผู้อ่าน)


ขอบคุณจอน ฉันคิดว่าสตริงผลลัพธ์จะเหมือนกับสตริงรูปแบบ ฉันจะลองทำตามคำแนะนำของคุณ
Eldorado

3
เพียงแค่การพิจารณาเล็ก ๆ น้อย ๆ เมื่อโหลดออบเจ็กต์ CultureInfo จากรหัสเฉพาะฉันมักแนะนำให้ตั้งค่าuseUserOverrideพารามิเตอร์เป็นเท็จมิฉะนั้นการตั้งค่าผู้ใช้บางอย่างสามารถแทนที่การตั้งค่าวัฒนธรรมได้ CultureInfo("ar-SA", false)ยกตัวอย่างเช่นในกรณีของคุณผมขอแนะนำให้ใช้ใหม่
Davide Icardi

@DavideIcardi: น่าสนใจขอบคุณ - แม้ว่าในกรณีนี้จุดประสงค์ของการใช้ซาอุดีอาระเบียก็เพื่อบอกว่าเหตุใดการใช้วัฒนธรรมที่ไม่แปรเปลี่ยนจึงน่าจะถูกต้อง จะจำไว้สำหรับโพสต์ในอนาคตแม้ว่า
Jon Skeet

7
ครึ่งทางของคำตอบที่ครอบคลุมนี้ฉันเริ่มสงสัยว่านี่จะเป็นจอนอีกครั้งหรือไม่? ใช่.
Grimace of Despair

จะจัดการกับ Html.TextBoxFor (x => x.Date, "{0: MM / dd / yyyy}") ได้อย่างไร
VISHMAY

10

:มีความหมายพิเศษคือตัวคั่นเวลา ( สตริงรูปแบบวันที่และเวลาที่กำหนดเอง )

ใช้\เพื่อหลบหนี:

DateTime.ToString(@"MM/dd/yyyy HH\:mm\:ss.fff")

หรือใช้CultureInfo.InvariantCulture:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)

ฉันขอแนะนำให้ใช้อันที่สองเพราะ/มีความหมายพิเศษเช่นกัน (มันคือตัวคั่นวันที่ ) ดังนั้นคุณอาจมีปัญหากับมันได้เช่นกัน


2
ไม่ใช่แค่ตัวคั่นวันที่เท่านั้นที่เป็นปัญหา - ดูคำตอบของฉันสำหรับตัวอย่างของวัฒนธรรมที่มีผลต่อตัวเลขจริงด้วย ...
Jon Skeet

1
\ ไม่หนี!
Shereef Marzouk

8

คุณสามารถใช้ InvariantCulture ได้เนื่องจากผู้ใช้ของคุณต้องอยู่ในวัฒนธรรมที่ใช้จุดแทนเครื่องหมายจุดคู่:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);

7

เมื่อเร็ว ๆ นี้ฉันพบปัญหานี้กับ Windows 10 จากทิศทางอื่นและพบว่าคำตอบจาก @JonSkeet มีประโยชน์มากในการแก้ปัญหาของฉัน

ฉันยังทำการวิจัยเพิ่มเติมด้วยแบบทดสอบและพบว่าเมื่อวัฒนธรรมปัจจุบันถูกตั้งค่าเป็น"no"หรือ"nb-NO"รันไทม์ (Thread.CurrentThread.CurrentCulture = new CultureInfo("no"); ) การเรียก ToString ("yyyy-MM-dd HH: mm: ss") จะตอบสนองแตกต่างกันใน Windows 7 และ Windows 10 มันส่งคืนสิ่งที่ฉันคาดหวังใน Windows 7 และ HH.mm.ss ใน Windows 10!

ฉันคิดว่ามันน่ากลัวไปหน่อย! เนื่องจากฉันเชื่อว่าวัฒนธรรมเป็นวัฒนธรรมใน Windows ทุกรุ่นเป็นอย่างน้อย


ฉันค่อนข้างอยากรู้อยากเห็นว่าอะไรเป็นสาเหตุของสิ่งนี้
Lauri Peltonen

2
ได้รับการยอมรับและแก้ไขแล้วว่าเป็น Bug ในการระบุตำแหน่งของ Windows 10 ดังนั้นการอัปเดต windows บนเครื่องไคลเอนต์จะแก้ไขปัญหาได้ ดูรายละเอียดเพิ่มเติมได้ในบล็อกโพสต์นี้: heikniemi.net/hardcoded/2015/08/…
HåkonSeljåsen

บล็อกของ Jouni Heikniemi ที่ฉันเชื่อมโยงไปข้างบนดูเหมือนจะพัง การอัปเดต Windows ที่เกี่ยวข้องซึ่งปัญหาได้รับการแก้ไขแสดงอยู่ในรายการ: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 และ Windows 8.1 KB3088955 - Windows Server 2012 และ Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows Server 2008 R2 SP1 และ Windows Vista SP2 พยายามเชื่อมโยงไปยังบล็อกอีกครั้งคราวนี้ผ่าน archive.org: web.archive.org/web/20161030193739/http://www.heikniemi.net/…
HåkonSeljåsen

4

คุณสามารถใช้ String.Format:

DateTime d = DateTime.Now;
string str = String.Format("{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}.{6:000}", d.Month, d.Day, d.Year, d.Hour, d.Minute, d.Second, d.Millisecond);
// I got this result: "02/23/2015 16:42:38.234"

0

แปลงวันที่เป็นสตริง

ใช้ชื่อ Space

using System.Globalization;

รหัส

string date = DateTime.ParseExact(datetext.Text, "dd-MM-yyyy", CultureInfo.InstalledUICulture).ToString("yyyy-MM-dd");

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