Using Locales with Java's toLowerCase() and toUpperCase()

JavaStringLocale

Java Problem Overview


I wanted code to convert all the characters in strings to uppercase or lowercase in Java.

I found a method that goes something like this:

public static String changelowertoupper()
{
         String str = "CyBeRdRaGoN";
         str=str.toLowerCase(Locale.ENGLISH);
         return str;
}

Now I've read that using certain Locales, like Turkish, "returns i (without dot) instead of i (with dot)."

Is it safe to use Locales like UK, US, ENGLISH, etc.? Are there any big differences between them when applied to strings?

Which is the most preferred Locale for Strings?

Java Solutions


Solution 1 - Java

I think you should use locale ,

> For instance, "TITLE".toLowerCase() in a Turkish locale returns > "tıtle", where 'ı' is the LATIN SMALL LETTER DOTLESS I character. To > obtain correct results for locale insensitive strings, use > toLowerCase(Locale.ENGLISH).

I refer to these links as solution to your problem and it has point to keep in mind in you situation "Turkish"

**FROM THE LINKS**

> toLowerCase() respects internationalization (i18n). It performs the > case conversion with respect to your Locale. When you call > toLowerCase(), internally toLowerCase(Locale.getDefault()) is getting > called. It is locale sensitive and you should not write a logic around > it interpreting locale independently.

import java.util.Locale;
 
public class ToLocaleTest {
    public static void main(String[] args) throws Exception {
        Locale.setDefault(new Locale("lt")); //setting Lithuanian as locale
        String str = "\u00cc";
    System.out.println("Before case conversion is "+str+
" and length is "+str.length());// Ì
        String lowerCaseStr = str.toLowerCase();
    System.out.println("Lower case is "+lowerCaseStr+
" and length is "+lowerCaseStr.length());// iı`
    }
}

> In the above program, look at the string length before and after > conversion. It will be 1 and 3. Yes the length of the string before > and after case conversion is different. Your logic will go for a toss > when you depend on string length on this scenario. When your program > gets executed in a different environment, it may fail. This will be a > nice catch in code review. > > To make it safer, you may use another method > toLowerCase(Locale.English) and override the locale to English always. > But then you are not internationalized. > > So the crux is, toLowerCase() is locale specific.

reference 1
reference 2
reference 3


Dotless-i, is a lowercase 'i' without dot. The uppercase of this character is the usual "I". There is another character, "I with dot". The lowercase of this character is the usual lowercase "i".

Have you noticed the problem? This unsymetrical conversion causes a serious problem in programming. We face this problem mostly in Java applications because of (IMHO) poor implementation of toLowerCase and toUpperCase functions.

In Java, String.toLowerCase() method converts characters to lowercase according to the default locale. This causes problems if your application works in Turkish locale and especially if you are using this function for a file name or a url that must obey a certain character set.

I have blogged about two serious examples before: The compile errors with Script libraries with "i" in their names and XSP Manager's fault if an XPage is in a database with "I" in its name.

There is a long history, as I said. For instance in some R7 version, router was unable to send a message to a recipient if his/her name starts with "I". Message reporting agents was not running in Turkish locale until R8. Anyone with Turkish locale could not install Lotus Notes 8.5.1 (it's real!). The list goes on...

There is almost no beta tester from Turkey and customers don't open PMR for these problems. So these problems are not going up to the first priority for development teams.

Even Java team has added a special warning to the latest documentation:

> This method is locale sensitive, and may produce unexpected results if > used for strings that are intended to be interpreted locale > independently. Examples are programming language identifiers, protocol > keys, and HTML tags. For instance, "TITLE".toLowerCase() in a Turkish > locale returns "tıtle", where 'ı' is the LATIN SMALL LETTER DOTLESS I > character. To obtain correct results for locale insensitive strings, > use toLowerCase(Locale.ENGLISH).

Solution 2 - Java

You can create appropriate locale for your String's language.

For example:

toUpperCase(new Locale("tr","TR"));

will do the trick for Turkish.

Solution 3 - Java

String str = "CyBeRdRaGoN";

str = str.toLowerCase(); // str = "cyberdragon"

str = str.toUpperCase(); // str = "CYBERDRAGON"

Your application will choose default locale, so if someone will run your application in Turkish with turkish locale he will see i without dot

Solution 4 - Java

If you are using this function for checking a string (e.g. search) It is safe to use the strings in a lowercase or uppercase form to check. You may use it like this:

if (mViewData.list.data[i].Name.toLowerCase(new Locale("tr", "TR"))
   .contains(mViewHolder.tctSearch.getText().toString().trim()
                                      .toLowerCase(new Locale("tr", "TR")))) {
    // your code here...
}

I confront the same issue but in a case of search in listview. I added this answer that it may help someone who has the same issue.

Solution 5 - Java

In kotlin

private fun changelowertoupper(): String {
        val str = "CyBeRdRaGoN"
        return str.lowercase()
    }

Solution 6 - Java

If you want you can use android:textLocale="tr" option on XML side.

<TextView
android:text="inciler"
android:textAllCaps="true"
android:textLocale="tr" />

Output: İNCİLER

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArjun K PView Question on Stackoverflow
Solution 1 - JavashareefView Answer on Stackoverflow
Solution 2 - JavaCanerView Answer on Stackoverflow
Solution 3 - JavaalasterView Answer on Stackoverflow
Solution 4 - JavaAlp AltunelView Answer on Stackoverflow
Solution 5 - JavaIrvin JoaoView Answer on Stackoverflow
Solution 6 - JavaEmefarView Answer on Stackoverflow