C# 如何将DataTable控制为CSV toString()格式?
我有一个小应用程序在我的机器上运行良好,我能够从MySQL数据库获取数据到DataTable,然后将该DataTable写入CSV,没有问题,然后有人尝试在他们的机器上运行该应用程序,datetime列开始出现与预期不同的行为: 在我的机器上有这样的东西:(这就是我想要的) 但在另一台机器上我有:C# 如何将DataTable控制为CSV toString()格式?,c#,csv,datatable,tostring,C#,Csv,Datatable,Tostring,我有一个小应用程序在我的机器上运行良好,我能够从MySQL数据库获取数据到DataTable,然后将该DataTable写入CSV,没有问题,然后有人尝试在他们的机器上运行该应用程序,datetime列开始出现与预期不同的行为: 在我的机器上有这样的东西:(这就是我想要的) 但在另一台机器上我有: 15/07/2015 4:40:55 PM, 15/07/2015 4:41:56 PM, 15/07/2015 4:42:55 PM, 15/07/2015 4:43:55 PM,
15/07/2015 4:40:55 PM,
15/07/2015 4:41:56 PM,
15/07/2015 4:42:55 PM,
15/07/2015 4:43:55 PM,
15/07/2015 4:44:56 PM,
我的代码是:
try
{
lock (writtingLock)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-CA");
dataTable = newMyDataTable;
fileId = dataTable.TableName;
PathMaker path = new PathMaker(fileId);
path.Make();
// writing the table to a file
using (StreamWriter swr =
new StreamWriter(File.Open(path.filePath, FileMode.Create), Encoding.Default, 1000000))
// change buffer size and Encoding to your needs
{
if (addHeader)
{
foreach (var dc in dataTable.Columns)
{
swr.Write(dc.ToString() + ",");
}
swr.WriteLine();
}
foreach (DataRow dr in dataTable.Rows)
{
Object[] test = dr.ItemArray;
test.Where(o => o.GetType() == typeof(DateTime)).Select(t => (DateTime)t).Select(x => x.ToFileTime());
swr.WriteLine(string.Join(",", test.Select(x => x.ToString().TrimEnd(null)).ToArray()));
}
}
}
}
添加或删除
Thread.CurrentThread.CurrentCulture=new CultureInfo(“en-CA”)代码>无效,如何解决此问题?是否仍有控制格式的方法?在此行中使用DateTime::ToString(“o”,CultureInfo.InvariantCulture)
:
swr.WriteLine(string.Join(",", test.Select(x => x.ToString().TrimEnd(null)).ToArray()));
查看x.ToString()
表达式
.Net正在使用重载解析来知道它需要调用。此方法的文档包括以下内容:
此方法使用从当前区域性派生的格式信息。特别是,它结合了ShortDatePattern和LongTimePattern返回的自定义格式字符串
换句话说,另一台计算机的日期格式选项与您的不同
您可以通过在代码的前面设置线程区域性来解释这一点。但是,如果我将自己的系统设置为使用en-CA
区域性,然后在我的机器上自定义日期/时间格式,那么将en-CA
区域性应用到线程仍然使用我自定义的日期-时间格式,因为我说过en-CA
在这个系统上应该是这样的
您可能不喜欢它,但这是一件非常正常的事情,作为程序员,当我们需要精确的格式时,我们应该提前考虑。看起来您确实需要精确的格式,因此您需要调整此代码,使其足够智能,以了解日期类型和其他类型之间的差异,从而可以指定所需的精确格式
对于数字类型(int
、float
、decimal
、single
、double
,等等),您也需要做同样的事情,因为这些类型的输出也可能因系统的当前区域性设置而异
有一条捷径。您可以使用InvariantCulture
。但是,只有当不变量区域性恰好具有您想要的格式时,这才起作用。如果您需要一些不同的东西,您可以重新处理单个类型。不过,有时候,不变量文化可能是一个有用的起点。例如,数字可能是正确的,因此您只需要提供日期格式
最后,当我在这里时,我想调用前面一行代码:
test.Where(o => o.GetType() == typeof(DateTime)).Select(t => (DateTime)t).Select(x => x.ToFileTime());
那代码没有效果!它不会重新分配给test
变量,因此它所做的任何工作(谢天谢地,这并不多,因为枚举数从未执行过)都会被扔掉。您可能应该删除这一行。我有问题,您能给我一个如何测试和处理这些“危险”类型的示例吗?你说的最后一行代码是无用的,如何将其固定为datetime格式?为什么不执行枚举器?枚举器只是创建一个知道如何循环原始集合的状态机。您需要使用实际的foreach
循环或类似于.ToArray()
,.ToLis()
,.All()
,.Count()
,或.Any()
之类的扩展方法,这些方法返回的结果不是另一个枚举数。
test.Where(o => o.GetType() == typeof(DateTime)).Select(t => (DateTime)t).Select(x => x.ToFileTime());