0

How to convert time line format 24-Hour Time Or 12-Hours Time based on device selection.

"Jan 15, 2021 22:05" or "Jan 15, 2021 10:05 PM"

convert it into date formate "yyyy-MM-dd'T'HH:mm:ssZZZ"

    let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZ"
        formatter.timeZone = TimeZone.current
        return formatter
    } ()

Convert to following date formate "yyyy-MM-dd'T'HH:mm:ssZZZ". //

Duncan C
  • 128,072
  • 22
  • 173
  • 272
KkMIW
  • 1,092
  • 1
  • 17
  • 27
  • @JoakimDanielson I want to product a string object example "2021-01-15T12:21:05-0900" – KkMIW Jan 31 '21 at 17:25
  • Sample Input "Jan 15, 2021 22:05" or "Jan 15, 2021 22:05" then outPut will be "2021-01-15T12:21:05-0900" – KkMIW Jan 31 '21 at 17:54
  • some times user will change from device Setting -> Date&Time -> 24-Hours Time that's why I have given both options – KkMIW Jan 31 '21 at 18:00
  • You can ignore the or condition "Jan 15, 2021 22:05" convert to 2021-01-15T12:21:05-0900" ? – KkMIW Jan 31 '21 at 18:02
  • Does this answer your question? [Date Format in Swift](https://stackoverflow.com/questions/35700281/date-format-in-swift) – Joakim Danielson Jan 31 '21 at 18:07
  • You say '"Jan 15, 2021 22:05" or "Jan 15, 2021 22:05"'. Those two strings are exactly identical. Did you mean to say '"Jan 15, 2021 22:05" or "Jan 15, 2021 10:05PM"'? – Duncan C Jan 31 '21 at 19:05
  • @DuncanC sorry my mistake I updated question “Jan 15, 2021 09:05 PM” – KkMIW Jan 31 '21 at 19:59
  • "22:05" is equivalent to "10:05" PM, not "09:05 PM". See my answer, in any case. – Duncan C Jan 31 '21 at 20:02

2 Answers2

2

Your question is a little bit confusing. I am assuming that you want to take an input date that either looks like "Jan 15, 2021 22:05" (24-hour time) or "Jan 15, 2021 10:05 PM" (12 hour time) and convert it to standard "internet date" ISO8601DateFormatter date format.

You say you want to determine the input selection based on "device selection". I'm assuming you mean that you expect to see input dates in either 12 or 24 hour format based on the settings on the user's device.

This function will let you figure out the 12/24 hour setting of the user's device:

func dateFormatIs24Hour() -> Bool {
    guard let dateFormat = DateFormatter.dateFormat (fromTemplate: "j",
                                                     options:0,
                                                     locale: Locale.current) else {
        return false
    }
    return !dateFormat.contains("a")
}

You should then be able to generate a date formatter formatString based on the device's 12/24 hour setting:

func MMMddyyyyDateFormat(twentyFourHour: Bool) -> String {
    let hourFormat = is24Hour ? "HH" : "hh"
    let amOrPmSuffix = is24Hour ? "" : "a"
    let  dateFormat = "MMM dd, yyyy \(hourFormat):mm \(amOrPmSuffix)"
    return dateFormat
}

And you can set up an ISO8601DateFormatter to output dates in "internet date format:

let internetDateFormatter = ISO8601DateFormatter()
internetDateFormatter.formatOptions = .withInternetDateTime

Pulling it all together in a sample viewDidLoad() function for a shell iOS app:

override func viewDidLoad() {
    super.viewDidLoad()
    is24Hour = dateFormatIs24Hour()


    let inputDateFormatter = DateFormatter()
    inputDateFormatter.dateFormat = MMMddyyyyDateFormat(twentyFourHour: is24Hour)

    let internetDateFormatter = ISO8601DateFormatter()
    internetDateFormatter.formatOptions = .withInternetDateTime

    //-----------------------------------------
    //This code to generate a value `randomDate` using `thirtyDays` is 
    //only for testing.  It generates a random date that is in a range 
    //from roughly 30 days in the past to 30 days in the future.
    let thirtyDays = 30.0 * 24 * 60 * 60

    let randomInterval = Double.random(in: -thirtyDays...thirtyDays)
    let randomDate = Date().addingTimeInterval(randomInterval)
    //-----------------------------------------


    let inputDateString = inputDateFormatter.string(from: randomDate)

    var outputDateString = ""

    if  let convertedDate = inputDateFormatter.date(from: inputDateString) {
         outputDateString = internetDateFormatter.string(from: convertedDate)
    }
    print("Date string \(inputDateString) in Internet format = \(outputDateString)")
}
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thanks Duncan! Will **ThirtyDays** will validated for feb month & 31 days month ? – KkMIW Jan 31 '21 at 20:03
  • I wrote sample code that generates a random date that a date range roughly from 30 days before the current date to thirty days after the current date. The var thirtyDays is a Double representing the approximate number of seconds in 30 days. (30 days • 24 hours/day • 60 minutes/hour • 60 seconds/minute. You're not really supposed to do date calculations that way, but it's just code to generate test dates. – Duncan C Jan 31 '21 at 20:08
  • I would not recommend using the thirtyDays code except for testing. It does not take into account the number of days in each month, ignores leap years and leap seconds, etc. It's is purely for testing. – Duncan C Jan 31 '21 at 20:10
0

you can find 24 hour to 12 from device select by below codes:

let formatter = DateFormatter.init()
        formatter.locale = Locale.current
        formatter.dateStyle = .none
        formatter.timeStyle = .short
        let dateString = formatter.string(from: Date())
        let amRange = dateString.range(of: formatter.amSymbol)
        let pmRange = dateString.range(of: formatter.pmSymbol)
        let is24h = (pmRange == nil && amRange == nil)
        print(is24h)

and set custom format for show timing with this code:

if is24h {
            formatter.dateFormat = "HH" // for 24 hour
        } else {
            formatter.dateFormat = "hh" // for 12 hour
        }
hessam
  • 404
  • 3
  • 10