web-dev-qa-db-fra.com

Swift - iOS - Dates et heures dans un format différent

Je travaille pour une application écrite en Swift et je veux manipuler les dates et les heures

let timestamp = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .ShortStyle, timeStyle: .ShortStyle)

retour

2/12/15, 11:27 PM

si je veux la date et l'heure dans un format différent, par exemple la date au format européen comme jj/mm/aa et les heures au format 24h sans AM et PM il y a une fonction qui puis-je utiliser ou je dois utiliser N Strings pour réorganiser les différents éléments?

41
GioB
func convertDateFormater(date: String) -> String {   
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    dateFormatter.timeZone = NSTimeZone(name: "UTC")

    guard let date = dateFormatter.dateFromString(date) else {
        assert(false, "no date from string")
        return ""
    }

    dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"
    dateFormatter.timeZone = NSTimeZone(name: "UTC")
    let timeStamp = dateFormatter.stringFromDate(date)

    return timeStamp
}

Modifier pour Swift 4

func convertDateFormatter(date: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"//this your string date format
    dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
    dateFormatter.locale = Locale(identifier: "your_loc_id")
    let convertedDate = dateFormatter.date(from: date)

    guard dateFormatter.date(from: date) != nil else {
        assert(false, "no date from string")
        return ""
    } 

    dateFormatter.dateFormat = "yyyy MMM HH:mm EEEE"///this is what you want to convert format
    dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
    let timeStamp = dateFormatter.string(from: convertedDate!)

    return timeStamp
}
59
idris yıldız

Comme déjà mentionné, vous devez utiliser DateFormatter pour formater vos objets Date. La façon la plus simple de le faire est de créer une extension Date de propriété calculée en lecture seule.


Propriétés calculées en lecture seule

Une propriété calculée avec un getter mais aucun setter est connue comme une propriété calculée en lecture seule. Une propriété calculée en lecture seule renvoie toujours une valeur et est accessible via la syntaxe à points, mais ne peut pas être définie sur une valeur différente.

Remarque:

Vous devez déclarer les propriétés calculées, y compris les propriétés calculées en lecture seule, en tant que propriétés variables avec le mot clé var, car leur valeur n'est pas fixe. Le mot clé let n'est utilisé que pour les propriétés constantes, pour indiquer que leurs valeurs ne peuvent pas être modifiées une fois définies dans le cadre de l'initialisation de l'instance.

Vous pouvez simplifier la déclaration d'une propriété calculée en lecture seule en supprimant le mot clé get et ses accolades:


extension Formatter {
    static let date = DateFormatter()
}

extension Date {
    var europeanFormattedEn_US : String {
        Formatter.date.calendar = Calendar(identifier: .iso8601)
        Formatter.date.locale   = Locale(identifier: "en_US_POSIX")
        Formatter.date.timeZone = .current
        Formatter.date.dateFormat = "dd/M/yyyy, H:mm"
        return Formatter.date.string(from: self)
    }
}

Pour le reconvertir, vous pouvez créer une autre propriété calculée en lecture seule mais en tant qu'extension de chaîne:

 extension String {
    var date: Date? {
        return Formatter.date.date(from: self)
    }
    func dateFormatted(with dateFormat: String = "dd/M/yyyy, H:mm", calendar: Calendar = Calendar(identifier: .iso8601), defaultDate: Date? = nil, locale: Locale = Locale(identifier: "en_US_POSIX"), timeZone: TimeZone = .current) -> Date? {
        Formatter.date.calendar = calendar
        Formatter.date.defaultDate = defaultDate ?? calendar.date(bySettingHour: 12, minute: 0, second: 0, of: Date())
        Formatter.date.locale = locale
        Formatter.date.timeZone = timeZone
        Formatter.date.dateFormat = dateFormat
        return Formatter.date.date(from: self)
    }
}

Usage:

let dateFormatted = Date().europeanFormattedEn_US         //"29/9/2018, 16:16"
if let date = dateFormatted.date {
    print(date.description(with:.current)) // Saturday, September 29, 2018 at 4:16:00 PM Brasilia Standard Time\n"\
    date.europeanFormattedEn_US                         // "29/9/2018, 16:27"
}

let dateString = "14/7/2016"
if let date = dateString.toDateFormatted(with: "dd/M/yyyy") {
    print(date.description(with: .current))
 // Thursday, July 14, 2016 at 12:00:00 PM Brasilia Standard Time\n"
}
30
Leo Dabus

Comme l'a déclaré Zaph, vous devez suivre la documentation. Certes, ce n'est peut-être pas le plus simple par rapport à d'autres références de classe. La réponse courte est que vous utilisez Table des symboles de champ de date pour déterminer le format que vous souhaitez. Une fois que vous faites:

