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 Date
tipo. 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 Date
estrutura . 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 DateComponents
para especificar os componentes e, em seguida, Calendar
criar a data. O Calendar
dá o Date
contexto. 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 DateFormatter
suporta.
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 NSDate
classe 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 NSDate
s dessa maneira.
Observe também que essa implementação simplesmente trava se você tentar inicializar um NSDate
passando 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 nil
uma 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)
}
}
NSDateFormatter
cada 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 NSDate
extensões.
Swift não tem seu próprio tipo de data, mas você deve usar o NSDate
tipo 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)
NSDateFormatter
mé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 swift3
sintaxe.
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 parse
mé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 }
NSDate
como no Objective-C?