C# 如何将DataTable控制为CSV toString()格式?

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,

我有一个小应用程序在我的机器上运行良好,我能够从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: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());