将Excel中的时间格式列转换为C# DateTime

5

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

我最初尝试读取所有单元格的原始数据,但发现日期格式的单元格给出了一个五位数的整数,而时间格式的单元格返回一个小数。因此,我找到了一个内置于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,或者这个浮点数代表什么意思。
有人能建议一种将Excel中时间格式的单元格(存储为奇怪的浮点数)转换为正确的DateTime变量的方法吗?

@pnuts 我做不到,因为电子表格将由用户提供,我需要为用户导入电子表格时准备许多不同的场景。感谢提供链接! - Mike Baxter
4个回答

14

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

Excel将其日期和时间编码为双精度浮点数。整数部分表示自1900年1月1日以来的天数。小数部分表示所引用日期的午夜后经过的时间。例如:

1.5是1900年1月1日@中午

41507.25 = 2013年8月21日@上午6:00

有关此函数的更多信息,请参阅MSDN文档:

http://msdn.microsoft.com/zh-cn/library/system.datetime.fromoadate.aspx


另外,DateTime.ToOADate() 可以反过来转换。 - Matt Kemp

3

“奇怪的浮点数”可能可以通过DateTime.FromOADate()方法转换为DateTime。实际上,它是自1900年1月1日以来的天数,时间为小数,例如,0.04236 = 1/24 + 1/(24 * 60)表示上午1:01。


0
我写了这个函数来处理从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;
        }
    }
}

0
如果您希望将日期值转换为双精度格式或日期格式,则可以尝试使用以下代码进行转换。其中,datestringvalue 应为您的输入值。
 DateTime dateNow = DateTime.Now;
 DateTime formatedDate = DateTime.TryParse("datestringvalue", out dateNow) ? Convert.ToDateTime("datestringvalue") : DateTime.FromOADate(Convert.ToDouble("datestringvalue"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接