将excel中时间格式的列转换为C#日期时间

本文关键字:时间 转换 日期 excel 格式 | 更新日期: 2023-09-27 18:28:39

我目前正在使用Excel C#库(Microsoft.Office.Interop.Excel)将Excel电子表格读取到我的C#应用程序中。

我最初试图将所有单元格作为原始数据读取,但发现日期格式的单元格给了我一个5位数的整数,时间格式的单元格返回了一个小数。所以我发现你可以使用Excel C#库中内置的日期转换方法,比如

DateTime excelDate = (DateTime)ExcelCalcValue.ExcelDateToDateTime(workbook, Double.Parse(cell.Value.ToString()));
output = excelDate.ToString("yyyy-MM-dd HH:mm");

通过使用各种测试表调试我的应用程序,我已经能够记录单元格以不同方式格式化时返回的各种格式字符串。以下是:

(WorksheetCell.CellFormat.FormatString)
Times
[$-F400]h:mm:ss'' AM/PM
hh:mm:ss;@
h:mm:ss;@
[$-409]hh:mm:ss'' AM/PM;@
[$-409]h:mm:ss'' AM/PM;@
Dates
m/d/yy
[$-F800]dddd'','' mmmm'' dd'','' yyyy
dd/mm/yyyy;@
dd/mm/yy;@
d/m/yy;@
d''.m''.yy;@
yyyy''-mm''-dd;@
[$-809]dd'' mmmm'' yyyy;@
[$-809]d'' mmmm'' yyyy;@

使用这些,我现在可以可靠地确定excel中单元格的格式样式。使用前面的代码,我可以检测日期格式的单元格,并以DateTime格式返回正确的数据。但是,我看不到用于转换时间格式单元格的等效函数。

当我读取格式化为[$-F400]h:mm:ss'' AM/PM的单元时间时,我得到了0.58368055555555554的结果。我完全不知道如何将其转换为DateTime,也不知道这个float代表什么。

有人能提出一种将时间格式的excel单元格(以奇怪的浮点形式存储)转换为正确的DateTime变量的方法吗?

将excel中时间格式的列转换为C#日期时间

正如FrankPI所说,使用DateTime.FromOADate()。您可以将此函数用于Excel单元格中的原始数据,无需解析格式。

Excel将日期和时间编码为双精度。完整部分代表1900年1月1日之后的日子。分数部分表示自引用日期午夜起的时间。例如:

1.5 is January 1, 1900 @ Noon

41507.25 = August 21, 2013 @ 6:00 am

有关更多信息,请参阅MSDN关于此功能的文档:

http://msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx

"奇异浮点"可能也可以通过DateTime.FromOADate()方法转换为DateTime。实际上,它是自1900年1月1日以来的天数,时间为分数,例如凌晨1点01分的0.04236 = 1/24 + 1/(24 * 60)

我写这个函数是为了处理从Excel到C#的日期输入。它处理日期单元格的多种数据类型可能性:

/// <summary>
/// Returns DateTime?
/// Excel dates are double values, and sometimes, they're typical dd/mm/yyyy dates.
/// This function handles both possibilities, and the possibility of a blank date input. 
/// /// 
/// </summary>
/// <param name="inputDate"></param>
/// <returns></returns>
private static DateTime? ResolveExcelDateInput(string inputDate)
{
    double incomingDate = 0;
    DateTime incomingDateDate = new DateTime();
    // If the incoming date is a double type, parse it into DateTime
    if (Double.TryParse(inputDate, out incomingDate))
    {
        return DateTime.FromOADate(incomingDate);
    }
    // IF the incoming date value is a date type, parse it.
    var parseDateResult = DateTime.TryParse(inputDate, out incomingDateDate);
    if(parseDateResult)
    {
        // If the parse is successful return the date
        return incomingDateDate;
    }
    else
    {
        // If the parse isn't successful; check if this a blank value and set to a default value.
        if(string.IsNullOrWhiteSpace(inputDate))
        {
            return new DateTime(1901, 1, 1);
        }
        else
        {
            // Otherwise return null value so that is then handled by the validation logic.
            // log a validation result because inputDate is likely an invalid string value that has nothing to do with dates.
            return null;
        }
    }
}

如果您希望日期值是双格式或日期格式,它会将其转换为日期格式,然后尝试使用以下代码。datestringvalue应该是您的输入值。

 DateTime dateNow = DateTime.Now;
 DateTime formatedDate = DateTime.TryParse("datestringvalue", out dateNow) ? Convert.ToDateTime("datestringvalue") : DateTime.FromOADate(Convert.ToDouble("datestringvalue"));