Как вы создаете объект даты из даты в Swift Xcode.
Например, в JavaScript вы бы сделали:
var day = new Date('2014-05-20');
Как вы создаете объект даты из даты в Swift Xcode.
Например, в JavaScript вы бы сделали:
var day = new Date('2014-05-20');
Ответы:
Swift имеет свой Dateтип. Не нужно использовать NSDate.
В Swift даты и время хранятся в 64-битном числе с плавающей запятой, которое измеряет количество секунд с базовой даты 1 января 2001 года в 00:00:00 UTC . Это выражено в Dateструктуре . Следующее даст вам текущую дату и время:
let currentDateTime = Date()
Для создания других дат-времени вы можете использовать один из следующих методов.
Способ 1
Если вам известно количество секунд до или после контрольной даты 2001 года, вы можете использовать ее.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Способ 2
Конечно, было бы проще использовать такие вещи, как годы, месяцы, дни и часы (а не относительные секунды) для создания Date. Для этого вы можете использовать, DateComponentsчтобы указать компоненты, а затем Calendarсоздать дату. Это Calendarдает Dateконтекст. Иначе как бы он узнал, в каком часовом поясе или календаре это выражать?
// 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)
Другие сокращения часовых поясов можно найти здесь . Если вы оставите это поле пустым, по умолчанию будет использоваться часовой пояс пользователя.
Способ 3
Наиболее кратким способом (но не обязательно лучшим) может быть использование DateFormatter.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
В технических стандартах Unicode показать другие форматы , что DateFormatterподставки.
Смотрите мой полный ответ о том, как отображать дату и время в удобочитаемом формате. Также прочитайте эти отличные статьи:
Лучше всего это сделать с помощью расширения существующего NSDateкласса.
Следующее расширение добавляет новый инициализатор, который будет создавать дату в текущей локали, используя строку даты в указанном вами формате.
extension NSDate
{
convenience
init(dateString:String) {
let dateStringFormatter = NSDateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
let d = dateStringFormatter.dateFromString(dateString)!
self.init(timeInterval:0, sinceDate:d)
}
}
Теперь вы можете создать NSDate из Swift, просто выполнив:
NSDate(dateString:"2014-06-06")
Обратите внимание, что эта реализация не кэширует NSDateFormatter, что может потребоваться из соображений производительности, если вы собираетесь создавать множество NSDates таким способом.
Также обратите внимание, что эта реализация просто потерпит крах, если вы попытаетесь инициализировать NSDate, передав строку, которая не может быть проанализирована правильно. Это связано с принудительной разверткой необязательного значения, возвращаемого функцией dateFromString. Если вы хотите вернуть a nilпри плохом разборе, в идеале вы должны использовать неисправный инициализатор; но вы не можете сделать это сейчас (июнь 2015 г.) из-за ограничений в Swift 1.2, поэтому следующий ваш лучший выбор - использовать метод фабрики классов.
Более сложный пример, который решает обе проблемы, находится здесь: https://gist.github.com/algal/09b08515460b7bd229fa .
extension Date {
init(_ dateString:String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
let date = dateStringFormatter.date(from: dateString)!
self.init(timeInterval:0, since:date)
}
}
NSDateFormatterкаждом доступе к функции. Как говорится в Руководстве по форматированию даты Создание средства форматирования даты не является дешевой операцией . Кроме того, этот класс является поточно-ориентированным, начиная с iOS7, поэтому его можно безопасно использовать для всех NSDateрасширений.
У Swift нет собственного типа Date, но вы должны использовать существующий NSDateтип Cocoa , например:
class Date {
class func 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
}
class func 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
}
}
Который вы можете использовать как:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatterметода date(from:). Это возвращается nil. Я нашел эту проблему в журнале сбоев fabric.io.
Вот как я это сделал в Swift 4.2:
extension Date {
/// Create a date from specified parameters
///
/// - Parameters:
/// - year: The desired year
/// - month: The desired month
/// - day: The desired day
/// - Returns: A `Date` object
static func 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
}
}
Использование:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
Согласно документации Apple
Пример :
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
В Swift 3.0 вы установили объект даты для этого способа.
extension Date
{
init(dateString:String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
let d = dateStringFormatter.date(from: dateString)!
self(timeInterval:0, since:d)
}
}
Лично я думаю, что это должен быть неудачный инициализатор:
extension Date {
init?(dateString: String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
if let d = dateStringFormatter.date(from: dateString) {
self.init(timeInterval: 0, since: d)
} else {
return nil
}
}
}
В противном случае строка с неверным форматом вызовет исключение.
Согласно ответу @mythz, я решил опубликовать обновленную версию его расширения с использованием swift3синтаксиса.
extension Date {
static func from(_ year: Int, _ month: Int, _ day: Int) -> Date?
{
let gregorianCalendar = Calendar(identifier: .gregorian)
let dateComponents = DateComponents(calendar: gregorianCalendar, year: year, month: month, day: day)
return gregorianCalendar.date(from: dateComponents)
}
}
Я не использую parseметод, но если кому-то понадобится, я обновлю этот пост.
Мне часто нужно комбинировать значения даты из одного места со значениями времени для другого. Я написал вспомогательную функцию для достижения этой цели.
let startDateTimeComponents = NSDateComponents()
startDateTimeComponents.year = NSCalendar.currentCalendar().components(NSCalendarUnit.Year, fromDate: date).year
startDateTimeComponents.month = NSCalendar.currentCalendar().components(NSCalendarUnit.Month, fromDate: date).month
startDateTimeComponents.day = NSCalendar.currentCalendar().components(NSCalendarUnit.Day, fromDate: date).day
startDateTimeComponents.hour = NSCalendar.currentCalendar().components(NSCalendarUnit.Hour, fromDate: time).hour
startDateTimeComponents.minute = NSCalendar.currentCalendar().components(NSCalendarUnit.Minute, fromDate: time).minute
let startDateCalendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
combinedDateTime = startDateCalendar!.dateFromComponents(startDateTimeComponents)!
Согласно руководству по форматированию данных Apple
Создание средства форматирования даты - не дешевая операция. Если вы, вероятно, будете часто использовать средство форматирования, обычно более эффективно кэшировать один экземпляр, чем создавать и распоряжаться несколькими экземплярами. Одним из подходов является использование статической переменной
И хотя я согласен с @Leon, что это должен быть неудачный инициализатор, когда вы вводите начальные данные, у нас может быть тот, который не является неисправным (как и есть UIImage(imageLiteralResourceName:)).
Итак, вот мой подход:
extension DateFormatter {
static let yyyyMMdd: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
extension Date {
init?(yyyyMMdd: String) {
guard let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd) else { return nil }
self.init(timeInterval: 0, since: date)
}
init(dateLiteralString yyyyMMdd: String) {
let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd)!
self.init(timeInterval: 0, since: date)
}
}
А теперь наслаждайтесь простым звонком:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDateже, как в Objective-C?