2012-08-29 38 views
1

我正在使用Office 2003 doc(.xls)的VS2008 .NET3.5。我正在使用Microsoft.Office.Interop.Excel访问文档。从XLS到C#的转换失败的日期时间

这对我的目的很好,但每当我尝试获取日期时都会失败。

我使用的方法是最常见的:

object date= xlWorkSheet.get_Range("E" + i, "E" + i).Value2; 
double doubleDate = double.Parse(date); 
DateTime finallyDate = DateTime.FromOADate(doubleDate); 

我已存储的日期是1961年1月12日(在意大利语中的意思第一十二月,如果我打开Excel它tolds我1961年12月1日)。

当我运行我的应用程序时,碰巧double的值变为15011.0,并且finallyDate值为2/4/1941时,这是不正确的!

我该如何解决这个问题?有什么方法可以转换(也是手动)15011号码吗?

谢谢!

+0

在分析之前,“date”本身的值究竟是什么? (我惊讶上面的代码甚至编译,因为'date'被声明为'object' ...) –

+1

@JonSkeet使用Excel Interop(在C#4之前,你可以使用动态)我认为一切都是作为对象返回。要使用分配运算符左侧以外的任何对象,您需要根据需要将它投射到右侧 – JMK

+1

@JMK:当然,对于第一条语句我没有问题 - 但没有double.Parse (object)'方法... –

回答

3

获得的价值属性,而不是值2,那么你将能够与Date对象的工作。您可能需要将其转换为(DateTime)。

你用Value2得到的是Date的浮点值。

例如,看看下面我的电子表格,其中,A1包含日期:

Spreadsheet

然后在Excel中,添加我参考Microsoft.Office.Interop。Excel和抢值和值2的属性,像这样:

var excel = new Excel.Application(); 

var workbook = excel.Workbooks.Open(@"C:\Test\Test.xlsx"); 
var worksheet = (Excel.Worksheet)workbook.Sheets[1]; 

Excel.Range range = worksheet.get_Range("A1"); 

var rangeAsValue = range.Value; 
var rangeAsValue2 = range.Value2; 

Console.WriteLine(rangeAsValue); 
Console.WriteLine(rangeAsValue2); 

Console.ReadLine(); 

我得到这样的输出:

Output

有趣的是,如果你尝试这种在.NET 4.5的应用程序,它仍然有效,但的类型被解析为rangeAsValuerangeAsValue2的动态,并且您失去了智能感知。

+0

嗨!我正在使用Microsoft Excel 12.0对象库...使用您的代码我看不到Value,但只有Value2! –

+1

我也使用12.0库,并针对.net 3.5客户端框架,这对我很有用。唯一使用的声明我需要添加'使用Excel = Microsoft.Office.Interop.Excel;' – JMK

+0

不知道为什么,但它仍然不会给我的日期,但一些数字...... :( –

0

您的问题的第一部分,我该如何解决这个问题?

做保证

  1. 文档保存。
  2. 您正在访问正确的单元格。

问题的第二部分,有什么办法可以将15011号码转换(也可以手动)吗?

15011实际上是1-1-1900的天数。我通常只是将提到的数字除以365得到一个粗糙的日期。你会问为什么粗糙?因为我们需要考虑闰年,一些年份有366天。

如果需要使用序列号日期的精确计算,你可能想使用这里找到的方法。 http://naspinski.net/post/Translate-an-Excel-Serial-Date-into-a-C-DateTime.aspx

public DateTime ExcelSerialDateToDT(int nSerialDate) 
{ 
int l = nSerialDate + 68569 + 2415019; 
int n = ((4 * l)/146097); 
l = l - ((146097 * n + 3)/4); 
int i = ((4000 * (l + 1))/1461001); 
l = l - ((1461 * i)/4) + 31; 
int j = ((80 * l)/2447); 
int nDay = l - ((2447 * j)/80); 
l = (j/11); 
int nMonth = j + 2 - (12 * l); 
int nYear = 100 * (n - 49) + i + l; 

return DateTime.Parse(nMonth + "/" + nDay + "/" + nYear); 
} 

你可以阅读更多关于为什么Microsoft Office Excel中此行为对 http://www.codeproject.com/Articles/2750/Excel-serial-date-to-Day-Month-Year-and-vise-versa

+0

嗨..文档已保存,我正在访问正确的单元格.. 如果我使用您建议的代码,我会得到同样的错误日期excel ..我得到2/4/1941 intstea of​​ 12/1/1961 –

+1

以上是静态DateTime.FromOADate()的一个相当差的版本 – Eddy

相关问题