我通过日期选择器接受来自用户的日期信息。我需要以文化中立的方式存储它们。我面临的问题是,如果我按照en-US格式存储日期(基于日历设置),即11/20/1990,当文化为en-GB时,它将无法解析。
反之亦然,当文化为en-US时,日期按英国格式存储,dd / mm / yyyy拒绝解析。如何以文化中立的方式在文件中存储日期信息,以便我在两个位置都可以使用日期?
DateTime.TryParse(userEnteredValue, out result);
result.ToShortDateString(); //this is what I am doing
尝试使用此代码进行不变文化
string input = "20/10/1983";
DateTime userInput;
bool result = DateTime.TryParse(input, out userInput);
string invariantCulture = userInput.Date.ToString(CultureInfo.InvariantCulture);
DateTime storedValue;
result = DateTime.TryParse(invariantCulture, out storedValue);
使用en-GB日历设置尝试此代码,第二个语句DateTime.TryParse失败。
答案 0 :(得分:4)
@SonerGönül的回答是如果您将日期保存到数据库的话。但是,您提到要将DateTime
往返于文件进行往返。
由于文件可能是文本文件,因此您需要以文化中立的方式编写DateTime
。您可以使用DateTime.ToString
方法中指定的"O" format执行此操作。这将输出符合ISO 8601的字符串表示。可以使用DateTime.Parse
解析结果字符串,而无需文化信息。
举个例子:
string filename = @"c:\temp\test.txt";
string usDateString = "11/18/2014 12:32"; // MM/dd/yyyy
string ukDateString = "18/11/2014 12:33"; // dd/MM/yyyy
//I'm mimicking you getting the DateTime from the user here
//I'm assuming when you receive the date(s) from the front
//end you'll know the culture - if not then all bets are off.
DateTime usDate =
DateTime.Parse(usDateString, CultureInfo.GetCultureInfo("en-US"));
DateTime ukDate =
DateTime.Parse(ukDateString, CultureInfo.GetCultureInfo("en-GB"));
//write the dates to a file using the "o" specifier
File.AppendAllText(filename, usDate.ToString("o") + Environment.NewLine);
File.AppendAllText(filename, ukDate.ToString("o") + Environment.NewLine);
//read them back in as strings
string[] contents = File.ReadAllLines(filename);
foreach (var date in contents)
{
//prove we can parse them as dates.
Console.WriteLine(DateTime.Parse(date).ToString());
}
这会创建一个包含以下内容的文件:
2014-11-18T12:32:00.0000000
2014-11-18T12:33:00.0000000
并在我的系统(在英国)打印:
18/11/2014 12:32:00
18/11/2014 12:33:00
答案 1 :(得分:3)
如果我按照en-US格式存储日期......
请停止!您似乎尝试使用字符串表示法保存DateTime
值。
DateTime
没有任何隐式格式。它只有日期和时间值。它们的字符串表示可以具有格式。生成您的插入查询,并使用parameterized way直接传递您的DateTime
值 。
请阅读;
如果您希望使用特定格式获取DateTime
值的字符串表示形式,则可以始终使用DateTime.ToString()
方法及其重载。
您的en-GB
文化可以解析MM.dd.yyyy
(因为您使用/
format specifier替换了自己提供的文化DateSeparator
)和en-US
文化可以解析MM/dd/yyyy
也是。
但是,由于您使用.ToShortDateString()
方法,因此根据您的CurrentCulture
设置表示您的日期时间。作为解决方案,您可以将此属性设置为您想要的文化,ToShortDateString
可以根据它进行工作。
result = DateTime.TryParse(invariantCulture, out storedValue);
使用en-UK日历设置尝试此代码,第二个声明 DateTime.TryParse失败了。
由于此DateTime.TryParse
使用了您的CurrentCulture
而且invariantCulture
变量为10/20/1983 00:00:00
,因此这不是CurrentCulture
的标准日期和时间格式}。
顺便说一下,en-UK
没有这样的文化。
10/20/1983 00:00:00
格式为MM/dd/yyyy HH:mm:ss
。但en-GB
文化并未将此格式设为标准日期和时间格式,这就是您的方法返回false
的原因。
作为替代方案,您可以使用自定义格式字符串,如;
string s = "10/20/1983 00:00:00";
string format = "MM/dd/yyyy HH:mm:ss";
DateTime dt;
if (DateTime.TryParseExact(s, format, CultureInfo.GetCultureInfo("en-GB"),
DateTimeStyles.None, out dt))
{
Console.WriteLine(dt);
}
答案 2 :(得分:1)
我碰到了这个问题,并且发现我还带来了其他人没有提到的其他方式:
DateTime.ToBinary()用于序列化,DateTime.FromBinary(Int64)用于反序列化。
以下是这些: ToBinary()返回一个long,可以很容易地以文化不变的方式存储。 FromBinary(Int64)将从提供的long参数返回DateTime对象。 (他们甚至考虑日期时间Kind属性。)
这里有一些代码:
DateTime d1l = DateTime.Now;
long dl = d1l.ToBinary();
DateTime d2l = DateTime.FromBinary(dl);
DateTime d1u = DateTime.UtcNow;
long du = d1u.ToBinary();
DateTime d2u = DateTime.FromBinary(du);
Console.WriteLine("Local test passed: " + (d1l == d2l).ToString());
Console.WriteLine("d2l kind: " + d2l.Kind.ToString());
Console.WriteLine("Utc test passed: " + (d1u == d2u).ToString());
Console.WriteLine("d2u kind: " + d2u.Kind.ToString());
控制台输出:
Local test passed: True
d2l kind: Local
Utc test passed: True
d2u kind: Utc
我觉得这很漂亮!
答案 3 :(得分:0)
String s = "24. 11. 2001";
d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("sk-SK"));
我怀疑你更喜欢英语(印度)(en-IA)。
但是如果你真的无法决定在将日期转换为字符串时使用什么文化,反之亦然,并且日期永远不会向用户显示,那么你可以使用不变文化:
String s = "11/24/2001" //invariant culture formatted date
d = DateTime.Parse(s, CultureInfo.InvariantCulture); //parse invariant culture date
s = d.ToString(CultureInfo.InvariantCulture); //convert to invariant culture string
答案 4 :(得分:0)
我试图通过这种方法找出解决方案,请告诉我它是否正确。
我使用的代码如下。
对于保存日期时间,我使用以下滴答。
DateTime userInput;
bool result = DateTime.TryParse(this.dpSave.Text, out userInput);
if (result)
{
long ticks = userInput.Ticks;
System.IO.File.WriteAllText(@"D:\folder\Ticks.txt", ticks.ToString());
}
else
{
MessageBox.Show("Date time parse failed");
}
为了加载它,我使用
if (System.IO.File.Exists(@"D:\folder\Ticks.txt"))
{
string contents = System.IO.File.ReadAllText(@"D:\Sandeep\Ticks.txt");
long ticks;
if (long.TryParse(contents, out ticks))
{
DateTime storedDateTime = new DateTime(ticks);
MessageBox.Show("Stored Date" + storedDateTime.ToShortDateString());
}
else
{
MessageBox.Show("Unable to obtain stored dates");
}
}
这似乎有用,只要我使用en-US文化保存并使用en-GB文化加载。
如果这是正确的方法,请告诉我!
答案 5 :(得分:0)
a)交换数据应始终存储文化不变(xml等)
b)你必须小心这个术语。 你究竟指的是文化INVARIANT(而不是'文化中立')。 有三种文化类型: 1)不变量 2)文化中立(例如" en") 3)特定文化(例如" en-US")答案 6 :(得分:0)
public DateTime getdate3()
{
CultureInfo Invc = CultureInfo.InvariantCulture; //culture
string cul = Thread.CurrentThread.CurrentCulture.Name;
CultureInfo us = new CultureInfo(cul);
string shortUsDateFormatString = us.DateTimeFormat.ShortDatePattern;//pattern
DateTime dt = Convert.ToDateTime(DateTime.Now);
TimeZoneInfo myZone = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time"); //india zone
DateTime dateindia = TimeZoneInfo.ConvertTime(dt, myZone);
string dt1 = Convert.ToDateTime(dateindia).ToString(shortUsDateFormatString); //string format
}