C# – Exceldate不通过date序列在Value2中

我有一个Excel表单,里面有一个人的生日列表,内容如下:

Mary 08/17/1993 John 01/23/1991 Ann 12/07/1989 

其中左栏为“GENERAL”格式,右栏为“DATE”格式。 目的是要有一个窗口服务,每天将读这个生日列表,并发出任何“生日快乐! 适用的电子邮件。

这是我用来阅读excel数据的代码:

 public static List<Tuple<string, DateTime>> getBirthdays() { List<Tuple<string, DateTime>> birthdays = new List<Tuple<string, DateTime>>(); Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Users\AGuaja\Desktop\birthdays.xlsx"); Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1]; Excel.Range xlRange = xlWorksheet.UsedRange; int rowCount = xlRange.Rows.Count; int colCount = xlRange.Columns.Count; string user = String.Empty; DateTime bday = DateTime.Now; for (int i = 1; i <= rowCount; i++) { for (int j = 1; j <= colCount; j++) { if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null) { if (j == 1) user = xlRange.Cells[i, j].Value2.ToString(); else bday = DateTime.FromOADate(double.Parse(xlRange.Cells[i, j].Value2)); } } birthdays.Add(new Tuple<string, DateTime>(user, bday)); } GC.Collect(); GC.WaitForPendingFinalizers(); Marshal.ReleaseComObject(xlRange); Marshal.ReleaseComObject(xlWorksheet); xlWorkbook.Close(); Marshal.ReleaseComObject(xlWorkbook); xlApp.Quit(); Marshal.ReleaseComObject(xlApp); return birthdays; } 

在search了一下之后,我了解到从Excel获取date的正确方法是使用FromOADate方法,例如,需要FromOADatedouble精度值来表示date。 然而事情是,我的Value2没有返回该date序列,而是上面看到的格式的值,12/07/1989,因此我不能使用转换Exceldate的“正确方法” 。

我的意思是,当然,我可以使用Value2的string,并将其parsing为Date,但为什么值不能正确传递呢?

我认为你可能会让这个过程变得更加复杂。 如果您只是从单元格中查找date,请使用DateTime.TryParse(…) 。 即使列设置为Date ,用户也可以像在Excel中一样进行任何操作。 问题是,你不能依靠Excel来返回一个有效的date,所以只需检查它是否有效,并作出适当的反应。 下面的代码将做到这一点。

 DateTime cellDate; if (DateTime.TryParse(xlRange.Cells[i, j].Value, out cellDate)) { Console.WriteLine("Valid Date: " + cellDate.ToLongDateString()); } else { Console.WriteLine("Date Is Invalid: " + xlRange.Cells[i, j].Value); } 

希望这可以帮助!

编辑OP答复

我很高兴你发现你遇到的问题。 不过,我必须说,我认为你仍然错过了我的观点。 你不能依赖于具有适当值的Excel单元格。 在大多数情况下,如果你从excel单元中获得值,并且你想在你的程序中使用这些值来获得string以外的值,你必须validation这个值,以防止你的代码崩溃。 在你的修复…你只是确保在Excel单元格中的值格式正确。 将来,如果您无意中input了错误的格式,程序将会崩溃。 这在任何环境中都是不可取的。

使用你的生日邮件或电子贺卡的例子是微不足道的,没有那么重要,除非有人真的想要他们的生日电子贺卡。 在这个“生日”的情况下,忽略无效数据是可以接受的; 然而,知道为什么它没有被发送可能是很好的。 在您当前的代码中,您将通过崩溃意识到这种情况。 所以你必须去查找无效的date,如果它足够重要,并在Excel中修复它。

给你的描述让我们假设它足够重要,试图修复无效的date。 这里出现了几个问题。 正如你在答案中所说的那样,你的MM / DD / YYYY(美国)date默认为dd / MM / YYYY格式 。在这种情况下,只有“你”会知道这一点。 如果其他人input的date你不可能知道03/10/1997是否正确或10/03/1997是正确的,因为两者都是有效的date。 在这种情况下,它只是错误的生日date,无论是由您或其他用户input。 当两个date都有效时,你可以做的绝对是零,以防止这种情况发生。 如果一个大公司犯了这个错误,直到客户抱怨他们在错误的date得到了他们的生日电子名片,才可能知道这个错误。

最后,当我开始的时候,你的当前代码有一个错误,如果date格式无效,将会崩溃。 这里的问题是你知道这一点,而不是在你的代码中解决这种情况。 这是错误的方法; 修复你的代码,使其不会崩溃。

所以经过一些debugging,我意识到问题所在。 我input了MM/dd/YYYY (美国)date,而这些date默认为dd/MM/YYYY格式。 尽pipe这个string在技术上是正确的,但是这个date本身是无效的,这就是为什么没有date序列被传递的原因。

更改date以匹配正确的格式(或者为他们指定美国惯例)解决了这个问题。