我正在将日期从Excel电子表格转换为NSDate的日期,但是由于某些原因,它们总是提前两天出现:星期日是星期二,等等。
我的转换方法基于cpearson.com的以下信息:
Excel将日期和时间存储为一个数字,表示自1900年1月0日以来的天数,再加上一个24小时工作日的一个小数部分:
ddddd.tttttt。这称为序列日期或序列日期时间。(...)数字的整数部分ddddd表示自1900年1月0日以来的天数。(...)数字的小数部分ttttt表示一天24小时的小数部分。例如,6:00 AM被存储为0.25,或一天24小时的25%。同样,下午6点存储的时间为一天24小时的0.75,即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,小数= 0.000000 theTimeInterval = 3613766400.000000 inputDate = 08 jul。2014年01:40
同样,2014年7月13日,星期日,00:00产生:
序列日期= 41833.000000,整数= 41833.000000,分数= 0.000000 theTimeInterval = 3614371200.000000 inputDate = 15七月。2014年01:40
我可以通过减去2天1小时40分钟来更正输出:
theTimeInterval -= ((60 * 60 * 24 * 2) + (60*60) + (60*40));
但我不知道那有多健壮。
两天的时间差使我认为它与year年修正有关,因此我尝试通过将nsTimeInterval秒添加到excelBaseDate中,让日历进行计算,如下所示:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setSecond:theInterval];
NSDate *inputDate = [nl_gregorianCalendar dateByAddingComponents:comps
toDate:excelBaseDate
options:0];
奇怪的是,这给了我1870年代的约会。谁知道发生了什么事?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句