80 votes

iOS Swift - Obtention de l'heure et de la date actuelles

Je suis en train de faire une fréquentation de l'app et je suis vraiment confus au sujet de la date et de l'heure dans iOS et Firebase.

J'utilise date Clé, c'est la structure de mon Firebase base de données.

--Employees
  --Unique_ID
     --Details
          Name: John
     --Attendance
          --dateToday
              Timein: 8:00 AM
              Timeout: 5:00 PM
              BreakStart: 12:00 PM
              BreakFinish: 1:00 PM

C'est mon code pour obtenir la date timestamp j'ai utilisé comme Clé

 override func viewDidLoad() {
     super.viewDidLoad()

     let now = NSDate()
     let nowTimeStamp = self.getCurrentTimeStampWOMiliseconds(dateToConvert: now)

     // I save this dateToday as Key in Firebase
     dateToday = nowTimeStamp
}


func getCurrentTimeStampWOMiliseconds(dateToConvert: NSDate) -> String {
    let objDateformat: DateFormatter = DateFormatter()
    objDateformat.dateFormat = "yyyy-MM-dd"
    let strTime: String = objDateformat.string(from: dateToConvert as Date)
    let objUTCDate: NSDate = objDateformat.date(from: strTime)! as NSDate
    let milliseconds: Int64 = Int64(objUTCDate.timeIntervalSince1970)
    let strTimeStamp: String = "\(milliseconds)"
    return strTimeStamp
}

Mais quand je la convertir à date je obtenir 2017-09-22 16:00:00 +0000, ce qui est faux, car il est 23 septembre, dans ma position.

Quel est le code à utiliser de sorte que je peux obtenir la date du jour heure et le time timestamp?

138voto

Satish Babariya Points 1708

Pour enregistrer l'heure actuelle dans la base de données firebase, j'utilise la conversation Unic Epoch:

 let timestamp = NSDate().timeIntervalSince1970
 

et pour le décodage de l’époque Unix jusqu’à la date ().

 let myTimeInterval = TimeInterval(timestamp)
let time = NSDate(timeIntervalSince1970: TimeInterval(myTimeInterval))
 

54voto

lenooh Points 507

Si vous voulez juste le timestamp unix, créez une extension:

 extension Date {
    func currentTimeMillis() -> Int64 {
        return Int64(self.timeIntervalSince1970 * 1000)
    }
}
 

Ensuite, vous pouvez l'utiliser comme dans d'autres langages de programmation:

 let timestamp = Date().currentTimeMillis()
 

25voto

Alex Points 915

Je souhaite tout d'abord vous conseillons de stocker votre horodatage comme un NSNumber dans votre Firebase Base de données, au lieu de les stocker en tant que String.

Une autre chose à mentionner ici est que si vous voulez manipuler des dates avec Swift, vous feriez mieux d'utiliser Date au lieu de NSDate, sauf si vous êtes en interaction avec certains Obj-C code dans votre application.

Vous pouvez bien sûr utiliser les deux, mais les états de Documentation:

Date de ponts à la NSDate classe. Vous pouvez les utiliser de façon interchangeable dans code qui interagit avec Objective-C Api.

Maintenant pour répondre à votre question, je pense que le problème ici c'est à cause de l'horaire.

Par exemple, si vous print(Date()), pour l'instant, vous obtenez:

2017-09-23 06:59:34 +0000

C'est le Temps Moyen de Greenwich (GMT).

Donc selon où vous vous trouvez (ou la localisation de vos utilisateurs), vous devez ajuster le fuseau horaire avant (ou après, lorsque vous essayez d'accéder aux données par exemple), le stockage de vos Date:

    let now = Date()

    let formatter = DateFormatter()

    formatter.timeZone = TimeZone.current

    formatter.dateFormat = "yyyy-MM-dd HH:mm"

    let dateString = formatter.string(from: now)

Ensuite, vous avez votre correctement formaté String, reflétant l'heure actuelle à votre emplacement, et vous êtes libre de faire ce que vous voulez avec elle :) (le convertir en Date / NSNumber, ou de les stocker directement en tant que String dans la base de données..)

10voto

Mangi Reddy Points 622

Le moyen simple de créer Current TimeStamp. comme ci-dessous,

 func generateCurrentTimeStamp () -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy_MM_dd_hh_mm_ss"
    return (formatter.string(from: Date()) as NSString) as String
}
 

