Home > Software engineering >  Convert Int to date formatter followed with timezone
Convert Int to date formatter followed with timezone

Time:12-13

Trying to convert Int to formatted string date with supplied timezone value and formatter to expected result "12/01/2022 09:03:41 PM THA".

//Response Data.

{
      "code": "THA",
      "name": "Thailand Standard Time (THA) (UTC 07)",
      "offset": 25200,
      "utc_offset": "UTC 07",
      "region": "Asia/Phnom_Penh"
}

I have picked Timezone from api response code, Here is what I have implemented.

   var timezoneCode = response.timeZone.code ?? ""

    if let updatedOn = self.dict?["updated_on"]?.intValue{ // i.e., 1669903421000
        let dateValue =  Date(milliseconds: Int64(updatedOn))
        stringDate = dateToStringTimeZone(date: dateValue, dateFormat: "MM/dd/yyyy hh:mm:ss a zzz", timeZone: timezoneCode)
    }

// convert Data To String with Timezone / DateFormate

func dateToStringTimeZone(date: Date, dateFormat: String, timeZone: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = dateFormat
    dateFormatter.locale = Locale.init(identifier: "en_US_POSIX")
    dateFormatter.timeZone = TimeZone.init(abbreviation: timeZone)
    let dateStr = dateFormatter.string(from: date)
    return dateStr
}

// Date Extension

extension Date {
    var millisecondsSince1970: Int64 {
        return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
    }

    init(milliseconds: Int64) {
        self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
    }
}

After Trying it the above code resultant String date

"12/01/2022 07:33:41 PM GMT 5:30"

Can any one guild how to achive the formatted date value as shown below?

"12/01/2022 09:03:41 PM THA"

CodePudding user response:

Replace "zzz" with your wanted timezone code directly in the date format string

"MM/dd/yyyy hh:mm:ss a '\(timezoneCode)'"

You also need to use another init for TimeZone, using the offset property seems to work

let offset = response.timeZone.offset
dateFormatter.timeZone = TimeZone(secondsFromGMT: offset)

CodePudding user response:

You can condense your code into a Codable model since your string is coming as a response.

//Conform to Codable for decoding API
struct TimeZoneResponse: Codable{
    //MARK: Response variables
    let code: String
    let name: String
    let offset: Int
    let utcOffset: String
    let region: String
    //MARK: Custom variables
    ///Returns timezone based on provided variables
    var timeZone: TimeZone?{
        //You only need one
        if let tz = TimeZone(identifier: region){
            return tz
        } else if let tz = TimeZone(secondsFromGMT: offset){
            return tz
        } else if let tz = TimeZone(abbreviation: code){
            return tz
        } else {
            print("timeZone invalid timezone region \(region)")
            return nil
        }
    }
    //Returns a DateFormatter with the avaialble tiime zone and "MM/dd/yyyy hh:mm:ss a" format
    var dateFormatter: DateFormatter? {
        guard let tz = timeZone else{
            print("dateFormatter unavaialble timezone")
            return nil
        }
        
        let f = DateFormatter()
        f.timeZone = tz
        f.dateFormat = "MM/dd/yyyy hh:mm:ss a"
        return f
    }
    //MARK: Functions
    ///returns String with "12/01/2022 09:03:41 PM THA" format
    func getDateString(date: Date) -> String?{
        guard let f = dateFormatter else {
            print("\(#function) :: no available date formatter")
            return nil
        }
        return f.string(from: date)   " \(code)"
    }
    ///returns Date from String with "12/01/2022 09:03:41 PM THA" format
    func getDate(string: String) -> Date?{
        guard let f = dateFormatter else {
            print("\(#function) :: no available date formatter")
            return nil
        }
        return f.date(from: string)
    }
    //MARK: CodingKeys
    enum CodingKeys: String, CodingKey{
        case code
        case name
        case offset
        case utcOffset = "utc_offset"
        case region
    }
}

Then you can decode with JSONDecoder and use the provided function to get the String

do{
    let decoder = JSONDecoder()
    let apiTZ = try decoder.decode(TimeZoneResponse.self, from: sampleInput.data(using: .utf8)!)
    //Decoded object
    print(apiTZ)
    //The String for the provided date
    print(apiTZ.getDateString(date: Date())!)
}catch{
    print(error)
}

You can also extent Date and pass the responses time zone

extension Date{
    func getString(_ tz: TimeZoneResponse) -> String?{
        tz.getDateString(date: self)
    }
}

Date().getString(timeZoneResponse)
  • Related