下面的代码看起来不错,但在保存/解析泰国日历时失败,例如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";
// Set the current thread to the Thai culture.
// This line is only here to demonstrate the problem and can be removed.
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";
// Set the current thread to the Thai culture.
// This line is only here to demonstrate the problem and can be removed.
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
如果要以特定格式保存字符串,则在解析时必须先将其转换为相同的格式,然后再将其解析为另一种格式。你可以参考这个答案寻求帮助使用系统区域设置读取日期并将其转换为新格式