Como você cria um objeto de data a partir de uma data no xcode rápido.
por exemplo, em javascript, você faria:
var day = new Date('2014-05-20');
Como você cria um objeto de data a partir de uma data no xcode rápido.
por exemplo, em javascript, você faria:
var day = new Date('2014-05-20');
Respostas:
Swift tem seu próprio Datetipo. Não há necessidade de usar NSDate.
No Swift, as datas e horas são armazenadas em um número de ponto flutuante de 64 bits, medindo o número de segundos desde a data de referência de 1 de janeiro de 2001 às 00:00:00 UTC . Isso é expresso na Dateestrutura . O seguinte forneceria a data e hora atuais:
let currentDateTime = Date()
Para criar outras datas e horários, você pode usar um dos seguintes métodos.
Método 1
Se você souber o número de segundos antes ou depois da data de referência de 2001, poderá usá-lo.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Método 2
Obviamente, seria mais fácil usar coisas como anos, meses, dias e horas (em vez de segundos relativos) para criar um Date. Para isso, você pode usar DateComponentspara especificar os componentes e, em seguida, Calendarcriar a data. O Calendardá o Datecontexto. Caso contrário, como saberia em que fuso horário ou calendário expressá-lo?
// 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)
Outras abreviações de fuso horário podem ser encontradas aqui . Se você deixar em branco, o padrão é usar o fuso horário do usuário.
Método 3
A maneira mais sucinta (mas não necessariamente a melhor) poderia ser usar DateFormatter.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
As normas técnicas Unicode mostrar outros formatos que DateFormattersuporta.
Veja minha resposta completa sobre como exibir a data e a hora em um formato legível. Leia também estes excelentes artigos:
É melhor fazer isso usando uma extensão para a NSDateclasse existente .
A extensão a seguir adiciona um novo inicializador que criará uma data no local atual usando a sequência de datas no formato especificado.
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)
}
}
Agora você pode criar um NSDate a partir do Swift apenas fazendo:
NSDate(dateString:"2014-06-06")
Observe que esta implementação não armazena em cache o NSDateFormatter, o que você pode querer fazer por motivos de desempenho, se espera criar muitos NSDates dessa maneira.
Observe também que essa implementação simplesmente trava se você tentar inicializar um NSDatepassando uma string que não pode ser analisada corretamente. Isso ocorre devido ao desempacotamento forçado do valor opcional retornado por dateFromString. Se você deseja retornar niluma análise ruim, o ideal seria usar um inicializador com falha; mas você não pode fazer isso agora (junho de 2015), devido a uma limitação no Swift 1.2, então a sua melhor opção é usar um método de fábrica de classe.
Um exemplo mais elaborado, que aborda os dois problemas, está aqui: 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)
}
}
NSDateFormattercada vez que a função é acessada. Como indica o Guia de formatação de data , criar um formatador de data não é uma operação barata . Além disso, a classe é segura para threads desde o iOS7, para que você possa usá-la com segurança em todas as NSDateextensões.
Swift não tem seu próprio tipo de data, mas você deve usar o NSDatetipo de cacau existente , por exemplo:
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
}
}
Que você pode usar como:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormattermétodo date(from:). Retorna nil. Encontrei esse problema no log de falha do fabric.io.
Aqui está como eu fiz isso no 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
}
}
Uso:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
De acordo com a documentação da Apple
Exemplo:
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
No Swift 3.0, você definiu o objeto de data dessa maneira.
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)
}
}
Pessoalmente, acho que deve ser um inicializador disponível:
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
}
}
}
Caso contrário, uma sequência com um formato inválido gerará uma exceção.
De acordo com a resposta @mythz, decido postar a versão atualizada de sua extensão usando a swift3sintaxe.
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)
}
}
Eu não uso o parsemétodo, mas se alguém precisar, atualizarei esta postagem.
Muitas vezes, preciso combinar valores de data de um local com valores de hora para outro. Eu escrevi uma função auxiliar para fazer isso.
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)!
De acordo com o Guia de formatação de dados da Apple
Criar um formatador de datas não é uma operação barata. Se é provável que você use um formatador com frequência, geralmente é mais eficiente armazenar em cache uma única instância do que criar e descartar várias instâncias. Uma abordagem é usar uma variável estática
E, embora eu concorde com o @Leon que este deve ser um inicializador disponível, quando você insere dados iniciais, poderíamos ter um que não esteja disponível (exatamente como existe UIImage(imageLiteralResourceName:)).
Então, aqui está a minha abordagem:
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)
}
}
E agora aproveite simplesmente ligando para:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDatecomo no Objective-C?