[C#] IFormatProvider для счетных существительных
От: PawnHunter  
Дата: 30.05.04 21:01
Оценка: 278 (18)
Класс NumeralsFormatter реализует интерфейс IFormatProvider.
Позволяет с помощью форматирующих строк строить грамматически правильные выражения, содержащие числовые значения. Позволяет форматировать числа в числительные. Поддерживает только русский и английский языки.
Короче, это для детей. (С)"Наследник Хадсакера"

Возможны два типа форматирования:
W — для выбора правильной формы существительного.
T — для построения числительного.

Из примеров все должно быть понятно.

NumeralsFormatter formatter = new NumeralsFormatter();
string s = String.Format(formatter, format, param1, param2, ...);


Дальше примеры того, каким может быть format, и каким может быть s в зависимости от параметров.

format = "Inbox: {0} {0:W;новое,новых} {0:W;сообщение,сообщения,сообщений}";

Inbox: 1 новое сообщение
Inbox: 2 новых сообщения
Inbox: 5 новых сообщений


Сокращенная форма:

format = "Inbox: {0} {0:W;нов(ое,ых)} {0:W;сообщени(е,я,й)}";

Inbox: 1 новое сообщение
Inbox: 2 новых сообщения
Inbox: 5 новых сообщений


Еще один пример:

format = "{0:W;Найден(а,о)} {0} {0:W;запис(ь,и,ей)}, {0:W;удовлетворяющ(ая,их)} запросу.";

Найдена 1 запись, удовлетворяющая запросу.
Найдено 5 записей, удовлетворяющих запросу.


Для форматирования числа в числительное используется символ T:

format = "{0:T}";

Одно
Тринадцать


После форматирующего символа можно через точку с запятой указать род числительного.
От регистра форматирующего символа зависит регистр первой буквы числительного:

format = "{0:t;f}";

одна
тринадцать


Еще несколько примеров:

format = "{0:T} {0:W;час(,а,ов)}.";

Два часа.
Десять часов.


format = "{0:T;M} {0:W;час(,а,ов)} {1:t;F} {1:W;минут(а,ы,)}.";

Два часа десять минут.
Двадцать один час одна минута.
Ноль часов ноль минут.


Сумма прписью:

format = "{0:T;M} {0:W;рубл(ь,я,ей)} {1:00} коп.";

Один рубль 12 коп.
Три рубля 05 коп.


Выбор языка числительных зависит от свойства NumeralsFormatter.CultureInfo.
По умолчанию используется CultureInfo текущего потока.
Можно явно передать нужный CultureInfo в конструктор NumeralsFormatter либо изменить значения свойства.

Переходим на английский:
formatter.CultureInfo = new CultureInfo("en-US");

format = "{0:T} {0:W;dollar(,s)} and {1:t} {1:W;cent(,s)}.";

One dollar and two cents.
One hundred and twenty-three thousand, four hundred and fifty-six dollars and seven cents.


Полученную строчку не стыдно и пользователю показать, а можно и синтезатору речи передать.
Если в системе установлен MS Text To Speech API, то можно на подобии английского языка послушать, который сейчас час.

format = "{0:T} {0:W;hour(,s)} and {1:t} {1:W;minute(,s)}.";
string text = String.Format(formatter, format, DateTime.Now.Hour, DateTime.Now.Minute);

SpVoiceClass voice = new SpVoiceClass();
voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);


Вообще-то MS Speech понимает цифры, и переводить их в текст не обязательно. Но если в языке числительные изменяются по родам (как в русском и многих других), то перевод в текст необходим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.