2016-12-16 3 views
10

Я столкнулся с проблемой, когда 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 день».

+0

Почему вы используете '14.7'? – shallowThought

+0

@shallowThought Я установил 'maximumUnitCount' - форматтер не должен возвращать более одного блока. –

+0

FYI - Использование 'Date (timeIntervalSinceNow: -14.7 * 24 * 60 * 60)' - ужасный способ сделать математику по дате. Не каждый день имеет 24 часа. Не каждый час имеет 3600 секунд. Используйте один из методов 'Calendar date (byAdding ...)'. – rmaddy

ответ

1

Вы проходили мимо -14.7, округленное от -15. Таким образом, вы получаете 2 недели 1 день. Так округлите число, чтобы получить ожидаемые результаты.

+3

Я установил 'maximumUnitCount' - форматтер не должен возвращать более одного устройства. –

+2

Странно. Как только u сделает его меньше -14.5, он показывает только один блок. Если вы делаете -15, то также отображается только 1 единица. Где-то между -14.5 до -14.99 он терпит неудачу. То же самое наблюдается при начале любой новой недели. Я имею в виду -21, -28 и так .. – Apurv

+0

спасибо. Теперь вы видите.) –

3

Я решил проблему путем проверки запятой и использовать его для подстроки выхода 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) 
+0

Я предлагаю проверить число «,» вхождения в зависимости от 'maximumUnitCount', чтобы сделать его более общим. В то же время известно ли, что все языки используют запятую для разделения единиц? –

+0

[Сообщение OpenRadar] (https://openradar.appspot.com/26354907) указывает только, что «maximumUnitCount = 1» обнаруживает ошибку. Я проверил [документацию] (https://developer.apple.com/reference/foundation/datecomponentsformatter/) и не нашел никакой информации о разделителях. Резерв просто использует всю строку без изменений, поэтому я считаю, что это приемлемый резерв. – Mknsri

+0

Хорошо, я отвечу на ваш ответ, потому что я делаю почти то же самое. –

0

Я бы предложил немного более надежное решение (пока еще не уверено, что это работает для всех случаев)

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]) 
} 
Смежные вопросы