簡體   English   中英

將 DateTime 保存在字符串中並將其解析回來的最佳方法

[英]The best way to save DateTime in string and the parse it back

下面的代碼似乎沒問題,但在保存/解析泰國日歷時失敗,例如 08/31/2555 將失敗,並將被解析為 31/8/3108。 為什么會這樣? 如果我指定“泰國文化”,那么它將因美國/歐盟時間而失敗。

DateTime time = DateTime.Now.AddYears(-10);
String timeString = time.ToString("MM/dd/yyyy HH:mm:ss");

DateTime newTime = DateTime.ParseExact(timeString, "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture));

你確定你得到的是 3108 而不是 3098?

您的字符串將在當地日歷中(泰歷提前 543 年,因此 2022 - 10 + 543 = 2555) - 然后您正在使用不變文化(使用公歷)讀取該日期。

公歷中的 2555 然后在打印時轉換為泰歷,並應導致第二次轉換:2555 + 543 = 3098。

您的代碼相當於:

const string desiredFormat = "MM/dd/yyyy HH:mm:ss";
Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH");

// {31/8/2555 15:32:04} - original
var time = DateTime.Now.AddYears(-10);

// "08/31/2555 15:32:04" (Thai calendar string)
var timeStringLocal = time.ToString(desiredFormat);

// {31/8/3098 15:32:04} - incorrect
// 2555 is treated as a Gregorian date, then converted to 3098 in the Thai calendar when displayed
var newTimeFromLocal = DateTime.ParseExact(timeStringLocal, desiredFormat, CultureInfo.InvariantCulture);

相反,我建議您將用於解析的字符串改為使用不變(公歷)日歷,這將避免任何此類問題。

const string desiredFormat = "MM/dd/yyyy HH:mm:ss";
Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH");

// {31/8/2555 15:32:04} - original
var time = DateTime.Now.AddYears(-10);

// "08/31/2012 15:32:04" - (invariant - Gregorian - calendar string)
var timeStringInvariant = time.ToString(desiredFormat, CultureInfo.InvariantCulture);

// {31/8/2555 15:32:04} - correct
var newTimeFromInvariant = DateTime.ParseExact(timeStringInvariant, desiredFormat, CultureInfo.InvariantCulture);

如果您可以完全控制保存和解析,則可以對兩者使用特定的文化

例如使用"en-US"文化:

CultureInfo DATETIME_CULTURE = CultureInfo.GetCultureInfo("en-US");
const string DATETIME_FORMAT = "yyyy/MM/dd_HH:mm:ss";

DateTime time = DateTime.Now.AddYears(-10);
string timeString = time.ToString(DATETIME_FORMAT, DATETIME_CULTURE);
DateTime newTime = DateTime.ParseExact(timeString, DATETIME_FORMAT, DATETIME_CULTURE, DateTimeStyles.None);

現在time應該與newTime相同。

使用文化不變的格式O

var th = new CultureInfo("th-TH");
var us = new CultureInfo("en-US");
var str = DateTime.Now.AddYears(-10).ToString("O");
Console.WriteLine(str);
var dt_th = DateTime.Parse(str, th);
var dt_us = DateTime.Parse(str, us);
Console.WriteLine(dt_th);
Console.WriteLine(dt_us);
Console.WriteLine(dt_th == dt_us);
2012-08-31T14:24:14.4710048+00:00
8/31/2012 2:24:14 PM
8/31/2012 2:24:14 PM
True

如果要以特定格式保存字符串,則在解析時必須先將其轉換為相同的格式,然后再將其解析為另一種格式。 您可以參考此答案以獲取幫助Read date using system locale 並將其轉換為新格式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM