iosswiftxcodesuperscriptdateformatter

How to make the st,nd,rd,th as superscript along with date and time in swift ios


How to make the st,nd,rd,th as supescript along with date and time in swift xcode 13. I have set the items in the tableviewcell

From the tableView cell I'm setting the date and time like in below code

let date = meetingListArray[indexPath.row].callScheduleDate?.dateConversion(date: meetingListArray[indexPath.row].callScheduleDate ?? "") ?? ""
        let toTime = meetingListArray[indexPath.row].timeTo?.timeConverter(date: meetingListArray[indexPath.row].timeTo ?? "") ?? ""
        let fromTime = meetingListArray[indexPath.row].timeFrom?.timeConverter(date: meetingListArray[indexPath.row].timeFrom ?? "") ?? ""
        let time = fromTime + " -" + toTime
        cell.callDateAndTime.text = date  + time

I have written the the dateFormatWithSuffix(), daySuffix() as extension

 func dateFormatWithSuffix() -> String {
            return "MMMM dd'\(self.daySuffix())' yyyy  | "
        }

        func daySuffix() -> String {
            let calendar = Calendar.current
            let components = (calendar as NSCalendar).components(.day, from: self)
            let dayOfMonth = components.day
            switch dayOfMonth {
            case 1, 21, 31:
                return "st"
            case 2, 22:
                return "nd"
            case 3, 23:
                return "rd"
            default:
                return "th"
            }
        }

I have added the image of date and time here Image of date and time


Solution

  • One way to do this is with an Attributed string.

    For example (using your daySuffix() func):

        let someDate: Date = Date()
    
        let df = DateFormatter()
    
        // use DateFormatter and/or Calendar Components to get
        //  Month Name, dayOfMonth, year (as Strings)
        df.dateFormat = "MMMM"
        let m: String = df.string(from: someDate)
        
        df.dateFormat = "d"
        let d: String = df.string(from: someDate)
    
        df.dateFormat = "yyyy"
        let y: String = df.string(from: someDate)
        
        // get the day suffix
        let dsf = someDate.daySuffix()
        
        // however you parse/format your to/from times
        let theTimePart: String = "12:00 AM - 12:00 AM"
        
        // font for everything except the superscript
        let font1: UIFont = .systemFont(ofSize: 12.0, weight: .regular)
        // font for the superscript (slightly smaller)
        let font2: UIFont = .systemFont(ofSize: 8.0, weight: .regular)
        
        // atributes for "main" part of string
        let mainAttributes: [NSAttributedString.Key: Any] = [.font: font1]
        
        // atributes for "superscript" part of string
        //  baselineOffset of the difference between the two font sizes
        //  seems to work fairly well
        let superscriptAttributes: [NSAttributedString.Key: Any] = [.font: font2, .baselineOffset: (font1.pointSize - font2.pointSize)]
    
        // first part will be (for example) "August 17" with main attributes
        let firstPart = NSMutableAttributedString(string: m + " \(d)", attributes: mainAttributes)
        // second part will be the day suffix (st,nd,th,rd) with superscript attributes
        let secondPart = NSAttributedString(string: dsf, attributes: superscriptAttributes)
        // third part will be (for example) " 2022 | 12:00 AM - 12:00 AM" with main attributes
        let thirdPart = NSAttributedString(string: " \(y) | \(theTimePart)", attributes: mainAttributes)
        
        // append second part
        firstPart.append(secondPart)
        // append third part
        firstPart.append(thirdPart)
        
        // set the label's attributed text
        cell.callDateAndTime.text = firstPart
    

    Result:

    enter image description here