let dateFormatter = NSDateFormatter()
//the "M/d/yy, H:mm" is put together from the Symbol Table
dateFormatter.dateFormat = "M/d/yy, H:mm"
dateFormatter.stringFromDate(NSDate())

Vous devrez également pouvoir utiliser la table si vous devez convertir une date qui est une chaîne en NSDate.

let dateAsString = "02/12/15, 16:48"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "M/d/yyyy, H:mm"
let date = dateFormatter.dateFromString(dateAsString)
12
Jeremy Pope

Date/heure actuelle à la chaîne formatée:

let currentDate = Date()
let dateFormatter = DateFormatter()

dateFormatter.dateFormat = "dd/MM/yyyy hh:mm:ss a"
let convertedDate: String = dateFormatter.string(from: currentDate) //08/10/2016 01:42:22 AM

Plus de formats Datetime

10
Atif Mahmood

Vous avez déjà trouvé NSDateFormatter, il suffit de lire la documentation à ce sujet.

Référence de classe NSDateFormatter

Pour les définitions de caractères de format
Voir: Dates et heures de formatage IC
Aussi: Table de symboles de champ de date. .

4
zaph

Si vous souhaitez utiliser une programmation orientée protocole (Swift 3)

1) Créer un protocole dateable

protocol Dateable {
    func userFriendlyFullDate() -> String
    func userFriendlyHours() -> String
}

2) Étendre la classe Date et implémenter le protocole Dateable

extension Date: Dateable {
    var  formatter: DateFormatter { return DateFormatter() }

    /** Return a user friendly hour */
    func userFriendlyFullDate() -> String {
        // Customize a date formatter
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        formatter.timeZone = TimeZone(abbreviation: "UTC")

        return formatter.string(from: self)
    }

    /** Return a user friendly hour */
    func userFriendlyHours() -> String {
        // Customize a date formatter
        formatter.dateFormat = "HH:mm"
        formatter.timeZone = TimeZone(abbreviation: "UTC")

        return formatter.string(from: self)
    }

    // You can add many cases you need like string to date formatter

}

) Utilisez-le

let currentDate: Date = Date()
let stringDate: String = currentDate.userFriendlyHours()
// Print 15:16
4
Ludovic

J'ai utilisé une approche similaire à @ iod07, mais comme extension. J'ai également ajouté quelques explications dans les commentaires pour comprendre comment cela fonctionne.

Fondamentalement, ajoutez simplement cela en haut ou en bas de votre contrôleur de vue.

extension NSString {

class func convertFormatOfDate(date: String, originalFormat: String, destinationFormat: String) -> String! {

    // Orginal format :
    let dateOriginalFormat = NSDateFormatter()
    dateOriginalFormat.dateFormat = originalFormat      // in the example it'll take "yy MM dd" (from our call)

    // Destination format :
    let dateDestinationFormat = NSDateFormatter()
    dateDestinationFormat.dateFormat = destinationFormat // in the example it'll take "EEEE dd MMMM yyyy" (from our call)

    // Convert current String Date to NSDate
    let dateFromString = dateOriginalFormat.dateFromString(date)

    // Convert new NSDate created above to String with the good format
    let dateFormated = dateDestinationFormat.stringFromDate(dateFromString!)

    return dateFormated

}
}

Exemple

Imaginons que vous souhaitiez convertir "16 05 05" à "Thursday 05 May 2016" et votre date est déclarée comme suit let date = "16 06 05"

Appelez-le simplement avec:

let newDate = NSString.convertFormatOfDate(date, originalFormat: "yy MM dd", destinationFormat: "EEEE dd MMMM yyyy")

J'espère que ça aide !

3
tsnkff

Swift 3:

//This gives month as three letters (Jun, Dec, etc)
let justMonth = DateFormatter()
justMonth.dateFormat = "MMM"
myFirstLabel.text = justMonth.string(from: myDate)

//This gives the day of month, with no preceding 0s (6,14,29)
let justDay = DateFormatter()
justDay.dateFormat = "d"
mySecondLabel.text = justDay.string(from: myDate)

//This gives year as two digits, preceded by an apostrophe ('09, '16, etc)
let justYear = DateFormatter()
justYear.dateFormat = "yy"
myThirdLabel.text = "'\(justYear.string(from: lastCompDate))"

Pour plus de formats, consultez cette lien vers une table codingExplorer avec tous les formats disponibles. Chaque composant de date a plusieurs options, par exemple:

