5

In Swift, I can do something like this:

let ordinalFormatter = NumberFormatter()
ordinalFormatter.numberStyle = .ordinal

print(ordinalFormatter.string(from: NSNumber(value: 3))) // 3rd

but I don't see any way to do this so easily in Kotlin. Is there such a way, or will I have to use 3rd-party libraries or write my own?

Ky -
  • 30,724
  • 51
  • 192
  • 308
  • 1
    Well, it is usually hard to prove that something doesn't exist. :) But I'm almost sure there's no such function in stdlib or anything that can be immediately adapted for it. Moreover, stdlib doesn't contain anything locale-specific, and you should actually resort to some third-party software or implement your own solution. – hotkey Jan 21 '17 at 00:01
  • @hotkey Sounds like an answer to me! – Ky - Jan 21 '17 at 00:05
  • 1
    Okay then, posted this as an answer. :) – hotkey Jan 21 '17 at 00:39

2 Answers2

14

Well, it is usually hard to prove that something doesn't exist. But I have never come across any function in kotlin-stdlib that would do this or could be immediately adapted for this. Moreover, kotlin-stdlib doesn't seem to contain anything locale-specific (which number ordinals certainly are).

I guess you should actually resort to some third-party software or implement your own solution, which might be something as simple as this:

fun ordinalOf(i: Int) {
    val iAbs = i.absoluteValue // if you want negative ordinals, or just use i
    return "$i" + if (iAbs % 100 in 11..13) "th" else when (iAbs % 10) {
        1 -> "st"
        2 -> "nd"
        3 -> "rd"
        else -> "th"
    }
}

Also, solutions in Java: (here)

hotkey
  • 140,743
  • 39
  • 371
  • 326
2

Here's my take, a variant of @hotkey's solution:

    fun Int.ordinal() = "$this" + when {
        (this % 100 in 11..13) -> "th"
        (this % 10) == 1 -> "st"
        (this % 10) == 2 -> "nd"
        (this % 10) == 3 -> "rd"
        else -> "th"
    }

Invoke with e.g. 13.ordinal().

neu242
  • 15,796
  • 20
  • 79
  • 114