web-dev-qa-db-fra.com

Swift 3.0: Convertissez l'heure UTC du serveur en heure locale et inversement

Je veux convertir l'heure UTC du serveur en heure locale et vice-versa ... Voici mon code.

var isTimeFromServer = true
var time:String!
var period:String!
let timeString = "6:59 AM" //Current UTC time

if isTimeFromServer {

    let index = timeString.index(timeString.startIndex, offsetBy: 5)
    let twelve = timeString.substring(to: index)

    var dateString:String!

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "H:mm"
    let date12 = dateFormatter.date(from: twelve)!

    dateFormatter.dateFormat = "h:mm a"
    let date22 = dateFormatter.string(from: date12)

    //print(date22)
    dateString = date22
    //print("dateString=\(dateString)")

    time = dateString.components(separatedBy: " ")[0]
    period = dateString.components(separatedBy: " ")[1]

}
else {
    time = timeString.components(separatedBy: " ")[0]
    period = timeString.components(separatedBy: " ")[1]
}

var hour = Int(time.components(separatedBy: ":")[0])

hour = period == "AM" ? hour : hour! + 12
let minute = Int(time.components(separatedBy: ":")[1])
let calender = NSCalendar.current
var datecomponent = DateComponents()
datecomponent.calendar = calender
datecomponent.hour = hour
datecomponent.minute = minute

if !isTimeFromServer {
    // local to UTC
    datecomponent.timeZone = TimeZone.current
}
else {
    datecomponent.timeZone = TimeZone(abbreviation: "UTC")
}

let date = datecomponent.date
let dateFormatter = DateFormatter()

if !isTimeFromServer {
    dateFormatter.dateFormat = "H:mm"
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.string(from: date!)
}
else {
    //UTC to local
    dateFormatter.dateFormat = "h:mm a"
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.string(from: date!)
}

Je reçois l'heure locale 

o/p: "12h52"

Mais le décalage entre l'heure locale et l'heure de sortie est de 23 minutes.

22
NiravS

Je ne sais pas ce qui ne va pas avec votre code.
Mais il semble y avoir trop de choses inutiles, comme si vous établissiez un calendrier, récupérant des éléments dans string ..__ Voici ma petite version de UTCToLocal et de la fonction localToUTC. 
Mais pour cela, vous devez passer une chaîne dans un format spécifique. Parce que j'ai forcément déballé des objets de date. Mais vous pouvez utiliser certaines conditions de garde pour éviter le crash de votre application.

func localToUTC(date:String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a"
    dateFormatter.calendar = NSCalendar.current
    dateFormatter.timeZone = TimeZone.current

    let dt = dateFormatter.date(from: date)
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "H:mm:ss"

    return dateFormatter.string(from: dt!)
}

func UTCToLocal(date:String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "H:mm:ss"
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")

    let dt = dateFormatter.date(from: date)
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.dateFormat = "h:mm a"

    return dateFormatter.string(from: dt!)
}

et appelez ces fonctions comme ci-dessous.

print(UTCToLocal(date: "13:07:00"))
print(localToUTC(date: "06:40 PM"))

J'espère que ceci vous aidera.
Bonne codage !!

57
Mrugesh Tank

La réponse de Mrugesh est parfaite, mais si quelqu'un doit utiliser ses propres formats, ou dans un format différent, je l'ai généralisé afin que vous puissiez donner un format différent ou identique dans les deux paramètres.

func localToUTC(date:String, fromFormat: String, toFormat: String) -> String {

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = fromFormat
    dateFormatter.calendar = NSCalendar.current
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.date
    let dt = dateFormatter.date(from: date)
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = toFormat

    return dateFormatter.string(from: dt!)
}

func UTCToLocal(date:String, fromFormat: String, toFormat: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = fromFormat
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")

    let dt = dateFormatter.date(from: date)
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.dateFormat = toFormat

return dateFormatter.string(from: dt!)
}

let localDateAsString = UTCToLocal(date: dateAsString!, fromFormat: "hh:mm a, dd MMM yyyy", toFormat: "hh:mm a, dd MMM yyyy")

Vous pouvez l'utiliser comme ci-dessus. J'espère que ça aide.

15
Hardik

Avec l'aide de Mrugesh Tank Answer, 

J'ai mis à jour sa réponse et créer les extensions pour la date. Vous pouvez ainsi accéder facilement aux fonctions depuis n'importe où, à partir de ViewController ou de la classe de cellule.

extension String {

  //MARK:- Convert UTC To Local Date by passing date formats value
  func UTCToLocal(incomingFormat: String, outGoingFormat: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = incomingFormat
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")

    let dt = dateFormatter.date(from: self)
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.dateFormat = outGoingFormat

    return dateFormatter.string(from: dt ?? Date())
  }

  //MARK:- Convert Local To UTC Date by passing date formats value
  func localToUTC(incomingFormat: String, outGoingFormat: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = incomingFormat
    dateFormatter.calendar = NSCalendar.current
    dateFormatter.timeZone = TimeZone.current

    let dt = dateFormatter.date(from: self)
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = outGoingFormat

    return dateFormatter.string(from: dt ?? Date())
  }
}

Exemple d'utilisation: -

Note:- eventStartDate is the string which you have to converted in your format like this:- "2018-07-11T16:22:00.000Z" 

let finalDate = eventStartDate.UTCToLocal(incomingFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZ", outGoingFormat: "MMM d, yyyy h:mm a")
5
Mandeep Singh

Essayez-le:

func convertUTCToLocal(timeString: String) -> String? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a"

    dateFormatter.timeZone = TimeZone.init(abbreviation: "UTC")
    let timeUTC = dateFormatter.date(from: timeString)

    if timeUTC != nil {
        dateFormatter.timeZone = NSTimeZone.local

        let localTime = dateFormatter.string(from: timeUTC!)
        return localTime
    }

    return nil
}



func convertLocalToUTC(localTime: String) -> String? {

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a"
    dateFormatter.timeZone = NSTimeZone.local
    let timeLocal = dateFormatter.date(from: localTime)

    if timeLocal != nil {
        dateFormatter.timeZone = TimeZone.init(abbreviation: "UTC")

        let timeUTC = dateFormatter.string(from: timeLocal!)
        return timeUTC
    }
    return nil
}


    var isTimeFromServer = true
    var time:String!
    var period:String!
    let timeString = "6:59 AM" //Current UTC time


    if isTimeFromServer {
        print(convertUTCToLocal(timeString: timeString))
    } else {
        print(convertLocalToUTC(localTime: timeString))
    }
1
javimuu

Pour tous ceux qui utilisent des objets TimeZone ... Je vous conseillerais de créer votre TimeZone à partir d’un identifiant plutôt que d’une abréviation lorsque vous en avez la possibilité.

Cela évite les erreurs causées par l'heure d'été.

Pour illustrer mon propos, prenons un exemple . Vous pouvez instancier comme ceci let timeZone = TimeZone(identifier: "Europe/Paris") Ou comme cela let timeZone = TimeZone(abbreviation: "CEST") ou "UTC +2: 00"

Mais c’est le fuseau horaire pour l’étéCESTsignifie Heure d’été de l’Europe centrale Nous avonsCETsens Heure de l’Europe centrale pour l’hiver qui est "UTC + 1:00 "

Vous pouvez gérer l'heure d'été par vous-même avec Date.isDaylightSavingsTime, mais cela signifie plus de code et vous ne contrôlez pas d'où vient votre heure d'été. "indique si le récepteur utilise actuellement l'heure d'été" dans le document officiel

Tout est c'est-à-dire à privilégier TimeZone (identifiant: ...)

0
Bertrand Villain