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


131

Tôi có một ứng dụng WP8, sẽ gửi thời gian hiện tại cho một dịch vụ web.

Tôi nhận được chuỗi thời gian bằng cách gọi

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

Đối với hầu hết người dùng, nó hoạt động rất tốt và cung cấp cho tôi chuỗi chính xác như thế nào "09/10/2013 04:04:31.415". Nhưng đối với một số người dùng, chuỗi kết quả là một cái gì đó giống như "09/14/2013 07.20.31.371", điều này gây ra vấn đề trong dịch vụ web của tôi.

Có phải vì một số vấn đề định dạng văn hóa? Làm thế nào tôi có thể chắc chắn rằng chuỗi kết quả được phân định bằng dấu hai chấm thay vì dấu chấm?


2
sự khác biệt duy nhất là dấu hai chấm so với dấu chấm.
Eldorado

Câu trả lời:


244

Có phải vì một số vấn đề định dạng văn hóa?

Đúng. Người dùng của bạn phải ở trong một nền văn hóa nơi dấu phân cách thời gian là một dấu chấm. Cả ":" và "/" đều được diễn giải theo cách nhạy cảm về văn hóa theo các định dạng ngày và giờ tùy chỉnh .

Làm thế nào tôi có thể chắc chắn rằng chuỗi kết quả được phân định bằng dấu hai chấm thay vì dấu chấm?

Tôi đề nghị chỉ định CultureInfo.InvariantCulture:

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

Ngoài ra, bạn chỉ có thể trích dẫn dấu phân cách thời gian và ngày:

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

... nhưng điều đó sẽ mang lại cho bạn kết quả "thú vị" mà bạn có thể không mong đợi nếu bạn khiến người dùng chạy trong một nền văn hóa nơi hệ thống lịch mặc định không phải là lịch Gregorian. Ví dụ: lấy mã sau:

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"));
    }
} 

Điều đó tạo ra sản lượng (vào ngày 18 tháng 9 năm 2013) của:

11/12/1434 15:04:31.750

Tôi đoán là dịch vụ web của bạn sẽ ngạc nhiên về điều đó!

Tôi thực sự đề nghị không chỉ sử dụng văn hóa bất biến, mà còn thay đổi sang định dạng ngày ISO-8601:

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

Đây là một định dạng được chấp nhận toàn cầu hơn - nó cũng có thể sắp xếp được, và làm cho thứ tự ngày và ngày trở nên rõ ràng. (Trong đó 06/07/2013 có thể được hiểu là ngày 7 tháng 6 hoặc ngày 6 tháng 7 tùy thuộc vào văn hóa của người đọc.)


cảm ơn Jon Tôi nghĩ rằng chuỗi kết quả sẽ chính xác như chuỗi định dạng. Tôi sẽ làm thử lời đề nghị của bạn.
Eldorado

3
Chỉ cần một cân nhắc nhỏ. Khi tải một đối tượng CultureInfo từ một mã cụ thể, tôi luôn đề nghị đặt useUserOverridetham số thành false, nếu không, một số cài đặt người dùng có thể ghi đè cài đặt văn hóa. Ví dụ trong trường hợp của bạn, tôi đề nghị sử dụng mới CultureInfo("ar-SA", false).
Davide Icardi

@DavideIcardi: Thật thú vị, cảm ơn - mặc dù trong trường hợp này, mục đích sử dụng Ả Rập Xê Út đặc biệt để nói tại sao sử dụng văn hóa bất biến có lẽ là đúng. Sẽ ghi nhớ điều đó cho các bài viết trong tương lai.
Jon Skeet

7
Nửa chừng câu trả lời mở rộng này, tôi bắt đầu tự hỏi: liệu đây có phải là Jon nữa không? Vâng.
Nỗi sợ hãi tuyệt vọng

Làm cách nào để quản lý tương tự với Html.TextBoxFor (x => x.Date, "{0: MM / dd / yyyy}")?
VISHMAY

9

:có ý nghĩa đặc biệt: đó là Dấu phân cách thời gian. ( Chuỗi định dạng ngày và giờ tùy chỉnh ).

Sử dụng \để thoát khỏi nó:

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

Hoặc sử dụng CultureInfo.InvariantCulture:

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

Tôi sẽ đề nghị đi với cái thứ hai, bởi vì nó /cũng có ý nghĩa đặc biệt (đó là Dấu phân cách ngày. ), Vì vậy bạn cũng có thể gặp vấn đề với điều đó.


2
Đó không chỉ là dấu phân cách ngày là một vấn đề - hãy xem câu trả lời của tôi để biết ví dụ về văn hóa ảnh hưởng đến các con số thực tế ...
Jon Skeet

1
\ không thoát khỏi nó!
Shereef Marzouk

8

Bạn có thể sử dụng InvariantCARM vì người dùng của bạn phải ở trong một nền văn hóa sử dụng dấu chấm thay vì dấu hai chấm:

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

7

Gần đây tôi đã gặp phải vấn đề này với Windows 10 từ một hướng khác và nhận thấy câu trả lời từ @JonSkeet rất hữu ích trong việc giải quyết vấn đề của tôi.

Tôi cũng đã nghiên cứu thêm với một hình thức kiểm tra và thấy rằng khi văn hóa hiện tại được đặt thành "no"hoặc "nb-NO"tại thời gian chạy ( Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), cuộc gọi ToString ("yyyy-MM-dd HH: mm: ss") đã phản hồi khác nhau trong Windows 7 và Windows 10. Nó trả về những gì tôi mong đợi trong Windows 7 và HH.mm.ss trong Windows 10!

Tôi nghĩ rằng điều này là một chút đáng sợ! Vì tôi tin rằng văn hóa là văn hóa trong bất kỳ phiên bản Windows nào.


Tôi sẽ khá tò mò để tìm hiểu những gì thực sự gây ra điều này.
Lauri Peltonen

2
Nó đã được công nhận và sửa lỗi là lỗi định vị Windows 10. Vì vậy, một bản cập nhật windows trên máy khách sẽ khắc phục vấn đề. Thông tin chi tiết có sẵn trong bài đăng trên blog này: heikniemi.net/hardcoding/2015/08/ Kẻ
Håkon Seljåsen

Blog của Jouni Heikniemi, mà tôi liên kết đến ở trên dường như bị phá vỡ. Các bản cập nhật Windows có liên quan trong đó các vấn đề đã được khắc phục được liệt kê ở đó: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 và Windows 8.1 KB3088955 - Windows Server 2012 và Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows server 2008 R2 SP1 và Windows Vista SP2 Đang cố gắng để liên kết đến các blog một lần nữa, lần này mặc dù archive.org: web.archive.org/web/20161030193739/http://www.heikniemi.net/...
Håkon Seljåsen

4

Bạn có thể sử dụng 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

Chuyển đổi ngày thành chuỗi

Tên không gian

using System.Globalization;

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

Đây không phải là cách chuyển đổi một ngày thành một chuỗi. Phân tích cú pháp là ngược lại!
Vincent Wrapsalbergh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.