Sự cố DateTime.TryParse với các ngày có định dạng yyyy-dd-MM


82

Tôi có ngày sau ở định dạng chuỗi "2011-29-01 12:00 sáng". Bây giờ tôi đang cố gắng chuyển đổi định dạng đó sang định dạng ngày giờ với mã sau:

DateTime.TryParse(dateTime, out dt); 

Nhưng tôi luôn nhận được dt là {1/1/0001 12:00:00 AM}, bạn có thể vui lòng cho tôi biết tại sao không? và làm cách nào để chuyển đổi chuỗi đó thành ngày tháng.

CHỈNH SỬA: Tôi vừa thấy mọi người được đề cập sử dụng đối số định dạng. Bây giờ tôi sẽ đề cập rằng tôi không thể sử dụng tham số định dạng vì tôi có một số cài đặt để chọn định dạng ngày tùy chỉnh mà người dùng muốn và dựa trên đó, người dùng có thể tự động nhận ngày trong hộp văn bản ở định dạng đó thông qua jQuery datepicker.


4
Nhân tiện, bạn có thể xác định xem chuyển đổi không thành công bằng cách kiểm tra giá trị trả về của TryParse. Đó là bool success = DateTime.TryParse(...);.
Jim Mischel,

Câu trả lời:


184

Điều này sẽ hoạt động dựa trên ví dụ của bạn "2011-29-01 12:00 sáng"

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);

8
Đánh bại tôi với nó. Nếu bạn biết định dạng chuỗi đầu vào của mình, bạn hầu như luôn phải sử dụng các phương thức TryParseExact / ParseExact.
Euro Micelli

OK, vì vậy định dạng ngày của tôi tương tự như trong ví dụ, nhưng nếu giá trị ngày hoặc tháng là một chữ số, thì trình phân tích cú pháp DateTime sẽ trả lại lỗi, vì nó tìm kiếm hai chữ số khi chỉ có một. Bạn sẽ đề xuất điều gì trong tình huống này?
Ciaran Gallagher

11
Để trả lời câu hỏi của riêng tôi, trong trường hợp này nếu bạn sử dụng một ký tự đơn trong định dạng, nó hoạt động cho cả ngày ký tự đơn và ký tự kép. ví dụ d / m / yyyy làm việc cho 13/11/2012
Ciaran Gallagher

@BrokenGlass đây không phải đang làm việc cho tôi, bạn có thể xin vui lòng giúp tôi với điều này
Meena

2
@CiaranGallagher Chỉ cần một lưu ý nhỏ, ngày trong bình luận của bạn nên sử dụng M lớn (d / M / yyyy)
Yusril Maulidan Raji,

14

Bạn cần sử dụng ParseExactphương pháp . Điều này nhận một chuỗi làm đối số thứ hai của nó chỉ định định dạng datetime ở đó, ví dụ:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
try
{
   result = DateTime.ParseExact(dateString, format, provider);
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Nếu người dùng có thể chỉ định một định dạng trong giao diện người dùng, thì bạn cần phải dịch định dạng đó thành một chuỗi mà bạn có thể chuyển vào phương thức này. Bạn có thể làm điều đó bằng cách cho phép người dùng nhập trực tiếp chuỗi định dạng - mặc dù điều này có nghĩa là chuyển đổi có nhiều khả năng không thành công hơn vì họ sẽ nhập chuỗi định dạng không hợp lệ - hoặc có một hộp tổ hợp cung cấp cho họ các lựa chọn khả thi và bạn thiết lập các chuỗi định dạng cho các lựa chọn này.

Nếu có khả năng là đầu vào không chính xác (ví dụ: người dùng nhập) thì tốt hơn là sử dụng TryParseExactthay vì sử dụng các ngoại lệ để xử lý trường hợp lỗi:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Một giải pháp thay thế tốt hơn có thể là không giới thiệu cho người dùng lựa chọn định dạng ngày tháng, nhưng sử dụng quá tải có một loạt định dạng :

// A list of possible American date formats - swap M and d for European formats
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                   "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                   "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                   "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                   "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

Nếu bạn đọc các định dạng có thể có từ tệp cấu hình hoặc cơ sở dữ liệu thì bạn có thể thêm vào các định dạng này khi gặp tất cả các cách khác nhau mà mọi người muốn nhập ngày.


5

Hãy thử sử dụng phương pháp TryParseExact an toàn

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);

4

Từ DateTime trên msdn:

Loại: System.DateTime% Khi phương thức này trả về, chứa giá trị DateTime tương đương với ngày và giờ có trong s, nếu chuyển đổi thành công hoặc MinValue nếu chuyển đổi không thành công . Việc chuyển đổi không thành công nếu tham số s là null, là một chuỗi trống ("") hoặc không chứa biểu diễn chuỗi hợp lệ của ngày và giờ. Tham số này được chuyển khi chưa được khởi tạo.

"yyyy-dd-MM hh:mm tt"Thay vào đó, hãy sử dụng parseexact với chuỗi định dạng .


3

Điều đó hoạt động:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);

1
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);

0

Nếu bạn cho người dùng cơ hội thay đổi định dạng ngày / giờ, thì bạn sẽ phải tạo một chuỗi định dạng tương ứng để sử dụng cho việc phân tích cú pháp. Nếu bạn biết các định dạng ngày tháng có thể có (nghĩa là người dùng phải chọn từ danh sách), thì điều này sẽ dễ dàng hơn nhiều vì bạn có thể tạo các chuỗi định dạng đó tại thời điểm biên dịch.

Nếu bạn để người dùng thiết kế định dạng tự do của định dạng ngày / giờ, thì bạn sẽ phải tạo các DateTimechuỗi định dạng tương ứng trong thời gian chạy.


Đúng vậy jim Nếu bạn để người dùng thiết kế định dạng tự do của định dạng ngày / giờ, thì bạn sẽ phải tạo các chuỗi định dạng DateTime tương ứng trong thời gian chạy.
Pinal
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.