简体   繁体   English

DataTable转换为CSV日期格式

[英]DataTable to CSV date format

I'm trying to export a DataTable to CSV, with a number of columns. 我正在尝试将DataTable导出为具有许多列的CSV。 I would like that the date_time column is exported to CSV while retaining the database date_time format (YYY-MM-DD HH:mm:ss), or something like that. 我希望将date_time列导出为CSV,同时保留数据库的date_time格式(YYY-MM-DD HH:mm:ss)或类似的内容。

This is my code: 这是我的代码:

private void DataTableToCsv(string path, DataTable dt)
        {
            File.Delete(path);
            StringBuilder sb = new StringBuilder();

            string[] columnNames = dt.Columns.Cast<DataColumn>().
                                              Select(column => column.ColumnName).
                                              ToArray();
            sb.AppendLine(string.Join(",", columnNames));

            foreach (DataRow row in dt.Rows)
            {
                string[] fields = row.ItemArray.Select(field => field.ToString()).
                                                ToArray();
                sb.AppendLine(string.Join(",", fields));
            }

            File.WriteAllText(path, sb.ToString());
        }

The dates are appearing in a different format, which is giving me errors when trying to pick up from MySQL. 日期以不同的格式出现,这在尝试从MySQL提取时给了我错误。

I know there is an accepted answer already, but... 我知道已经有一个可以接受的答案,但是...

Actually there is a way to control the formatting of dates in a consistent manner, without specifying the format for every type of data: you can use IFormatProvider 实际上, 有一种方法可以以一致的方式控制日期的格式,而无需为每种数据类型指定格式:您可以使用IFormatProvider

First, the method object.ToString(); 首先,方法object.ToString(); with no parameters is formatting your object using current CultureInfo set in your thread/application/system. 如果没有参数,则使用线程/应用程序/系统中设置的当前CultureInfo格式化对象。 This is problematic when you need consistent formatting, for example when you try to save values into database. 当您需要一致的格式时(例如,当您尝试将值保存到数据库中时),这是有问题的。 It isn't only problematic for dates but also for numbers - there are languages out there that use comma as decimal separator or use thousand separator in a number, for example, and databases do not like that very much. 它不仅对日期而且对数字都有问题-例如,有一些语言使用逗号作为小数点分隔符或在数字中使用千位分隔符,而数据库不太喜欢这种语言。 Now imagine your program is run on the computer that has a different language set... 现在,假设您的程序在具有不同语言集的计算机上运行...

Having said that, many of those problems can be avoided by using object.ToString(CultureInfo.InvariantCulture); 话虽如此,通过使用object.ToString(CultureInfo.InvariantCulture);可以避免许多此类问题object.ToString(CultureInfo.InvariantCulture); instead. 代替。 It is associated with the English language. 它与英语相关。 Then, the result for 31th October 2014will be: 10/31/2014 08:35:52 那么,2014年10月31日的结果将是: 10/31/2014 08:35:52

Obviously still not what you want. 显然仍然不是您想要的。

You can further control your formatting by modifying the culture a little yourself: 您可以通过自己稍微修改区域性来进一步控制格式:

CultureInfo format = (CultureInfo) CultureInfo.InvariantCulture.Clone();

// those are the formats used by ToString() mathod:
format.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
format.DateTimeFormat.ShortTimePattern = "HH:mm:ss";

Console.WriteLine(DateTime.Now.ToString(format));

double ddd=13.11;
Console.WriteLine(ddd.ToString(format));

string sss = "some string";
// although this may not be a good idea:
Console.WriteLine(sss.ToString(format));

result: 结果:

2014-10-31 08:39:53
13.11
some string

With DateTime values, you can control the output by calling 使用DateTime值,您可以通过调用来控制输出

dateTimeField.ToString("yyyy-dd-MM");

Currently you're treating all fields equally, and using the default conversion: 当前,您将平等对待所有字段,并使用默认转换:

field => field.ToString()

You can't specify a conversion as object.ToString() has no overloads to do so; 您不能将转换指定为object.ToString()没有重载。 you'd have to specify what conversion to use for each type separately, ie: 您必须分别为每种类型指定要使用的转换,即:

string[] fields = row.ItemArray.Select(field => ConvertToCsvValue(field)).ToArray();

and

static void ConvertToCsvValue(object value)
{
    if (value is DateTime)
    {
        return ((DateTime)value).ToString("yyyy-dd-MM");
    }
    else
    {
        return value.ToString();
    }
}

data in a database is not aware of any format; 数据库中的数据不知道任何格式; the behaviour you are experiencing is related to that and is correct. 您所经历的行为与此相关并且是正确的。
when filling the csv your code is taking the default format for the env/os/locale and applying it to the values. 填充csv时,您的代码采用env / os / locale的默认格式并将其应用于值。

to solve the issue you have some possible solution: 要解决此问题,您有一些可能的解决方案:

  • you change the source sql code to produce a sql text field filled with formatted data (imho a bad choice) 您更改源sql代码以产生一个填充了格式化数据的sql文本字段(恕我直言,这是错误的选择)

  • you handle the format client side when preparing the csv; 您在准备csv时要处理格式客户端; you have to modify your code to handle the fields one by one applying the correct format to date fields 您必须修改代码以将正确的格式应用于日期字段来逐一处理字段

  • you alter the datatable content applying the expected format to date fields (this may be possible or maybe not depending on datatype of the involved fields) 您更改数据表内容,将期望的格式应用于日期字段(这可能是可能的,或取决于所涉及字段的数据类型)

my preference goes to the second or third solution because i prefer to keep formatting on the client side but YMMV and in your post there is not enough information to make a proper choice. 我偏爱第二种或第三种解决方案,因为我更喜欢在客户端保留格式,但是YMMV和您的帖子中没有足够的信息来做出适当的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM