NSDateComponentsFormatter的方法stringFromDate:ToDate:每秒返回一个不同的值



我正在尝试获取今天日期和未来日期之间的天数。我每秒调用以下内容:

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:2025];
[components setMonth:1];
[components setDay:1];
NSDate *currentDate = [NSDate date];
NSDate *futureDate = [[NSCalendar currentCalendar] dateFromComponents:components];
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorNone;
formatter.allowedUnits = NSCalendarUnitDay;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated;
NSString *remainingDaysAsString = [formatter stringFromDate:currentDate toDate:futureDate];

我每秒打印剩余的变量DaysAsString,它总是一天不同。

3,551d
3,551d
3,550d
3,550d
3,551d
3,550d
3,551d

有没有人经历过类似的事情?这看起来像是类的错误吗?

这很奇怪,看起来像一个错误。如果您指定,则NSDateComponentsFormatter的结果是正确的(在我的测试中)所有单位精确到秒:

formatter.allowedUnits = NSCalendarUnitDay + NSCalendarUnitHour + NSCalendarUnitMinute  + NSCalendarUnitSecond;

获取两个日期之间的天数的一种更简单可靠的方法是

NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitDay
                                                      fromDate:currentDate
                                                        toDate:futureDate
                                                       options:0];
NSInteger days = comp.day;

我遇到了同样的问题:

let fmt1 = NSDateComponentsFormatter()
fmt1.allowedUnits = .CalendarUnitYear |
    .CalendarUnitMonth |
    .CalendarUnitDay
let dc1 = NSDateComponents()
dc1.month = 1
dc1.day = 15
// This occasionally outputs "1 month, 14 days" instead of
// "1 month, 15 days" when the formatter is constrained to
// years, months and days. If formatter is allowed to use
// all units, the output is "1 month, 14 days, 23 hours,
// 59 minutes, 59 seconds".
fmt1.stringFromDateComponents(dc1)

可以通过指定正秒数并将其与限制允许的单位和/或将格式化程序参数设置为固定值maximumUnitCount

let fmt2 = NSDateComponentsFormatter()
fmt2.allowedUnits = .CalendarUnitYear |
    .CalendarUnitMonth |
    .CalendarUnitDay
fmt2.maximumUnitCount = 2
fmt2.collapsesLargestUnit = true
let dc2 = NSDateComponents()
dc2.month = 1
dc2.day = 15
dc2.second = 10
// This always outputs "1 month, 15 days"
fmt2.stringFromDateComponents(dc2)

因此,在您的情况下,只需为NSDateComponents分配一些正秒数:

[components setYear:2025];
[components setMonth:1];
[components setDay:1];
[components setSecond:10];

这将防止舍入误差。

我不知道

您描述的问题,只是想让您知道另一种方法。

NSDate * date1; 
NSDate * date2;
//assuming both vars contain a date
NSTimeInterval duration = [date2 timeIntervalSince1970] - [date1 timeIntervalSince1970];
NSLog("@days between %@ and %@: %f", date1, date2, duration / (24 * 60 * 60));

最新更新