1voto

bsod Points 3192

Lorsque vous convertissez un horodatage UTC (c'est à dire 2017-11-06 20:15:33 -08:00) en Date() objet dans Swift, Swift remet à zéro le fuseau horaire de GMT (qui est de plus ou moins 0). Pour le calcul d'un intervalle de temps, cela ne pose pas un problème en raison toutefois de nombreuses heures (et quelques minutes, comme il y a un certain nombre de zones qui ne sont pas divisés sur l'heure, mais à l' :45 :30) sont ajoutés ou soustraits de la réinitialisation de la zone sont ajoutés ou soustraits à la date de l'heure (et parfois à la minute) de la valeur, de sorte que le point absolu dans le temps ne change jamais. Cependant, lors de la conversion de cette date, objet en chaîne de caractères, à l'aide de DateFormatter() ou ISO8601DateFormatter(), qui n'est pas sans poser problème, car le fuseau horaire d'origine a été remis à zéro.

Maintenant, je suis favorable à l'aide de RFC3339 (c'est à dire 2017-11-06T20:15:33-08:00), l'internet-format convivial pour les ISO8601 normalisé format de l'heure. Les Chances sont que de la 3e partie de l'API, vous aurez un jour de crochet jusqu'à l'utilisera donc je pense que nous devrions tous être à l'utiliser maintenant. Le format Swift yyyy-MM-dd'T'HH:mm:ssXXXXX. Swift a également un ISO8601DateFormatter() que peut convertir les littéraux de chaîne dans la date objets très simplement:

func getDateFromUTC(RFC3339: String) -> Date? {
    let formatter = ISO8601DateFormatter()
    return formatter.date(from: RFC3339)
}

Et à l'aide de la RFC3339 format rend également l'extraction de la zone de temps très simple:

func getTimeZoneFromUTC(RFC3339: String) -> TimeZone? {
    switch RFC3339.suffix(6) {
    case "+05:45":
        return TimeZone(identifier: "Asia/Kathmandu")
    default:
        return nil
    }
}

Bien sûr, vous devez remplir les 37 autres ou si les fuseaux horaires à l'aide de toutes les méthodes vous conviennent le mieux. Et maintenant, si vous voulez format de chaîne de caractères littérale en quelque chose de plus convivial, vous pouvez combiner les deux méthodes ci-dessus en quelque chose comme ceci:

func getFormattedDateFromUTC(RFC3339: String) -> String? {
    guard let date = getDateFromUTC(RFC3339: RFC3339),
        let timeZone = getTimeZoneFromUTC(RFC3339: RFC3339) else {
            return nil
    }
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mma EEE, MMM d yyyy"
    formatter.amSymbol = "AM"
    formatter.pmSymbol = "PM"
    formatter.timeZone = timeZone // preserve local time zone
    return formatter.string(from: date)
}

Et donc, cette chaîne de caractères "2018-11-06T17:00:00+05:45", qui exprime à 5:00PM quelque part dans Katmandou, permet d'imprimer 5:00PM Tue, Nov 6 2018, l'affichage de l'heure locale, indépendamment de l'endroit où la machine est. Et, bien sûr, si vous ne voulez pas formater à l'aide contextuelle, heure locale, il suffit de ne pas définir le fuseau horaire de la propriété.

Comme une note de côté, en réponse à certaines des suggestions dans ce fil, je vous recommande de stocker les dates comme des chaînes de caractères dans Firebase. Stocke les dates sous la forme de chaînes, en particulier à l'aide d'un format comme RFC3339, met ces données à la plate-forme agnostique. Vous pouvez changer la base sur n'importe quelle plate-forme dans le cadre et vous n'auriez pas besoin de changer toute logique, car les chaînes sont toujours des chaînes de caractères. Et RFC3339 est l'un profil qui, en gros, le cadre vaut son sel reconnaît.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X