我正在将日期从Excel电子表格转换为NSDate,但出于某种原因,它们总是提前两天出现:星期天出现在星期二等等。
我的转化方法基于cpearson.com的以下信息:
Excel将日期和时间存储为表示数字的数字 自1900年1月1日以来的几天,加上24小时工作日的一小部分:
ddddd.tttttt。这称为序列日期或序列日期时间。 (...)数字的整数部分ddddd表示数字 自1900年1月1日以来的几天。 (...)数字的小数部分, ttttt,表示24小时工作日的小数部分。对于 例如,上午6:00存储为0.25,或24小时工作日的25%。 同样,6PM存储在0.75,或24小时工作日的75%。
- (NSDate *)dateFromExcelSerialDate:(double)serialdate
{
if (serialdate == 0)
return nil;
NSTimeInterval theTimeInterval;
NSInteger numberOfSecondsInOneDay = 86400;
double integral;
double fractional = modf(serialdate, &integral);
NSLog(@"%@ %@ \r serialdate = %f, integral = %f, fractional = %f",
[self class], NSStringFromSelector(_cmd),
serialdate, integral, fractional);
theTimeInterval = integral * numberOfSecondsInOneDay; //number of days
if (fractional > 0) {
theTimeInterval += numberOfSecondsInOneDay / fractional; //portion of one day
}
NSCalendar *nl_gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSTimeZone *nl_timezone = [[NSTimeZone alloc] initWithName:@"Europe/Amsterdam"];
[nl_gregorianCalendar setTimeZone:nl_timezone];
NSDateComponents *excelBaseDateComps = [[NSDateComponents alloc] init];
[excelBaseDateComps setMonth:1];
[excelBaseDateComps setDay:1];
[excelBaseDateComps setHour:00];
[excelBaseDateComps setMinute:00];
[excelBaseDateComps setTimeZone:nl_timezone];
[excelBaseDateComps setYear:1900];
NSDate *excelBaseDate = [nl_gregorianCalendar dateFromComponents:excelBaseDateComps];
NSDate *inputDate = [NSDate dateWithTimeInterval:theTimeInterval sinceDate:excelBaseDate];
NSLog(@"%@ %@ \r serialdate %f, theTimeInterval = %f \r inputDate = %@",
[self class], NSStringFromSelector(_cmd),
serialdate, theTimeInterval,
[self.nl_dateFormatter stringFromDate:inputDate]);
return inputDate;
}
该电子表格是在荷兰制作的,大概是荷兰语版的Microsoft Excel。 电子表格日期2014年7月6日星期日00:00产生以下结果: dateFromExcelSerialDate:
serialdate = 41826.000000,integral = 41826.000000,fractional = 0.000000 theTimeInterval = 3613766400.000000 inputDate = 08 jul。 2014 01:40
同样,2014年7月13日星期日00:00收益率:
serialdate = 41833.000000,integral = 41833.000000,fractional = 0.000000 theTimeInterval = 3614371200.000000 inputDate = 15 jul。 2014 01:40
我可以通过减去2天,1小时40分钟来纠正输出:
theTimeInterval -= ((60 * 60 * 24 * 2) + (60*60) + (60*40));
但我不知道那是多么强大。
这两天的差异让我觉得它与闰年修正有关,所以我试图让日历通过在excelBaseDate中添加NSTimeInterval秒来进行计算,如下所示:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setSecond:theInterval];
NSDate *inputDate = [nl_gregorianCalendar dateByAddingComponents:comps
toDate:excelBaseDate
options:0];
奇怪的是,这给了我1870年代的某个日期。谁知道发生了什么?
答案 0 :(得分:-1)
这里有两件事:
您的开始日期为1900-Jan-1
,但您的推荐说明明确指出:引用为1900-Jan-0
- 您可以在此处添加额外的一天;
1900年不是闰年 - 你可以在这里额外增加一天;
我想,这就是为什么你每次都要多加两天的原因。
Microsoft在此处了解see more有关此主题的信息。