An:

  • "y" - 2016 (les premières dates comme l'année 1 seraient: "1")
  • "aa" - 16 (année 1: "01"
  • "aaaa" - 2016 (année 1: "001")
  • "aaaa" - 2016 (année 1: "0001")

Presque tous les composants ont 2 à 4 options, en utilisant la première lettre pour exprimer le format (le jour est "d", l'heure est "h", etc.). Cependant, le mois est un "M" majuscule, car le "m" minuscule est réservé à la minute. Il existe cependant d'autres exceptions, alors consultez le lien!

2
Dave G

Voici une solution qui fonctionne avec Xcode 10.1 (23 février 2019):

func getCurrentDateTime() {

    let now = Date()
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "fr_FR")
    formatter.dateFormat = "EEEE dd MMMM YYYY"
    labelDate.text = formatter.string(from: now)
    labelDate.font = UIFont(name: "HelveticaNeue-Bold", size: 12)
    labelDate.textColor = UIColor.lightGray

    let text = formatter.string(from: now)
    labelDate.text = text.uppercased()
}

Le label "Accueil" n'est pas lié au code.

2
Benjamin Tourin

iOS 8+

Il est lourd et difficile à préciser locale explicitly. Vous ne savez jamais où votre application sera utilisée. Je pense donc qu'il vaut mieux définir locale sur Calender.current.locale et utilisez la méthode DateFormatter de setLocalizedDateFormatFromTemplate.

setLocalizedDateFormatFromTemplate (_ :)

Définit le format de date à partir d'un modèle en utilisant les paramètres régionaux spécifiés pour le récepteur. - developer.Apple.com

extension Date {
    func convertToLocaleDate(template: String) -> String {
        let dateFormatter = DateFormatter()

        let calender = Calendar.current

        dateFormatter.timeZone = calender.timeZone
        dateFormatter.locale = calender.locale
        dateFormatter.setLocalizedDateFormatFromTemplate(template)

        return dateFormatter.string(from: self)
    }
}



Date().convertToLocaleDate(template: "dd MMMM YYYY")
0
mahan
let usDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "en-US"))
            //usDateFormat now contains an optional string "MM/dd/yyyy"

let gbDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "en-GB"))
            //gbDateFormat now contains an optional string "dd/MM/yyyy"

let geDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "de-DE"))
            //geDateFormat now contains an optional string "dd.MM.yyyy"

Vous pouvez l'utiliser de la manière suivante pour obtenir le format actuel de l'appareil:

let currentDateFormat = DateFormatter.dateFormat(fromTemplate: "MMddyyyy", options: 0, locale: Locale.current)
0
mswyss
extension String {

    func convertDatetring_TopreferredFormat(currentFormat: String, toFormat : String) ->  String {
        let dateFormator = DateFormatter()
        dateFormator.dateFormat = currentFormat
        let resultDate = dateFormator.date(from: self)
        dateFormator.dateFormat = toFormat
        return dateFormator.string(from: resultDate!)
    }

}

Appelez à partir de votre fichier de contrôleur de vue comme ci-dessous.

"your_date_string".convertDatetring_TopreferredFormat(currentFormat: "yyyy-MM-dd HH:mm:ss.s", toFormat: "dd-MMM-yyyy h:mm a")
0
Sunil aruru
let dateString = "1970-01-01T13:30:00.000Z"
let formatter = DateFormatter()

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let date = formatter.date(from: String(dateString.dropLast(5)))!
formatter.dateFormat = "hh.mma"
print(formatter.string(from: date))

si vous remarquez que j'ai mis .dateFormat = "hh.mma"par ceci, vous n'aurez que du temps. Résultat:01.30PM

0
Ahsan

Il s'agit peut-être d'un ancien fil de discussion, mais je travaillais récemment sur des heures et j'étais coincé avec un problème similaire, j'ai donc fini par créer un de mes utilitaires qui ressemble à ceci,

Cet utilitaire prendrait une date de chaîne et retournerait un objet date facultatif

        func toDate(dateFormat: DateFormatType) -> Date? {
        let formatter = DateFormatter()
        formatter.timeZone = NSTimeZone(name: "UTC") as TimeZone?
        formatter.dateFormat = dateFormat.rawValue
        let temp = formatter.date(from: self)
        return formatter.date(from: self)
        }

l'énumération DateFormatType ressemble à ceci

        enum DateFormatType : String {
        case type1 = "yyyy-MM-dd - HH:mm:ss"
        case type2 = "dd/MM/yyyy"
        case type3 = "yyyy/MM/dd"
    }

Une chose importante que je voudrais mentionner ici est la ligne

formatter.timeZone = NSTimeZone(name: "UTC") as TimeZone?

il est très important que vous ajoutiez cette ligne car sans cela, le DateFormatter utiliserait ses conversions par défaut pour convertir la date et vous pourriez finir par voir des dates différentes si vous travaillez avec une équipe distante et rencontrez toutes sortes de problèmes avec données en fonction des dates.

J'espère que cela t'aides

0
NSDumb