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)