Swift ma swój własny Datetyp. Nie ma potrzeby używania NSDate.
Tworzenie daty i godziny w Swift
W języku Swift daty i godziny są przechowywane w 64-bitowej liczbie zmiennoprzecinkowej mierzącej liczbę sekund od daty odniesienia 1 stycznia 2001 r. O godzinie 00:00:00 czasu UTC . Wyraża się to w Datestrukturze . Poniższe informacje podają aktualną datę i godzinę:
let currentDateTime =Date()
Aby utworzyć inne daty i godziny, możesz użyć jednej z następujących metod.
Metoda 1
Jeśli znasz liczbę sekund przed lub po dacie odniesienia 2001, możesz z tego skorzystać.
let someDateTime =Date(timeIntervalSinceReferenceDate:-123456789.0)//Feb2,1997,10:26 AM
Metoda 2
Oczywiście łatwiej byłoby użyć takich rzeczy jak lata, miesiące, dni i godziny (zamiast względnych sekund), aby utworzyć plik Date. W tym celu możesz użyć, DateComponentsaby określić składniki, a następnie Calendarutworzyć datę. To Calendardaje Datekontekst. W przeciwnym razie skąd miałoby wiedzieć, w jakiej strefie czasowej lub kalendarzu ma to wyrazić?
// Specify date components
var dateComponents =DateComponents()
dateComponents.year =1980
dateComponents.month =7
dateComponents.day =11
dateComponents.timeZone =TimeZone(abbreviation:"JST")// Japan Standard Time
dateComponents.hour =8
dateComponents.minute =34// Create date from components
let userCalendar =Calendar.current // user calendar
let someDateTime = userCalendar.date(from: dateComponents)
Inne skróty stref czasowych można znaleźć tutaj . Jeśli pozostawisz to pole puste, domyślnie używana jest strefa czasowa użytkownika.
Metoda 3
Najbardziej zwięzłym (ale niekoniecznie najlepszym) sposobem może być użycie DateFormatter.
let formatter =DateFormatter()
formatter.dateFormat ="yyyy/MM/dd HH:mm"let someDateTime = formatter.date(from:"2016/10/08 22:31")
Zauważ, że ta implementacja nie buforuje NSDateFormatter, co możesz chcieć zrobić ze względu na wydajność, jeśli spodziewasz się tworzenia wielu plików NSDatew ten sposób.
Należy również pamiętać, że ta implementacja po prostu ulegnie awarii, jeśli spróbujesz zainicjować an NSDateprzez przekazanie ciągu, którego nie można poprawnie przeanalizować. Dzieje się tak z powodu wymuszonego rozpakowania wartości opcjonalnej zwróconej przez dateFromString. Jeśli chciałbyś zwrócić a nilprzy złej analizie, najlepiej byłoby użyć nieudanego inicjatora; ale nie możesz tego zrobić teraz (czerwiec 2015) z powodu ograniczeń w Swift 1.2, więc następnym najlepszym wyborem jest użycie metody fabryki klas.
Wskazuje, że rozszerzenie udostępnia inicjator, który w rzeczywistości deleguje inicjalizację do już istniejącego wyznaczonego inicjatora, którym w tym przypadku jest inicjator NSDate.init (timeInterval:, sinceDate :). Jest to opisane na stronie 275 książki Swift Programming Language.
glony
1
Jedna wada, którą widzę w powyższym kodzie, polega na ponownym tworzeniu się za NSDateFormatterkażdym razem, gdy uzyskuje się dostęp do funkcji. Jak podaje przewodnik po formatowaniu daty , utworzenie programu formatującego datę nie jest tanią operacją . Ponadto klasa jest bezpieczna dla wątków od iOS7, więc można ją bezpiecznie używać dla wszystkich NSDaterozszerzeń.
Yevhen Dubinin
@eugenedubinin poprawnie. dlatego powiedziałem "ta implementacja nie buforuje NSDateFormatter, co możesz chcieć zrobić ze względu na wydajność".
Swift nie ma własnego typu Date, ale możesz użyć istniejącego NSDatetypu Cocoa , np .:
classDate{classfunc from(year:Int, month:Int, day:Int)->Date{let gregorianCalendar =NSCalendar(calendarIdentifier:.gregorian)!var dateComponents =DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
let date = gregorianCalendar.date(from: dateComponents)!return date
}classfunc parse(_ string:String, format:String="yyyy-MM-dd")->Date{let dateFormatter =DateFormatter()
dateFormatter.timeZone =NSTimeZone.default
dateFormatter.dateFormat = format
let date = dateFormatter.date(from: string)!return date
}}
Które możesz użyć na przykład:
var date =Date.parse("2014-05-20")var date =Date.from(year:2014, month:05, day:20)
Musiałem zmienić wiersz: var date = gregorian? .DateFromComponents (c), ale nie rozumiem dlaczego, a parse return dateFmt.dateFromString też narzeka. Jakieś wskazówki? Ach, zmieniłem zwracany typ funkcji z NSDate na NSDate? co pozwala na kompilację. Ale nie jestem pewien, dlaczego musi mieć wartość zerową.
Senator
1
@TheSenator NSCalendar init zwraca opcjonalny (?), Więc gregoriański jest opcjonalny (?). Dostęp do opcjonalnej potrzeby Opcjonalne łańcuchowanie dostępu do niego tak gregoriańskiego? .DateFromCoomponents jest opcjonalnym łańcuchem do rozpakowywania wartości z opcji gregoriańskich (NSCalendar). Więcej informacji na temat opcjonalnego łączenia łańcuchowego tutaj
iluvatar_GR
NSGregorianCalendar jest przestarzałe od iOS 8, więc zamiast tego użyj NSCalendarIdentifierGregorian
Adam Knights
2
@The Senator Complains coz Swift ma strukturę Date, a ten kod ponownie określa Date jako klasę. Więc powinieneś zrobić coś w stylu: 'extension Date' i 'static func'
Zaporozhchenko Oleksandr
Notatka o parsowaniu ciągu z powrotem do daty. Ciąg „1979-07-01” z „rrrr-MM-dd” dla NSDateFormattermetody date(from:). Wraca nil. Znalazłem ten problem w dzienniku awarii fabric.io.
AechoLiu
12
Oto, jak zrobiłem to w Swift 4.2:
extensionDate{/// Create a date from specified parameters
///
/// - Parameters:
/// - year: The desired year
/// - month: The desired month
/// - day: The desired day
/// - Returns: A `Date` object
staticfunc from(year:Int, month:Int, day:Int)->Date?{let calendar =Calendar(identifier:.gregorian)var dateComponents =DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
return calendar.date(from: dateComponents)??nil}}
Stosowanie:
let marsOpportunityLaunchDate =Date.from(year:2003, month:07, day:07)
Tworzenie programu formatującego datę nie jest tanią operacją. Jeśli często używasz programu formatującego, zwykle bardziej wydajne jest buforowanie pojedynczego wystąpienia niż tworzenie i usuwanie wielu wystąpień. Jednym podejściem jest użycie zmiennej statycznej
I chociaż zgadzam się z @Leon, że powinien to być dostępny inicjator, kiedy wprowadzasz dane początkowe, możemy mieć taki, który nie jest dostępny (tak jak jest UIImage(imageLiteralResourceName:)).
NSDate
tak jak w Objective-C?Odpowiedzi:
Swift ma swój własny
Date
typ. Nie ma potrzeby używaniaNSDate
.Tworzenie daty i godziny w Swift
W języku Swift daty i godziny są przechowywane w 64-bitowej liczbie zmiennoprzecinkowej mierzącej liczbę sekund od daty odniesienia 1 stycznia 2001 r. O godzinie 00:00:00 czasu UTC . Wyraża się to w
Date
strukturze . Poniższe informacje podają aktualną datę i godzinę:Aby utworzyć inne daty i godziny, możesz użyć jednej z następujących metod.
Metoda 1
Jeśli znasz liczbę sekund przed lub po dacie odniesienia 2001, możesz z tego skorzystać.
Metoda 2
Oczywiście łatwiej byłoby użyć takich rzeczy jak lata, miesiące, dni i godziny (zamiast względnych sekund), aby utworzyć plik
Date
. W tym celu możesz użyć,DateComponents
aby określić składniki, a następnieCalendar
utworzyć datę. ToCalendar
dajeDate
kontekst. W przeciwnym razie skąd miałoby wiedzieć, w jakiej strefie czasowej lub kalendarzu ma to wyrazić?Inne skróty stref czasowych można znaleźć tutaj . Jeśli pozostawisz to pole puste, domyślnie używana jest strefa czasowa użytkownika.
Metoda 3
Najbardziej zwięzłym (ale niekoniecznie najlepszym) sposobem może być użycie
DateFormatter
.Te normy techniczne Unicode pokazać inne formaty , że
DateFormatter
obsługuje.Uwagi
Zobacz moją pełną odpowiedź, jak wyświetlić datę i godzinę w czytelnym formacie. Przeczytaj także te doskonałe artykuły:
źródło
Najlepiej jest to zrobić, używając rozszerzenia istniejącej
NSDate
klasy.Poniższe rozszerzenie dodaje nowy inicjator, który utworzy datę w bieżących ustawieniach regionalnych przy użyciu ciągu daty w określonym formacie.
Teraz możesz utworzyć NSDate w Swift, wykonując:
Zauważ, że ta implementacja nie buforuje NSDateFormatter, co możesz chcieć zrobić ze względu na wydajność, jeśli spodziewasz się tworzenia wielu plików
NSDate
w ten sposób.Należy również pamiętać, że ta implementacja po prostu ulegnie awarii, jeśli spróbujesz zainicjować an
NSDate
przez przekazanie ciągu, którego nie można poprawnie przeanalizować. Dzieje się tak z powodu wymuszonego rozpakowania wartości opcjonalnej zwróconej przezdateFromString
. Jeśli chciałbyś zwrócić anil
przy złej analizie, najlepiej byłoby użyć nieudanego inicjatora; ale nie możesz tego zrobić teraz (czerwiec 2015) z powodu ograniczeń w Swift 1.2, więc następnym najlepszym wyborem jest użycie metody fabryki klas.Bardziej rozbudowany przykład, który dotyczy obu problemów, znajduje się tutaj: https://gist.github.com/algal/09b08515460b7bd229fa .
Aktualizacja dla Swift 5
źródło
NSDateFormatter
każdym razem, gdy uzyskuje się dostęp do funkcji. Jak podaje przewodnik po formatowaniu daty , utworzenie programu formatującego datę nie jest tanią operacją . Ponadto klasa jest bezpieczna dla wątków od iOS7, więc można ją bezpiecznie używać dla wszystkichNSDate
rozszerzeń.Swift nie ma własnego typu Date, ale możesz użyć istniejącego
NSDate
typu Cocoa , np .:Które możesz użyć na przykład:
źródło
NSDateFormatter
metodydate(from:)
. Wracanil
. Znalazłem ten problem w dzienniku awarii fabric.io.Oto, jak zrobiłem to w Swift 4.2:
Stosowanie:
źródło
dateComponents
Zgodnie z dokumentacją Apple
Przykład:
źródło
W Swift 3.0 ustawiłeś w ten sposób obiekt daty.
źródło
Osobiście uważam, że powinien to być dostępny inicjalizator:
W przeciwnym razie ciąg o nieprawidłowym formacie zgłosi wyjątek.
źródło
Zgodnie z odpowiedzią @mythz zdecydowałem się opublikować zaktualizowaną wersję jego rozszerzenia przy użyciu
swift3
składni.Nie używam
parse
metody, ale jak ktoś będzie potrzebował, zaktualizuję ten post.źródło
Często mam potrzebę łączenia wartości dat z jednego miejsca z wartościami czasu w innym. Napisałem funkcję pomocniczą, aby to osiągnąć.
źródło
Zgodnie z instrukcją formatowania danych firmy Apple
I chociaż zgadzam się z @Leon, że powinien to być dostępny inicjator, kiedy wprowadzasz dane początkowe, możemy mieć taki, który nie jest dostępny (tak jak jest
UIImage(imageLiteralResourceName:)
).Oto moje podejście:
A teraz ciesz się po prostu dzwoniąc:
źródło