Does Kotlin have a standard way to format a number as an English ordinal?
Asked Answered
B

3

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?

Benedic answered 20/1, 2017 at 21:31 Comment(3)
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.Biannulate
@Biannulate Sounds like an answer to me!Benedic
Okay then, posted this as an answer. :)Biannulate
B
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)

Biannulate answered 21/1, 2017 at 0:38 Comment(6)
The Int class could also be extended, for example: fun Int.asOrdinal() ...Shirtwaist
This doesn't work for negatives 🙈Benedic
@Ky- Are negative ordinals a thing? I'm curious about your use case.Biannulate
@Biannulate "Find the $ordinal root of this number" -> Find the -4th root of this numberBenedic
@Ky, yeah, and I also found out about negative floor numbers (like, -2nd floor).Biannulate
It seems that just using the absoluteValue to determine the suffix should work if you want negative ordinals.Biannulate
S
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().

Stingaree answered 28/10, 2022 at 6:59 Comment(1)
This doesn't work for negatives 🙈Benedic
A
0
fun Int.toOrdinalNumber(): String {
    if (this in 11..13) {
        return "${this}th"
    }

    return when (this % 10) {
        1 -> "${this}st"
        2 -> "${this}nd"
        3 -> "${this}rd"
        else -> "${this}th"
    }
}

In this code, the In this code, the getOrdinalNumber extension function is added to the Int class. It first checks if the number is in the range of 11 to 13 because in these cases, the ordinal is always "th." For other cases, it checks the last digit of the number and appends "st," "nd," or "rd" accordingly. If none of these conditions match, it appends "th." extension function is added to the Int class. It first checks if the number is in the range of 11 to 13 because in these cases, the ordinal is always "th." For other cases, it checks the last digit of the number and appends "st," "nd," or "rd" accordingly. If none of these conditions match, it appends "th."

Aman answered 16/10, 2023 at 23:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.