Próbuję uzyskać NSDate
z UIDatePicker
, ale ciągle zwraca mi datę z końcem 20 sekund. Jak ręcznie ustawić NSDate
sekundę do zera?Jak ustawić sekundy na zero dla NSDate
Odpowiedz
NSDate jest niezmienny, więc nie można zmienić jego czasu. Ale można utworzyć nowy obiekt Date, który jest przyciągany do najbliższej minuty:
NSTimeInterval time = floor([date timeIntervalSinceReferenceDate]/60.0) * 60.0;
NSDate *minute = [NSDate dateWithTimeIntervalSinceReferenceDate:time];
Edycja, aby odpowiedzieć na komentarz Uli za
Datą odniesienia dla NSDate
jest 1 stycznia, 2001, 00:00 GMT. Od tego czasu dodano dwie sekundy przestępczości: 2005 i 2010, więc wartość zwrócona przez [NSDate timeIntervalSinceReferenceDate]
powinna być wyłączona o dwie sekundy.
Nie dotyczy: timeIntervalSinceReferenceDate
jest dokładnie synchroniczna z czasem ściany.
Podczas odpowiadania na pytanie nie upewniłem się, że jest to prawda. Właśnie założyłem, że Mac OS będzie miał behave as UNIX time (1970 rok): POSIX gwarantuje, że każdy dzień zaczyna się od wielokrotności 86 400 sekund.
Patrząc na wartości zwrócone z NSDate
to założenie wydaje się prawidłowe, ale na pewno dobrze byłoby znaleźć określone (udokumentowane) oświadczenie o tym.
rejestruje pojedynczy moment w czasie. Jeśli chcesz zachować określony dzień, nie używaj NSDate
. Otrzymasz wiele nieoczekiwanych bólów głowy związanych ze strefami czasowymi, czas letni e.tc.
Jednym z alternatywnych rozwiązań jest przechowywanie dnia jako liczby całkowitej w formacie standardowym quasi-ISO, na przykład 20110915 z 15 września 2011 r. Gwarantuje to sortowanie w ten sam sposób, w jaki sortuje się NSDate
.
Nie można bezpośrednio manipulować NSTimeInterval, ponieważ jest to odległość w sekundach od daty odniesienia, co nie jest gwarantowane jako 00-sekundowy czas podzielony przez 60. W końcu mogły być sekundy przestępne włożona, aby skorygować różnice między czasem słonecznym a czasem UTC. Każdy drugi skok byłoby wyrzucić cię o 1. Co zrobić, aby naprawić sekund moim dniu 0 wynosi:
NSDate * startDateTime = [NSDate date];
NSDateComponents * startSeconds = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate: startDateTime];
startDateTime = [NSDate dateWithTimeIntervalSinceReferenceDate: [startDateTime timeIntervalSinceReferenceDate] -[startSeconds second]];
ta zajmuje sekundy przestępne. Chyba jeszcze bardziej przejrzysty sposób byłoby użyć -dateByAddingComponents:
NSDate * startDateTime = [NSDate date];
NSDateComponents * startSeconds = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate: startDateTime];
[startSeconds setSecond: -[startSeconds second]];
startDateTime = [[NSCalendar currentCalendar] dateByAddingComponents: startSeconds toDate: startDateTime options: 0];
Dzięki temu masz gwarancję, że bez względu na specjalny rzeczy -dateByAddingComponents: dba o rozlicza również.
Wierzę, że twoje roszczenie dotyczące sekund przestępnych wpływające na 'timeIntervalSinceReferenceDate' nie jest prawdziwe. Podczas gdy Przewodnik programowania daty i czasu firmy Apple nie definiuje jawnie zachowania, POSIX robi to dla czasu UNIX: sekundy przestępne są ignorowane (patrz http://pl.wikipedia.org/wiki/Unix_time). Wygląda na to, że odnosi się to również do kakao. –
Inna myśl: oba proponowane rozwiązania nie uwzględniają ułamków sekundy. Oblicza się liczbę (całkowitą) sekund i odejmuje je od daty pierwotnej. Wynik odnosi się do czasu z zerową sekundą, ale niezerową milisekundą, co jest nieco dziwne. –
Mimo że jest to stare pytanie, a Uli podał "poprawną" odpowiedź, najprostszym rozwiązaniem jest odjęcie sekund od daty, tak jak otrzymano z kalendarza. Pamiętaj, że może to pozostawiać milisekundy na miejscu.
NSDate *date = [NSDate date];
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond
fromDate:date];
date = [date dateByAddingTimeInterval:-comp.second];
Tutaj jest przedłużeniem to zrobić w Swift:
extension NSDate {
func truncateSeconds() -> NSDate {
let roundedTime = floor(self.timeIntervalSinceReferenceDate/60) * 60
return NSDate(timeIntervalSinceReferenceDate: roundedTime)
}
}
Oto Swift rozszerzenie dla każdego, kto jest zainteresowany:
extension Date {
public mutating func floorSeconds() {
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self)
self = calendar.date(from: components) ?? self // you can handle nil however you choose, probably safe to force unwrap in most cases anyway
}
}
Przykład użycia:
let date = Date()
date.floorSeconds()
Korzystanie z DateComponents
jest znacznie solidniejsze niż dodanie przedziału czasowego do daty.
- 1. Jak ustawić tylko czas w zmiennej NSDate?
- 2. Dlaczego musimy ustawić zmienną __block na zero?
- 3. Oracle Konwertuj sekundy na godziny: minuty: Sekundy
- 4. Jak otrzymać NSDate na 00:00 w dniu [data NSDate]?
- 5. Jak wyciąć na zero?
- 6. Konwersja jiffies na sekundy
- 7. NSDate dla pierwszego dnia miesiąca
- 8. Jak rozbić NSTimeInterval na rok, miesiące, dni, godziny, minuty i sekundy na iPhonie?
- 9. NSDateComponents of NSDate
- 10. Obiektyw C iPhone, kiedy ustawić odniesienia do obiektu na zero
- 11. Jak wyłączyć błąd "Podziel przez zero" i ustawić wynik na wartość null dla całej aplikacji?
- 12. Ruby/Rails - jak przekonwertować sekundy na czas?
- 13. Znajdź NSDate na następny poniedziałek
- 14. Jakiego rodzaju właściwość należy ustawić na zero w dealloc?
- 15. Porównywanie NSDate do [data NSDate]
- 16. Jak ustawić datę UIDatePicker na inną datę?
- 17. Jak NSLog NSDate?
- 18. Czy lepiej ustawić pustą tabelę lub ustawić wszystkie elementy tabeli na zero?
- 19. IOS jak ustawić format daty
- 20. Generyczne zero dla funkcji ogólnej
- 21. Jakie jest zero dla napisu?
- 22. Jak dodawać godziny do NSDate?
- 23. Jak czekać przez 2 sekundy
- 24. Atrybut Core Data zmienia się na zero (ARC related?)
- 25. Konwersja sekund na minuty i sekundy
- 26. Jak wstrzymać wykonywanie kodu javascript na 2 sekundy
- 27. Konwertuj czas na sekundy wydania ciągu znaków
- 28. Jak przekonwertować czas trwania interfejsu API YouTube na sekundy?
- 29. Jak przekonwertować NSNull na zero w Swift?
- 30. Jak zmienić NSString w NSDate?
To nie zadziała. Przedział czasu od daty odniesienia nie może być równy wielokrotności 60 dla czasu, który ma 00 sekund. Jest to liczba sekund od daty odniesienia i jako takie, sekundy przestępne, które czasami są wstawiane, wyrzucą cię. Myślę, że będziesz musiał użyć NSCalendar, aby dowiedzieć się, jakie sekundy ma data, a następnie odejmij * to * od przedziału czasu. – uliwitness
Czas, jaki otrzymasz, może wynosić jedną minutę w przyszłości, jeśli aktualna minuta minie 30 sekund. Dzieje się tak, ponieważ runda może zaokrąglić. Spróbuj z 'podłogą ([date timeIntervalSinceReferenceDate]/60.0) * 60.0;' –
@flovonderuni Dobry połów. Wyniki z przełącznika 'podłogowego' w tym samym czasie robią zegary ścienne. Edytowana odpowiedź, dzięki! –