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.