DateComponentsFormatter返回错误的单位计数数



DateComponentsFormatter返回意外数量的单位时,我就面临问题。有人面临同样的问题吗?

import Foundation
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full;
formatter.maximumUnitCount = 1;
let date = Date(timeIntervalSinceNow: -14.7 * 24 * 60 * 60)
let dateString = formatter.string(from: date, to: Date()) // 2 weeks 1 day

我希望收到" 2周",但有" 2周1天"。

i通过检查逗号分隔符并将其用于订阅DateFormatters输出,在Swift 3

中使用它来解决问题。
// Test date
var df = DateFormatter()
df.dateFormat = "dd.MM.yyyy HH:mm:ss"
df.timeZone = TimeZone(secondsFromGMT: 0)
let fromDate = df.date(from: "01.01.2000 00:00:00")
var timeDifference = Date().timeIntervalSince(fromDate!)
// Setup formatter
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.includesApproximationPhrase = false
formatter.zeroFormattingBehavior = .dropAll
formatter.maximumUnitCount = 1
formatter.allowsFractionalUnits = false
// Use the configured formatter to generate the string.
var outputString = formatter.string(from: timeDifference) ?? ""
// Remove 2nd unit if exists
let commaIndex = outputString.characters.index(of: ",") ?? outputString.endIndex
outputString = outputString.substring(to: commaIndex)
// Result
print(outputString)

您正在通过-14.7,该-14.7为-15。因此,您要2周1天。因此,正确地将数字舍入以获得预期结果。

我会提出一些更可靠的解决方案(虽然不确定它对所有情况都有效)

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.maximumUnitCount = 1
let date = Date(timeIntervalSinceNow: -14.7 * 24 * 60 * 60)
let dateString = formatter.string(from: date, to: Date()) ?? ""
if let nsRange = try? NSRegularExpression(pattern: "\A\d* \w*").rangeOfFirstMatch(in: dateString, options: [], range: NSRange(location: 0, length: dateString.count)), let range = Range(nsRange, in: dateString) {
    let fixedString = String(dateString[range])
}

对于那些仍在寻找答案的人,这就是我发现的:

当前,解决此问题只有1个相对漂亮的方法,它是使用pod https://github.com/matthewyork/datetook.

至少直到https://openradar.appspot.com/26354907由苹果解决。

解决这个问题一段时间后,我设计了一个简单的解决方法,可能(或可能)对某些问题的人有效。该方法的作用是,它添加了提到的雷达错误报告中描述的时间,该报告导致错误出现:

/// Workaround for a known bug in `DateComponentsFormatter` that causes `maximumUnitCount` variable value to be ignored sometimes https://openradar.appspot.com/26354907
///
/// - Parameters:
///   - fromDate: First (earlier) date.
///   - toDate: Second (later) date.
///   - dateFormatter: Instance of `DateComponentsFormatter` with properly set `maximumUnitCount` property.
/// - Returns: Corrected timestamp with only one unit. Eg. `1d 1h` will be corrected to `1d`.
private static func correctedTimestamp(from fromDate: Date, to toDate: Date, dateFormatter: DateComponentsFormatter) -> String? {
    guard
        let days = Calendar.current.dateComponents([.day], from: fromDate, to: toDate).day,
        let hours = Calendar.current.dateComponents([.hour], from: fromDate, to: toDate).hour,
        let minutes = Calendar.current.dateComponents([.minute], from: fromDate, to: toDate).minute,
        days > 0,
        days * 24 - hours == 0,
        days * 24 * 60 - minutes < 0,
        let timestamp = dateFormatter.string(from: fromDate, to: toDate.addingTimeInterval(Double(days * 24 * 60 - minutes) * 60))
    else { return nil }
    return timestamp
}

最新更新