2016-12-16 8 views
10

Mam do czynienia z problemem, gdy DateComponentsFormatter zwraca nieoczekiwaną liczbę jednostek. Czy ktoś zmierzył się z tym samym problemem?DateComponentsFormatter zwraca niepoprawną liczbę jednostek jednostkowych

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 

Spodziewam się otrzymać "2 tygodnie", ale mam "2 tygodnie 1 dzień".

+0

Dlaczego używasz '14.7'? – shallowThought

+0

@shallowThought Ustawiłem 'maximumUnitCount' - formater nie powinien zwracać więcej niż jedną jednostkę. –

+0

FYI - Używanie 'Date (timeIntervalSinceNow: -14.7 * 24 * 60 * 60)' jest okropnym sposobem na zrobienie matematyki daty. Nie każdy dzień ma 24 godziny. Nie każda godzina ma 3600 sekund. Użyj jednej z metod 'Data kalendarza (dodając ...)'. – rmaddy

Odpowiedz

1

Przechodzisz -14.7, który jest zaokrąglony do -15. Więc dostajesz 2 tygodnie 1 dzień. Tak, aby odpowiednio zwiększyć liczbę, aby uzyskać oczekiwane wyniki.

+3

Ustawiłem 'maximumUnitCount' - formater nie powinien zwracać więcej niż jedną jednostkę. –

+2

Dziwne. Jak tylko osiągniesz mniej niż -14,5, pokazuje tylko jedną jednostkę. Jeśli wybierzesz -15, to pokaże też tylko 1 jednostkę. Gdzieś pomiędzy -14,5 a -14,99, to zawiedzie. To samo dzieje się przy rozpoczęciu każdego nowego tygodnia. Mam na myśli -21, -28 i tak .. – Apurv

+0

dzięki. Teraz widzisz.) –

3

I rozwiązać problem, sprawdzając separator przecinek i użyciu go do podciąg wyjście DateFormatters, przykład plac zabaw w 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

Proponuję sprawdzić liczbę "," wystąpień w zależności od "maximumUnitCount", aby uczynić go bardziej ogólnym. Jednocześnie wiadomo, że wszystkie języki używają przecinka do oddzielania jednostek? –

+0

[Posty OpenRadar] (https://openradar.appspot.com/26354907) określa tylko, że 'maximumUnitCount = 1' wykazuje tylko błąd. Sprawdziłem [dokumentację] (https://developer.apple.com/reference/foundation/datecomponentsformatter/) i nie znalazłem żadnych informacji na temat separatorów. Fallback po prostu używa całego ciągu znaków bez zmian, więc myślę, że jest to akceptowalna opcja. – Mknsri

+0

OK, przekażę twoją odpowiedź, ponieważ robię prawie to samo. –

0

proponuję nieco bardziej niezawodne rozwiązanie (gdy jeszcze nie wiesz to działa dla wszystkich przypadków)

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]) 
} 
Powiązane problemy