Ich versuche, NSDate
von UIDatePicker
zu bekommen, aber es liefert mir ständig eine Datumszeit mit nachlaufenden 20 Sekunden. Wie kann ich manuell die NSDate
Sekunde auf Null setzen?So stellen Sie Sekunden auf Null für NSDate
Antwort
NSDate ist unveränderbar, daher kann die Zeit nicht geändert werden. Sie können jedoch ein neues Date-Objekt erstellen, die auf die nächste Minute schnappt:
NSTimeInterval time = floor([date timeIntervalSinceReferenceDate]/60.0) * 60.0;
NSDate *minute = [NSDate dateWithTimeIntervalSinceReferenceDate:time];
bearbeiten zu Ulis Kommentar
Das Referenzdatum verantworten NSDate
ist 1. Januar 2001, 0:00 Uhr GMT. Seither wurden zwei Schaltsekunden hinzugefügt: 2005 und 2010, daher sollte der von [NSDate timeIntervalSinceReferenceDate]
zurückgegebene Wert um zwei Sekunden abweichen. Dies ist nicht der Fall: timeIntervalSinceReferenceDate
ist genau synchron zur Wandzeit
Bei der Beantwortung der Frage habe ich nicht sichergestellt, dass dies tatsächlich wahr ist. Ich habe einfach angenommen, dass Mac OS behave as UNIX time (1970 Epoche) tut: POSIX garantiert, dass jeder Tag mit einem Vielfachen von 86.400 Sekunden beginnt.
Mit Blick auf die Werte von NSDate
scheint diese Annahme korrekt zu sein, aber es wäre sicher schön, eine definitive (dokumentierte) Aussage darüber zu finden.
NSDate
zeichnet einen einzigen Zeitpunkt auf. Wenn Sie einen bestimmten Tag speichern möchten, verwenden Sie nicht NSDate
. Sie werden viele unerwartete Kopfschmerzen in Bezug auf Zeitzonen, Sommerzeit e.tc.
Eine alternative Lösung besteht darin, den Tag als Integer im Quasi-ISO-Standardformat zu speichern, wie 20110915 für den 15. September 2011. Dies wird garantiert auf die gleiche Weise sortiert wie NSDate
sortieren würde.
Sie können NSTimeInterval nicht direkt manipulieren, da dies die Entfernung in Sekunden seit dem Referenzdatum ist, die nicht garantiert ist, eine 00-Sekunden-Zeit zu sein, wenn sie durch 60 geteilt wird eingefügt, um die Unterschiede zwischen Sonnenzeit und UTC anzupassen. Jeder Schaltsekunde würde werfen Sie weg von 1. Was ich tun, um die Sekunden meines Zeitpunkt 0 zu beheben ist:
NSDate * startDateTime = [NSDate date];
NSDateComponents * startSeconds = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate: startDateTime];
startDateTime = [NSDate dateWithTimeIntervalSinceReferenceDate: [startDateTime timeIntervalSinceReferenceDate] -[startSeconds second]];
Diese kümmert sich um Schaltsekunden. Ich denke, eine noch sauberere Weg wäre -dateByAddingComponents zu verwenden:
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];
diese Weise werden Sie garantiert sind, dass das, was das Besondere -dateByAddingComponents: kümmert sich um für als auch berücksichtigt wird.
Ich glaube, Ihre Behauptung über Schaltsekunden, die das 'timeIntervalSinceReferenceDate 'beeinflussen, ist nicht wahr. Während Apples Date and Time Programming Guide das Verhalten nicht explizit definiert, macht POSIX dies für die UNIX-Zeit: Leap-Sekunden werden ignoriert (siehe http://en.wikipedia.org/wiki/Unix_time). Es scheint, dass dies auch für Cocoa gilt. –
Ein weiterer Gedanke: Beide von Ihnen vorgeschlagenen Lösungen berücksichtigen keine Bruchteile von Sekunden. Sie berechnen die (ganzzahlige) Anzahl von Sekunden und subtrahieren sie vom ursprünglichen Datum. Das Ergebnis bezieht sich auf eine Zeit mit null Sekunden, aber nicht null Millisekunden, was ein bisschen seltsam ist. –
Obwohl dies eine alte Frage ist und Uli die "richtige" Antwort gegeben hat, ist die einfachste Lösung IMHO, einfach die Sekunden vom Datum zu subtrahieren, wie es aus dem Kalender kommt. Beachten Sie, dass dies immer noch Millisekunden an Ort und Stelle bleiben kann.
NSDate *date = [NSDate date];
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond
fromDate:date];
date = [date dateByAddingTimeInterval:-comp.second];
Hier ist eine Erweiterung dieses in Swift zu tun:
extension NSDate {
func truncateSeconds() -> NSDate {
let roundedTime = floor(self.timeIntervalSinceReferenceDate/60) * 60
return NSDate(timeIntervalSinceReferenceDate: roundedTime)
}
}
ist hier ein Swift-Erweiterung für alle Interessierten:
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
}
}
Beispiel Nutzung:
let date = Date()
date.floorSeconds()
Verwenden DateComponents
ist viel robuster als das Hinzufügen eines Zeitintervalls zu einem Datum.
- 1. So stellen Sie die Suchzeit auf jwplayer
- 2. So stellen Sie Achsenstartpunkt auf 0 für Google Material Liniendiagramm
- 3. So stellen Sie ein Datumsformat auf dem iPhone ein
- 4. So drucken Sie Zeit bis zu 6 Stellen der Genauigkeit für Sekunden Wert
- 5. So stellen Sie UIcolor auf tiefblau ein
- 6. So stellen Sie die Bildschirmhelligkeit auf
- 7. So stellen Sie kAudioUnitSubType_Distortion ein
- 8. So stellen Sie die Zeit für den beantworteten Kanal ein
- 9. So stellen Sie Klassenmethoden vor
- 10. NSDate String Gibt null zurück
- 11. So stellen Sie die Rückkehr-URL für DotNetOpenAuth ein
- 12. So stellen Sie sicher, dass ein WinForm in genau X Sekunden schließt
- 13. So stellen Sie den Eckenradius für die Bildansicht ein
- 14. So stellen Sie ToolBar statt ActionBar ein
- 15. So stellen Sie Timeout für JAX-WS WebService-Aufruf ein
- 16. So stellen Sie Inhaltstypen effizient für einen Inhaltstypen-Hub bereit
- 17. So stellen Sie die Webpack-App auf heroku bereit
- 18. So stellen Sie die Ruftonlautstärke im Ziel auf 0 - c
- 19. So stellen Sie Hyperledger-Blockchain auf IBM Bluemix
- 20. So stellen Sie eine Bereitstellung für eine bestimmte Instanz bereit
- 21. So stellen Sie TimeOut für OwinContext in MVC ein 5
- 22. So stellen Sie den Apache CXF-Webservice für Glassfish bereit
- 23. So stellen Sie Audio- und Videodaten für MediaMux bereit
- 24. So stellen Sie eine Standardauthentifizierung für Kibana4 zur Verfügung
- 25. So stellen Sie ein C++ - Modell für QML bereit
- 26. So stellen Sie Dockerfile und Anwendungsdateien auf boot2docker
- 27. NSDate von String ist immer null
- 28. So stellen Sie eine domänenübergreifende Anfrage her
- 29. So stellen Sie VB6-Anwendungen bereit?
- 30. So stellen Sie TimeZone mit Powershell ein
Dies wird nicht funktionieren. Das Zeitintervall seit dem Referenzdatum ist nicht garantiert, ein gerades Vielfaches von 60 für eine Zeit zu sein, die 00 Sekunden hat. Es ist die Anzahl der Sekunden seit dem Referenzdatum, und daher werden Schaltsekunden, die gelegentlich eingefügt werden, Sie davon abhalten. Ich denke, Sie müssen NSCalendar verwenden, um herauszufinden, welche Sekunden Ihr Datum hat, dann subtrahieren Sie * das * vom Zeitintervall. – uliwitness
Die Zeit, die Sie erhalten, kann eine Minute in der Zukunft sein, wenn die aktuelle Minute die 30-Sekunden-Marke überschreitet. Dies geschieht, weil Runde runden könnte. Versuchen Sie es mit 'floor ([Datum timeIntervalSinceReferenceDate]/60.0) * 60.0;' –
@flovonderuni Guter Fang. Die Ergebnisse von 'floor' schalten gleichzeitig Wanduhren. Bearbeitete Antwort, danke! –