Skip to content

Instantly share code, notes, and snippets.

@NightOwl888
Last active April 24, 2023 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NightOwl888/ed824c8ceb23d6d5322997db9c5fd71e to your computer and use it in GitHub Desktop.
Save NightOwl888/ed824c8ceb23d6d5322997db9c5fd71e to your computer and use it in GitHub Desktop.
ICU4N RuleBasedNumberFormat Demo
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ICU4N" Version="60.1.0-alpha.402" />
</ItemGroup>
</Project>
using ICU4N;
using ICU4N.Globalization;
using System.Globalization;
using System.Numerics;
namespace ICU4N.RuleBasedNumberFormat.Demo
{
internal class Program
{
static void Main(string[] args)
{
long number1 = 34567;
int number2 = 123;
BigInteger number3 = 8890;
Console.OutputEncoding = System.Text.Encoding.UTF8;
// NOTE: The ToString() overloads here are extension methods, which can be found by
// adding "using ICU4N;" to the top of the file. They can alternatively be found in
// the ICU4N.FormatNumberRuleBased static class. For example:
// ICU4N.FormatNumberRuleBased.ToString(123, NumberPresentation.SpellOut, new UCultureInfo("en"));
Console.WriteLine("SpellOut formatting in neutral English culture:");
// Supported types for IFormatProvider are:
// 1) System.Globalization.CultureInfo
// 2) ICU4N.Globalization.UCultureInfo
// 3) ICU4N.Globalization.UNumberFormatInfo (which can be found on UCultureInfo.NumberFormat)
// NOTE: System.Globalization.NumberFormatInfo is not a currently supported provider.
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut, new UCultureInfo("en")));
Console.WriteLine();
Console.WriteLine("SpellOut formatting in neutral French culture:");
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut, new CultureInfo("fr")));
Console.WriteLine();
Console.WriteLine("SpellOut formatting in Spanish (Spain) culture with specific ruleSetName:");
var spain = new UCultureInfo("es-ES");
string[] spainRuleSetNames = spain.NumberFormat.SpellOut.RuleSetNames.ToArray();
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut, spainRuleSetNames[3], spain));
Console.WriteLine();
Console.WriteLine("Ordinal formatting in neutral Portuguese culture:");
var portuguese = new UCultureInfo("pt");
IReadOnlyList<string> portugueseRuleSetNames = portuguese.NumberFormat.Ordinal.RuleSetNames;
Console.WriteLine(number1.ToString(NumberPresentation.Ordinal, portugueseRuleSetNames[1], portuguese));
Console.WriteLine();
Console.WriteLine("Roman numerals in upper case:");
Console.WriteLine(number2.ToString(NumberPresentation.NumberingSystem, "%roman-upper", UCultureInfo.InvariantCulture));
Console.WriteLine();
Console.WriteLine("Hebrew (algoritmic) formatting in upper case:");
// Note that NumberingSystem rules are available in any culture. Here, we just use
// UCultureInfo.InvariantCulture rather than specifying "he" for Hebrew.
string number1Hebrew = number1.ToString(NumberPresentation.NumberingSystem, "%hebrew", UCultureInfo.InvariantCulture);
// NOTE: This may fail to display on Console if not setup on the local system. See: https://stackoverflow.com/a/5750227
Console.WriteLine(number1Hebrew);
Console.WriteLine();
Console.WriteLine("BigInteger SpellOut in German (Germany) culture:");
// This demonstrates setting the culture on the current thread rather than
// passing the culture as a parameter. We store the original culture temporarily
// so it can be restored after the operation. In a multi-threaded application
// it is typical to set the culture of the current thread at the beginning of
// the request and not pass it as a parameter to culture-sensitive APIs, such as
// number formatting.
CultureInfo temp = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = new CultureInfo("de-DE");
Console.WriteLine(number3.ToString(NumberPresentation.SpellOut)); // Uses the current culture
Console.WriteLine();
}
finally
{
CultureInfo.CurrentCulture = temp;
}
Console.WriteLine("SpellOut formatting in Japanese (Japan) culture:");
string number1Japanese = number1.ToString(NumberPresentation.SpellOut, new CultureInfo("ja-JP"));
// NOTE: This may fail to display on Console if not setup on the local system. See: https://stackoverflow.com/a/5750227
Console.WriteLine(number1Japanese);
Console.WriteLine();
Console.WriteLine("SpellOut formatting in current culture:");
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut)); // Uses the current culture
Console.WriteLine();
Console.WriteLine("SpellOut formatting in neutral Dutch culture with capitialization:");
var dutchCaptialized = new UCultureInfo("nl");
// Here we set the capitalization property directly.
// This is fine because the UCultureInfo instance was created for the current thread
// and nothing else needs to access it.
dutchCaptialized.NumberFormat.Capitalization = Capitalization.ForBeginningOfSentence;
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut, dutchCaptialized));
Console.WriteLine();
Console.WriteLine("SpellOut formatting in neutral current culture with capitialization:");
// Here we don't own the UCultureInfo instance, so we create a clone of UNumberFormatInfo
// to ensure any other code is unaffected by changing settings. We could alernatively clone
// UCultureInfo and then edit UCultureInfo.NumberFormat.Capitalization, as above.
var currentCulture = UCultureInfo.CurrentCulture;
var nfi = (UNumberFormatInfo)currentCulture.NumberFormat.Clone();
nfi.Capitalization = Capitalization.ForBeginningOfSentence;
Console.WriteLine(number1.ToString(NumberPresentation.SpellOut, nfi));
Console.WriteLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment