Swift tem seu próprio Datetipo. Não há necessidade de usar NSDate.
Criando uma data e hora no Swift
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)//Feb2,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")
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.
Indica que a extensão está fornecendo um inicializador que de fato delega a inicialização para um inicializador designado já existente, que nesse caso é o inicializador NSDate.init (timeInterval:, sinceDate :). Isso está descrito na página 275 do livro The Swift Programming Language.
amigos estão
1
Uma falha que vejo no código acima é recriada 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.
Yevhen Dubinin
@eugenedubinin correct. foi por isso que disse: "essa implementação não armazena em cache o NSDateFormatter, o que você pode querer fazer por motivos de desempenho".
Swift não tem seu próprio tipo de data, mas você deve usar o NSDatetipo de cacau existente , por exemplo:
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
}}
Que você pode usar como:
var date =Date.parse("2014-05-20")var date =Date.from(year:2014, month:05, day:20)
Eu tive que mudar a linha: var date = gregorian? .DateFromComponents (c), mas não entendo o porquê, e a análise de retorno dateFmt.dateFromString também está reclamando. Alguma pista? Ah, eu mudei o tipo de retorno da função de NSDate para NSDate? o que permite compilar. Mas não sei por que ele precisa ser anulável.
O senador
1
O init do TheSCenendar NSCalendar retorna um opcional (?), Portanto, gregoriano é um opcional (?). Acessar uma necessidade opcional de Encadeamento opcional para acessá-lo de forma gregoriana? .DateFromCoomponents é o encadeamento opcional para desembrulhar o valor das opções gregorian (NSCalendar). Mais para encadeamento opcional aqui
iluvatar_GR 4/15/15
NSGregorianCalendar está obsoleto a partir do iOS 8 por isso use NSCalendarIdentifierGregorian vez
Adam cavaleiros
2
@ O Senador reclama que o Swift possui a estrutura Date e esse código redefine Data novamente como classe. Então, você deve fazer algo como: 'extension Date' e 'static func' #
Zaporozhchenko Oleksandr
Uma nota sobre a sequência de análise de volta à Data. Uma cadeia de caracteres "1979/07/01" com "aaaa-MM-dd" para NSDateFormattermétodo date(from:). Retorna nil. Encontrei esse problema no log de falha do fabric.io.
AechoLiu
12
Aqui está como eu fiz isso no 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}}
Uso:
let marsOpportunityLaunchDate =Date.from(year:2003, month:07, day:07)
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:)).
NSDate
como no Objective-C?Respostas:
Swift tem seu próprio
Date
tipo. Não há necessidade de usarNSDate
.Criando uma data e hora no Swift
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: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.
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 usarDateComponents
para especificar os componentes e, em seguida,Calendar
criar a data. OCalendar
dá oDate
contexto. Caso contrário, como saberia em que fuso horário ou calendário expressá-lo?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
.As normas técnicas Unicode mostrar outros formatos que
DateFormatter
suporta.Notas
Veja minha resposta completa sobre como exibir a data e a hora em um formato legível. Leia também estes excelentes artigos:
fonte
É 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.
Agora você pode criar um NSDate a partir do Swift apenas fazendo:
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 pordateFromString
. Se você deseja retornarnil
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 .
Atualização para o Swift 5
fonte
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 asNSDate
extensões.Swift não tem seu próprio tipo de data, mas você deve usar o
NSDate
tipo de cacau existente , por exemplo:Que você pode usar como:
fonte
NSDateFormatter
métododate(from:)
. Retornanil
. Encontrei esse problema no log de falha do fabric.io.Aqui está como eu fiz isso no Swift 4.2:
Uso:
fonte
dateComponents
De acordo com a documentação da Apple
Exemplo:
fonte
No Swift 3.0, você definiu o objeto de data dessa maneira.
fonte
Pessoalmente, acho que deve ser um inicializador disponível:
Caso contrário, uma sequência com um formato inválido gerará uma exceção.
fonte
De acordo com a resposta @mythz, decido postar a versão atualizada de sua extensão usando a
swift3
sintaxe.Eu não uso o
parse
método, mas se alguém precisar, atualizarei esta postagem.fonte
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.
fonte
De acordo com o Guia de formatação de dados da Apple
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:
E agora aproveite simplesmente ligando para:
fonte