From b294b70c662d10156bb3d133f33ba452f482a6d9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 24 Feb 2024 19:54:49 +1100 Subject: [PATCH] clean up some formatting (#1453) --- src/Humanizer.Tests/ArticlePrefixSortTests.cs | 8 +- src/Humanizer.Tests/Bytes/ArithmeticTests.cs | 154 +++--- src/Humanizer.Tests/Bytes/ByteRateTests.cs | 48 +- .../Bytes/ByteSizeExtensionsTests.cs | 330 ++++++------ src/Humanizer.Tests/Bytes/ComparingTests.cs | 28 +- src/Humanizer.Tests/Bytes/CreatingTests.cs | 64 +-- src/Humanizer.Tests/Bytes/ParsingTests.cs | 58 +-- src/Humanizer.Tests/Bytes/ToStringTests.cs | 6 +- src/Humanizer.Tests/DateHumanize.cs | 136 ++--- .../DateHumanizeDefaultStrategyTests.cs | 22 +- src/Humanizer.Tests/DateOnlyHumanizeTests.cs | 131 +++-- src/Humanizer.Tests/EnumHumanizeTests.cs | 1 + src/Humanizer.Tests/FluentDate/InDateTests.cs | 46 +- src/Humanizer.Tests/FluentDate/OnDateTests.cs | 26 +- src/Humanizer.Tests/InflectorTests.cs | 490 +++++++++--------- .../Localisation/az/TimeSpanHumanizeTests.cs | 72 ++- .../Localisation/de/Bytes/ByteRateTests.cs | 5 +- .../de/DateToOrdinalWordsTests.cs | 6 +- .../en/DateToOrdinalWordsTests.cs | 16 +- .../en/TimeToClockNotationTests.cs | 97 ++-- .../Localisation/es/OrdinalizeTests.cs | 12 +- .../es/TimeToClockNotationTests.cs | 117 +++-- .../fr/DateToOrdinalWordsTests.cs | 14 +- .../Localisation/fr/TimeOnlyHumanizeTests.cs | 128 ++--- .../Localisation/fr/TimeSpanHumanizeTests.cs | 136 +++-- .../fr/TimeToClockNotationTests.cs | 109 ++-- .../is/CollectionFormatterTests.cs | 24 +- .../Localisation/is/TimeOnlyHumanizeTests.cs | 73 ++- .../Localisation/is/TimeSpanHumanizeTests.cs | 6 +- .../it/CollectionFormatterTests.cs | 24 +- .../Localisation/lb/Bytes/ByteRateTests.cs | 15 +- .../pt-BR/TimeToClockNotationTests.cs | 97 ++-- .../ro-Ro/CollectionFormatterTests.cs | 24 +- .../sr-Latn/TimeSpanHumanizeTests.cs | 72 ++- .../Localisation/sr/TimeSpanHumanizeTests.cs | 72 ++- .../Localisation/vi/TimeSpanHumanizeTests.cs | 72 ++- src/Humanizer.Tests/MetricNumeralTests.cs | 48 +- src/Humanizer.Tests/NumberToNumberTests.cs | 150 +++--- src/Humanizer.Tests/NumberToTimeSpanTests.cs | 304 +++++------ src/Humanizer.Tests/NumberToWordsTests.cs | 117 +++-- src/Humanizer.Tests/OrdinalizeTests.cs | 68 +-- src/Humanizer.Tests/TimeOnlyHumanizeTests.cs | 109 ++-- src/Humanizer.Tests/TimeSpanHumanizeTests.cs | 1 + src/Humanizer/ArticlePrefixSort.cs | 93 ++-- src/Humanizer/Bytes/ByteRate.cs | 26 +- src/Humanizer/Bytes/ByteSize.cs | 473 ++++++++--------- src/Humanizer/CasingExtensions.cs | 26 +- src/Humanizer/CollectionHumanizeExtensions.cs | 48 +- .../CollectionFormatterRegistry.cs | 28 +- src/Humanizer/Configuration/Configurator.cs | 24 +- ...DateOnlyToOrdinalWordsConverterRegistry.cs | 17 +- .../DateToOrdinalWordsConverterRegistry.cs | 13 +- .../Configuration/FormatterRegistry.cs | 129 ++--- .../Configuration/LocaliserRegistry.cs | 14 +- .../NumberToWordsConverterRegistry.cs | 100 ++-- .../Configuration/OrdinalizerRegistry.cs | 35 +- ...meOnlyToClockNotationConvertersRegistry.cs | 17 +- src/Humanizer/DateHumanizeExtensions.cs | 84 +-- .../DefaultDateOnlyHumanizeStrategy.cs | 19 +- .../DefaultTimeOnlyHumanizeStrategy.cs | 19 +- .../IDateOnlyHumanizeStrategy.cs | 17 +- .../ITimeOnlyHumanizeStrategy.cs | 17 +- .../PrecisionDateOnlyHumanizeStrategy.cs | 35 +- .../PrecisionTimeOnlyHumanizeStrategy.cs | 35 +- src/Humanizer/FluentDate/InDate.cs | 17 +- src/Humanizer/HeadingExtensions.cs | 85 +-- src/Humanizer/Inflections/Vocabularies.cs | 252 ++++----- src/Humanizer/InflectorExtensions.cs | 25 +- .../DefaultCollectionFormatter.cs | 104 ++-- .../DefaultDateOnlyToOrdinalWordConverter.cs | 17 +- .../EsDateOnlyToOrdinalWordsConverter.cs | 13 +- .../FrDateOnlyToOrdinalWordsConverter.cs | 13 +- .../FrDateToOrdinalWordsConverter.cs | 6 +- .../IDateOnlyToOrdinalWordConverter.cs | 25 +- .../LtDateOnlyToOrdinalWordsConverter.cs | 15 +- .../UsDateOnlyToOrdinalWordsConverter.cs | 11 +- .../Formatters/ArabicFormatter.cs | 24 +- .../Formatters/CroatianFormatter.cs | 14 +- .../Formatters/CzechSlovakPolishFormatter.cs | 12 +- .../Formatters/DefaultFormatter.cs | 60 +-- .../Formatters/FrenchFormatter.cs | 20 +- .../Formatters/HebrewFormatter.cs | 26 +- .../Formatters/LithuanianFormatter.cs | 36 +- .../Formatters/MalteseFormatter.cs | 14 +- .../Formatters/RussianFormatter.cs | 28 +- .../Formatters/SerbianFormatter.cs | 14 +- .../Formatters/SlovenianFormatter.cs | 22 +- .../Formatters/UkrainianFormatter.cs | 28 +- .../RussianGrammaticalNumberDetector.cs | 28 +- .../AfrikaansNumberToWordsConverter.cs | 224 ++++---- .../ArabicNumberToWordsConverter.cs | 374 +++++++------ .../ArmenianNumberToWordsConverter.cs | 236 +++++---- .../AzerbaijaniNumberToWordsConverter.cs | 171 +++--- .../BanglaNumberToWordsConverter.cs | 209 +++++--- ...azilianPortugueseNumberToWordsConverter.cs | 264 +++++----- .../BulgarianNumberToWordsConverter.cs | 188 +++---- .../CentralKurdishNumberToWordsConverter.cs | 101 ++-- .../ChineseNumberToWordsConverter.cs | 152 +++--- .../CzechNumberToWordsConverter.cs | 140 ++--- .../DutchNumberToWordsConverter.cs | 197 ++++--- .../EnglishNumberToWordsConverter.cs | 264 +++++----- .../FarsiNumberToWordsConverter.cs | 110 ++-- .../FrenchBelgianNumberToWordsConverter.cs | 36 +- .../GreekNumberToWordsConverter.cs | 425 ++++++++------- .../HebrewNumberToWordsConverter.cs | 233 +++++---- .../IcelandicNumberToWordsConverter.cs | 483 ++++++++++------- .../IndianNumberToWordsConverter.cs | 94 ++-- .../Italian/ItalianCardinalNumberCruncher.cs | 262 +++++----- .../Italian/ItalianOrdinalNumberCruncher.cs | 120 ++--- .../ItalianNumberToWordsConverter.cs | 31 +- .../JapaneseNumberToWordsConverter.cs | 71 +-- .../KoreanNumberToWordsConverter.cs | 160 +++--- .../LithuanianNumberToWordsConverter.cs | 308 +++++------ .../NorwegianBokmalNumberToWordsConverter.cs | 247 +++++---- .../PolishNumberToWordsConverter.cs | 170 +++--- .../PortugueseNumberToWordsConverter.cs | 264 +++++----- .../RomanianCardinalNumberConverter.cs | 290 ++++++----- .../RomanianOrdinalNumberConverter.cs | 190 ++++--- .../RomanianNumberToWordsConverter.cs | 19 +- .../RussianNumberToWordsConverter.cs | 358 ++++++------- .../SerbianCyrlNumberToWordsConverter.cs | 155 +++--- .../SerbianNumberToWordsConverter.cs | 155 +++--- .../SlovenianNumberToWordsConverter.cs | 157 +++--- .../SpanishNumberToWordsConverter.cs | 421 +++++++-------- .../SwedishNumberToWordsConverter.cs | 266 +++++----- .../TamilNumberToWordsConverter.cs | 384 +++++++------- .../ThaiNumberToWordsConverter.cs | 139 +++-- .../TurkishNumberToWordConverter.cs | 254 +++++---- .../UkrainianNumberToWordsConverter.cs | 346 ++++++------- .../UzbekCyrlNumberToWordConverter.cs | 153 +++--- .../UzbekLatnNumberToWordConverter.cs | 153 +++--- .../Ordinalizers/DutchOrdinalizer.cs | 14 +- .../Ordinalizers/EnglishOrdinalizer.cs | 32 +- .../Ordinalizers/FrenchOrdinalizer.cs | 15 +- .../Ordinalizers/ItalianOrdinalizer.cs | 22 +- .../Ordinalizers/SpanishOrdinalizer.cs | 42 +- .../Ordinalizers/UkrainianOrdinalizer.cs | 36 +- src/Humanizer/Localisation/Resources.cs | 27 +- ...tugueseTimeOnlyToClockNotationConverter.cs | 51 +- ...DefaultTimeOnlyToClockNotationConverter.cs | 61 ++- .../EsTimeOnlyToClockNotationConverter.cs | 139 +++-- .../FrTimeOnlyToClockNotationConverter.cs | 37 +- .../ITimeOnlyToClockNotationConverter.cs | 17 +- src/Humanizer/MetricNumeralExtensions.cs | 247 +++++---- src/Humanizer/RomanNumeralExtensions.cs | 138 +++-- src/Humanizer/StringDehumanizeExtensions.cs | 12 +- src/Humanizer/StringHumanizeExtensions.cs | 87 ++-- .../TimeOnlyToClockNotationExtensions.cs | 25 +- src/Humanizer/TimeSpanHumanizeExtensions.cs | 221 ++++---- src/Humanizer/ToQuantityExtensions.cs | 36 +- src/Humanizer/Transformer/ToLowerCase.cs | 6 +- src/Humanizer/Transformer/ToUpperCase.cs | 6 +- src/Humanizer/TruncateExtensions.cs | 33 +- src/Humanizer/TruncateFrom.cs | 17 + .../Truncation/FixedLengthTruncator.cs | 44 +- .../FixedNumberOfCharactersTruncator.cs | 74 +-- src/Humanizer/TupleizeExtensions.cs | 58 +-- 157 files changed, 8556 insertions(+), 7629 deletions(-) create mode 100644 src/Humanizer/TruncateFrom.cs diff --git a/src/Humanizer.Tests/ArticlePrefixSortTests.cs b/src/Humanizer.Tests/ArticlePrefixSortTests.cs index 40a989ded..4a75f58d9 100644 --- a/src/Humanizer.Tests/ArticlePrefixSortTests.cs +++ b/src/Humanizer.Tests/ArticlePrefixSortTests.cs @@ -14,8 +14,8 @@ public void SortStringArrayIgnoringArticlePrefixes(string[] input, string[] expe [Fact] public void An_Empty_String_Array_Throws_ArgumentOutOfRangeException() { - string[] items = []; - void action() => EnglishArticle.AppendArticlePrefix(items); - Assert.Throws(action); - } + string[] items = []; + void action() => EnglishArticle.AppendArticlePrefix(items); + Assert.Throws(action); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Bytes/ArithmeticTests.cs b/src/Humanizer.Tests/Bytes/ArithmeticTests.cs index f7aaa8a8e..66c49895b 100644 --- a/src/Humanizer.Tests/Bytes/ArithmeticTests.cs +++ b/src/Humanizer.Tests/Bytes/ArithmeticTests.cs @@ -5,136 +5,150 @@ public class ArithmeticTests [Fact] public void Add() { - var size1 = ByteSize.FromBytes(1); - var result = size1.Add(size1); + var size1 = ByteSize.FromBytes(1); + var result = size1.Add(size1); - Assert.Equal(2, result.Bytes); - Assert.Equal(16, result.Bits); - } + Assert.Equal(2, result.Bytes); + Assert.Equal(16, result.Bits); + } [Fact] public void AddBits() { - var size = ByteSize.FromBytes(1).AddBits(8); + var size = ByteSize + .FromBytes(1) + .AddBits(8); - Assert.Equal(2, size.Bytes); - Assert.Equal(16, size.Bits); - } + Assert.Equal(2, size.Bytes); + Assert.Equal(16, size.Bits); + } [Fact] public void AddBytes() { - var size = ByteSize.FromBytes(1).AddBytes(1); + var size = ByteSize + .FromBytes(1) + .AddBytes(1); - Assert.Equal(2, size.Bytes); - Assert.Equal(16, size.Bits); - } + Assert.Equal(2, size.Bytes); + Assert.Equal(16, size.Bits); + } [Fact] public void AddKilobytes() { - var size = ByteSize.FromKilobytes(2).AddKilobytes(2); + var size = ByteSize + .FromKilobytes(2) + .AddKilobytes(2); - Assert.Equal(4 * 1024 * 8, size.Bits); - Assert.Equal(4 * 1024, size.Bytes); - Assert.Equal(4, size.Kilobytes); - } + Assert.Equal(4 * 1024 * 8, size.Bits); + Assert.Equal(4 * 1024, size.Bytes); + Assert.Equal(4, size.Kilobytes); + } [Fact] public void AddMegabytes() { - var size = ByteSize.FromMegabytes(2).AddMegabytes(2); + var size = ByteSize + .FromMegabytes(2) + .AddMegabytes(2); - Assert.Equal(4 * 1024 * 1024 * 8, size.Bits); - Assert.Equal(4 * 1024 * 1024, size.Bytes); - Assert.Equal(4 * 1024, size.Kilobytes); - Assert.Equal(4, size.Megabytes); - } + Assert.Equal(4 * 1024 * 1024 * 8, size.Bits); + Assert.Equal(4 * 1024 * 1024, size.Bytes); + Assert.Equal(4 * 1024, size.Kilobytes); + Assert.Equal(4, size.Megabytes); + } [Fact] public void AddGigabytes() { - var size = ByteSize.FromGigabytes(2).AddGigabytes(2); + var size = ByteSize + .FromGigabytes(2) + .AddGigabytes(2); - Assert.Equal(4d * 1024 * 1024 * 1024 * 8, size.Bits); - Assert.Equal(4d * 1024 * 1024 * 1024, size.Bytes); - Assert.Equal(4d * 1024 * 1024, size.Kilobytes); - Assert.Equal(4d * 1024, size.Megabytes); - Assert.Equal(4d, size.Gigabytes); - } + Assert.Equal(4d * 1024 * 1024 * 1024 * 8, size.Bits); + Assert.Equal(4d * 1024 * 1024 * 1024, size.Bytes); + Assert.Equal(4d * 1024 * 1024, size.Kilobytes); + Assert.Equal(4d * 1024, size.Megabytes); + Assert.Equal(4d, size.Gigabytes); + } [Fact] public void AddTerabytes() { - var size = ByteSize.FromTerabytes(2).AddTerabytes(2); - - Assert.Equal(4d * 1024 * 1024 * 1024 * 1024 * 8, size.Bits); - Assert.Equal(4d * 1024 * 1024 * 1024 * 1024, size.Bytes); - Assert.Equal(4d * 1024 * 1024 * 1024, size.Kilobytes); - Assert.Equal(4d * 1024 * 1024, size.Megabytes); - Assert.Equal(4d * 1024, size.Gigabytes); - Assert.Equal(4d, size.Terabytes); - } + var size = ByteSize + .FromTerabytes(2) + .AddTerabytes(2); + + Assert.Equal(4d * 1024 * 1024 * 1024 * 1024 * 8, size.Bits); + Assert.Equal(4d * 1024 * 1024 * 1024 * 1024, size.Bytes); + Assert.Equal(4d * 1024 * 1024 * 1024, size.Kilobytes); + Assert.Equal(4d * 1024 * 1024, size.Megabytes); + Assert.Equal(4d * 1024, size.Gigabytes); + Assert.Equal(4d, size.Terabytes); + } [Fact] public void Subtract() { - var size = ByteSize.FromBytes(4).Subtract(ByteSize.FromBytes(2)); + var size = ByteSize + .FromBytes(4) + .Subtract(ByteSize.FromBytes(2)); - Assert.Equal(16, size.Bits); - Assert.Equal(2, size.Bytes); - } + Assert.Equal(16, size.Bits); + Assert.Equal(2, size.Bytes); + } [Fact] public void IncrementOperator() { - var size = ByteSize.FromBytes(2); - size++; + var size = ByteSize.FromBytes(2); + size++; - Assert.Equal(24, size.Bits); - Assert.Equal(3, size.Bytes); - } + Assert.Equal(24, size.Bits); + Assert.Equal(3, size.Bytes); + } [Fact] public void NegativeOperator() { - var size = ByteSize.FromBytes(2); + var size = ByteSize.FromBytes(2); - size = -size; + size = -size; - Assert.Equal(-16, size.Bits); - Assert.Equal(-2, size.Bytes); - } + Assert.Equal(-16, size.Bits); + Assert.Equal(-2, size.Bytes); + } [Fact] public void DecrementOperator() { - var size = ByteSize.FromBytes(2); - size--; + var size = ByteSize.FromBytes(2); + size--; - Assert.Equal(8, size.Bits); - Assert.Equal(1, size.Bytes); - } + Assert.Equal(8, size.Bits); + Assert.Equal(1, size.Bytes); + } [Fact] public void PlusOperator() { - var size1 = ByteSize.FromBytes(1); - var size2 = ByteSize.FromBytes(1); + var size1 = ByteSize.FromBytes(1); + var size2 = ByteSize.FromBytes(1); - var result = size1 + size2; + var result = size1 + size2; - Assert.Equal(2, result.Bytes); - } + Assert.Equal(2, result.Bytes); + } [Fact] public void MinusOperator() { - var size1 = ByteSize.FromBytes(2); - var size2 = ByteSize.FromBytes(1); + var size1 = ByteSize.FromBytes(2); + var size2 = ByteSize.FromBytes(1); - var result = size1 - size2; + var result = size1 - size2; - Assert.Equal(1, result.Bytes); - } -} \ No newline at end of file + Assert.Equal(1, result.Bytes); + } +} diff --git a/src/Humanizer.Tests/Bytes/ByteRateTests.cs b/src/Humanizer.Tests/Bytes/ByteRateTests.cs index 192be18b6..3915f19af 100644 --- a/src/Humanizer.Tests/Bytes/ByteRateTests.cs +++ b/src/Humanizer.Tests/Bytes/ByteRateTests.cs @@ -12,13 +12,15 @@ public class ByteRateTests [InlineData(15 * 60 * 1024 * 1024, 60, "15 MB/s")] public void HumanizesRates(long inputBytes, double perSeconds, string expectedValue) { - var size = new ByteSize(inputBytes); - var interval = TimeSpan.FromSeconds(perSeconds); + var size = new ByteSize(inputBytes); + var interval = TimeSpan.FromSeconds(perSeconds); - var rate = size.Per(interval).Humanize(); + var rate = size + .Per(interval) + .Humanize(); - Assert.Equal(expectedValue, rate); - } + Assert.Equal(expectedValue, rate); + } [Theory] [InlineData(1, 1, TimeUnit.Second, "1 MB/s")] @@ -32,27 +34,27 @@ public void HumanizesRates(long inputBytes, double perSeconds, string expectedVa [InlineData(1, 10 * 60 * 60, TimeUnit.Hour, "102.4 KB/h")] public void TimeUnitTests(long megabytes, double measurementIntervalSeconds, TimeUnit displayInterval, string expectedValue) { - var size = ByteSize.FromMegabytes(megabytes); - var measurementInterval = TimeSpan.FromSeconds(measurementIntervalSeconds); + var size = ByteSize.FromMegabytes(megabytes); + var measurementInterval = TimeSpan.FromSeconds(measurementIntervalSeconds); - var rate = size.Per(measurementInterval); - var text = rate.Humanize(displayInterval); + var rate = size.Per(measurementInterval); + var text = rate.Humanize(displayInterval); - Assert.Equal(expectedValue, text); - } + Assert.Equal(expectedValue, text); + } [Theory] [InlineData(19854651984, 1, TimeUnit.Second, null, "18.49 GB/s")] [InlineData(19854651984, 1, TimeUnit.Second, "#.##", "18.49 GB/s")] public void FormattedTimeUnitTests(long bytes, int measurementIntervalSeconds, TimeUnit displayInterval, string? format, string expectedValue) { - var size = ByteSize.FromBytes(bytes); - var measurementInterval = TimeSpan.FromSeconds(measurementIntervalSeconds); - var rate = size.Per(measurementInterval); - var text = rate.Humanize(format, displayInterval); + var size = ByteSize.FromBytes(bytes); + var measurementInterval = TimeSpan.FromSeconds(measurementIntervalSeconds); + var rate = size.Per(measurementInterval); + var text = rate.Humanize(format, displayInterval); - Assert.Equal(expectedValue, text); - } + Assert.Equal(expectedValue, text); + } [Theory] [InlineData(TimeUnit.Millisecond)] @@ -62,12 +64,10 @@ public void FormattedTimeUnitTests(long bytes, int measurementIntervalSeconds, T [InlineData(TimeUnit.Year)] public void ThrowsOnUnsupportedData(TimeUnit units) { - var dummyRate = ByteSize.FromBits(1).Per(TimeSpan.FromSeconds(1)); - - Assert.Throws(() => - { - dummyRate.Humanize(units); - }); - } + var dummyRate = ByteSize + .FromBits(1) + .Per(TimeSpan.FromSeconds(1)); + Assert.Throws(() => dummyRate.Humanize(units)); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Bytes/ByteSizeExtensionsTests.cs b/src/Humanizer.Tests/Bytes/ByteSizeExtensionsTests.cs index 18e37dc87..8f968607c 100644 --- a/src/Humanizer.Tests/Bytes/ByteSizeExtensionsTests.cs +++ b/src/Humanizer.Tests/Bytes/ByteSizeExtensionsTests.cs @@ -6,58 +6,58 @@ public class ByteSizeExtensionsTests [Fact] public void ByteTerabytes() { - const byte size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void SbyteTerabytes() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void ShortTerabytes() { - const short size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const short size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void UshortTerabytes() { - const ushort size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void IntTerabytes() { - const int size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const int size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void UintTerabytes() { - const uint size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void DoubleTerabytes() { - const double size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const double size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Fact] public void LongTerabytes() { - const long size = 2; - Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); - } + const long size = 2; + Assert.Equal(ByteSize.FromTerabytes(size), size.Terabytes()); + } [Theory] [InlineData(2, null, "en", "2 TB")] @@ -69,66 +69,68 @@ public void LongTerabytes() [InlineData(2.123, "#.#", "ru-RU", "2,1 TB")] public void HumanizesTerabytes(double input, string? format, string cultureName, string expectedValue) { - var culture = new CultureInfo(cultureName); + var culture = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Terabytes().Humanize(format, culture)); - } + Assert.Equal(expectedValue, input + .Terabytes() + .Humanize(format, culture)); + } [Fact] public void ByteGigabytes() { - const byte size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void SbyteGigabytes() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void ShortGigabytes() { - const short size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const short size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void UshortGigabytes() { - const ushort size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void IntGigabytes() { - const int size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const int size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void UintGigabytes() { - const uint size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void DoubleGigabytes() { - const double size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const double size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Fact] public void LongGigabytes() { - const long size = 2; - Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); - } + const long size = 2; + Assert.Equal(ByteSize.FromGigabytes(size), size.Gigabytes()); + } [Theory] [InlineData(0, null, "en", "0 b")] @@ -139,66 +141,68 @@ public void LongGigabytes() [InlineData(2.123, "#.##", "en", "2.12 GB")] public void HumanizesGigabytes(double input, string? format, string cultureName, string expectedValue) { - var cultureInfo = new CultureInfo(cultureName); + var cultureInfo = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Gigabytes().Humanize(format, cultureInfo)); - } + Assert.Equal(expectedValue, input + .Gigabytes() + .Humanize(format, cultureInfo)); + } [Fact] public void ByteMegabytes() { - const byte size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void SbyteMegabytes() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void ShortMegabytes() { - const short size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const short size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void UshortMegabytes() { - const ushort size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void IntMegabytes() { - const int size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const int size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void UintMegabytes() { - const uint size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void DoubleMegabytes() { - const double size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const double size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Fact] public void LongMegabytes() { - const long size = 2; - Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); - } + const long size = 2; + Assert.Equal(ByteSize.FromMegabytes(size), size.Megabytes()); + } [Theory] [InlineData(0, null, "en", "0 b")] @@ -209,66 +213,68 @@ public void LongMegabytes() [InlineData(2.123, "#", "en", "2 MB")] public void HumanizesMegabytes(double input, string? format, string cultureName, string expectedValue) { - var cultureInfo = new CultureInfo(cultureName); + var cultureInfo = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Megabytes().Humanize(format, cultureInfo)); - } + Assert.Equal(expectedValue, input + .Megabytes() + .Humanize(format, cultureInfo)); + } [Fact] public void ByteKilobytes() { - const byte size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void SbyteKilobytes() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void ShortKilobytes() { - const short size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const short size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void UshortKilobytes() { - const ushort size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void IntKilobytes() { - const int size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const int size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void UintKilobytes() { - const uint size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void DoubleKilobytes() { - const double size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const double size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Fact] public void LongKilobytes() { - const long size = 2; - Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); - } + const long size = 2; + Assert.Equal(ByteSize.FromKilobytes(size), size.Kilobytes()); + } [Theory] [InlineData(0, null, "en", "0 b")] @@ -279,66 +285,68 @@ public void LongKilobytes() [InlineData(2.123, "#.####", "en", "2.123 KB")] public void HumanizesKilobytes(double input, string? format, string cultureName, string expectedValue) { - var cultureInfo = new CultureInfo(cultureName); + var cultureInfo = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Kilobytes().Humanize(format, cultureInfo)); - } + Assert.Equal(expectedValue, input + .Kilobytes() + .Humanize(format, cultureInfo)); + } [Fact] public void ByteBytes() { - const byte size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void SbyteBytes() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void ShortBytes() { - const short size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const short size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void UshortBytes() { - const ushort size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void IntBytes() { - const int size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const int size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void UintBytes() { - const uint size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void DoubleBytes() { - const double size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const double size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Fact] public void LongBytes() { - const long size = 2; - Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); - } + const long size = 2; + Assert.Equal(ByteSize.FromBytes(size), size.Bytes()); + } [Theory] [InlineData(0, null, "en", "0 b")] @@ -354,59 +362,61 @@ public void LongBytes() [InlineData(10000000, "#,##0.# KB", "en", "9,765.6 KB")] public void HumanizesBytes(double input, string? format, string cultureName, string expectedValue) { - var cultureInfo = new CultureInfo(cultureName); + var cultureInfo = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Bytes().Humanize(format, cultureInfo)); - } + Assert.Equal(expectedValue, input + .Bytes() + .Humanize(format, cultureInfo)); + } [Fact] public void ByteBits() { - const byte size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const byte size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void SbyteBits() { - const sbyte size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const sbyte size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void ShortBits() { - const short size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const short size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void UshortBits() { - const ushort size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const ushort size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void IntBits() { - const int size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const int size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void UintBits() { - const uint size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const uint size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Fact] public void LongBits() { - const long size = 2; - Assert.Equal(ByteSize.FromBits(size), size.Bits()); - } + const long size = 2; + Assert.Equal(ByteSize.FromBits(size), size.Bits()); + } [Theory] [InlineData(0, null, "en", "0 b")] @@ -417,8 +427,10 @@ public void LongBits() [InlineData(10000, "#.# KB", "en", "1.2 KB")] public void HumanizesBits(long input, string? format, string cultureName, string expectedValue) { - var cultureInfo = new CultureInfo(cultureName); + var cultureInfo = new CultureInfo(cultureName); - Assert.Equal(expectedValue, input.Bits().Humanize(format, cultureInfo)); - } + Assert.Equal(expectedValue, input + .Bits() + .Humanize(format, cultureInfo)); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Bytes/ComparingTests.cs b/src/Humanizer.Tests/Bytes/ComparingTests.cs index f6fe56c4a..98e87a075 100644 --- a/src/Humanizer.Tests/Bytes/ComparingTests.cs +++ b/src/Humanizer.Tests/Bytes/ComparingTests.cs @@ -9,12 +9,12 @@ public class ComparingTests [InlineData(45, 23, 1)] public void CompareStrongTyped(double value, double valueToCompareWith, int expectedResult) { - var valueSize = new ByteSize(value); - var otherSize = new ByteSize(valueToCompareWith); - var result = valueSize.CompareTo(otherSize); + var valueSize = new ByteSize(value); + var otherSize = new ByteSize(valueToCompareWith); + var result = valueSize.CompareTo(otherSize); - Assert.Equal(expectedResult, result); - } + Assert.Equal(expectedResult, result); + } [Theory] [InlineData(13, 23, -1)] @@ -22,21 +22,21 @@ public void CompareStrongTyped(double value, double valueToCompareWith, int expe [InlineData(45, 23, 1)] public void CompareUntyped(double value, double valueToCompareWith, int expectedResult) { - var valueSize = new ByteSize(value); - object otherSize = new ByteSize(valueToCompareWith); - var result = valueSize.CompareTo(otherSize); + var valueSize = new ByteSize(value); + object otherSize = new ByteSize(valueToCompareWith); + var result = valueSize.CompareTo(otherSize); - Assert.Equal(expectedResult, result); - } + Assert.Equal(expectedResult, result); + } [Theory] [InlineData(new[] { "1GB", "3KB", "5MB" }, new[] { "3KB", "5MB", "1GB" })] [InlineData(new[] { "1MB", "3KB", "5MB" }, new[] { "3KB", "1MB", "5MB" })] public void SortList(IEnumerable values, IEnumerable expected) { - var list = values.Select(ByteSize.Parse).ToList(); - list.Sort(); + var list = values.Select(ByteSize.Parse).ToList(); + list.Sort(); - Assert.Equal(expected.Select(ByteSize.Parse), list); - } + Assert.Equal(expected.Select(ByteSize.Parse), list); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Bytes/CreatingTests.cs b/src/Humanizer.Tests/Bytes/CreatingTests.cs index 4f6b270b1..bb8a8d209 100644 --- a/src/Humanizer.Tests/Bytes/CreatingTests.cs +++ b/src/Humanizer.Tests/Bytes/CreatingTests.cs @@ -27,67 +27,67 @@ public class CreatingTests [Fact] public void Constructor() { - var result = new ByteSize(1099511627776); + var result = new ByteSize(1099511627776); - Assert.Equal(8.796093022208e12, result.Bits); - Assert.Equal(1099511627776, result.Bytes); - Assert.Equal(1073741824, result.Kilobytes); - Assert.Equal(1048576, result.Megabytes); - Assert.Equal(1024, result.Gigabytes); - Assert.Equal(1, result.Terabytes); - } + Assert.Equal(8.796093022208e12, result.Bits); + Assert.Equal(1099511627776, result.Bytes); + Assert.Equal(1073741824, result.Kilobytes); + Assert.Equal(1048576, result.Megabytes); + Assert.Equal(1024, result.Gigabytes); + Assert.Equal(1, result.Terabytes); + } [Fact] public void FromBits() { - var result = ByteSize.FromBits(8); + var result = ByteSize.FromBits(8); - Assert.Equal(8, result.Bits); - Assert.Equal(1, result.Bytes); - } + Assert.Equal(8, result.Bits); + Assert.Equal(1, result.Bytes); + } [Fact] public void FromBytes() { - var result = ByteSize.FromBytes(1.5); + var result = ByteSize.FromBytes(1.5); - Assert.Equal(12, result.Bits); - Assert.Equal(1.5, result.Bytes); - } + Assert.Equal(12, result.Bits); + Assert.Equal(1.5, result.Bytes); + } [Fact] public void FromKilobytes() { - var result = ByteSize.FromKilobytes(1.5); + var result = ByteSize.FromKilobytes(1.5); - Assert.Equal(1536, result.Bytes); - Assert.Equal(1.5, result.Kilobytes); - } + Assert.Equal(1536, result.Bytes); + Assert.Equal(1.5, result.Kilobytes); + } [Fact] public void FromMegabytes() { - var result = ByteSize.FromMegabytes(1.5); + var result = ByteSize.FromMegabytes(1.5); - Assert.Equal(1572864, result.Bytes); - Assert.Equal(1.5, result.Megabytes); - } + Assert.Equal(1572864, result.Bytes); + Assert.Equal(1.5, result.Megabytes); + } [Fact] public void FromGigabytes() { - var result = ByteSize.FromGigabytes(1.5); + var result = ByteSize.FromGigabytes(1.5); - Assert.Equal(1610612736, result.Bytes); - Assert.Equal(1.5, result.Gigabytes); - } + Assert.Equal(1610612736, result.Bytes); + Assert.Equal(1.5, result.Gigabytes); + } [Fact] public void FromTerabytes() { - var result = ByteSize.FromTerabytes(1.5); + var result = ByteSize.FromTerabytes(1.5); - Assert.Equal(1649267441664, result.Bytes); - Assert.Equal(1.5, result.Terabytes); - } + Assert.Equal(1649267441664, result.Bytes); + Assert.Equal(1.5, result.Terabytes); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Bytes/ParsingTests.cs b/src/Humanizer.Tests/Bytes/ParsingTests.cs index 650f80a3f..ce02b1b36 100644 --- a/src/Humanizer.Tests/Bytes/ParsingTests.cs +++ b/src/Humanizer.Tests/Bytes/ParsingTests.cs @@ -32,18 +32,18 @@ public void Parse() => [Fact] public void TryParseReturnsFalseOnNull() { - Assert.False(ByteSize.TryParse(null, out var result)); - Assert.Equal(default, result); - } + Assert.False(ByteSize.TryParse(null, out var result)); + Assert.Equal(default, result); + } [Fact] public void TryParse() { - var resultBool = ByteSize.TryParse("1020KB", out var resultByteSize); + var resultBool = ByteSize.TryParse("1020KB", out var resultByteSize); - Assert.True(resultBool); - Assert.Equal(ByteSize.FromKilobytes(1020), resultByteSize); - } + Assert.True(resultBool); + Assert.Equal(ByteSize.FromKilobytes(1020), resultByteSize); + } [Theory] [InlineData("2000.01KB", "")] // Invariant @@ -57,31 +57,31 @@ public void TryParse() [InlineData("+2000,01KB", "de")] public void TryParseWithCultureInfo(string value, string cultureName) { - var culture = new CultureInfo(cultureName); + var culture = new CultureInfo(cultureName); - Assert.True(ByteSize.TryParse(value, culture, out var resultByteSize)); - Assert.Equal(ByteSize.FromKilobytes(2000.01), resultByteSize); + Assert.True(ByteSize.TryParse(value, culture, out var resultByteSize)); + Assert.Equal(ByteSize.FromKilobytes(2000.01), resultByteSize); - Assert.Equal(resultByteSize, ByteSize.Parse(value, culture)); - } + Assert.Equal(resultByteSize, ByteSize.Parse(value, culture)); + } [Fact] public void TryParseWithNumberFormatInfo() { - var numberFormat = new NumberFormatInfo - { - NumberDecimalSeparator = "_", - NumberGroupSeparator = ";", - NegativeSign = "−", // proper minus, not hyphen-minus - }; + var numberFormat = new NumberFormatInfo + { + NumberDecimalSeparator = "_", + NumberGroupSeparator = ";", + NegativeSign = "−", // proper minus, not hyphen-minus + }; - var value = "−2;000_01KB"; + var value = "−2;000_01KB"; - Assert.True(ByteSize.TryParse(value, numberFormat, out var resultByteSize)); - Assert.Equal(ByteSize.FromKilobytes(-2000.01), resultByteSize); + Assert.True(ByteSize.TryParse(value, numberFormat, out var resultByteSize)); + Assert.Equal(ByteSize.FromKilobytes(-2000.01), resultByteSize); - Assert.Equal(resultByteSize, ByteSize.Parse(value, numberFormat)); - } + Assert.Equal(resultByteSize, ByteSize.Parse(value, numberFormat)); + } [Fact] public void ParseDecimalMegabytes() => @@ -99,13 +99,13 @@ public void ParseDecimalMegabytes() => [InlineData("1000KBB")] // Bad suffix public void TryParseReturnsFalseOnBadValue(string input) { - var resultBool = ByteSize.TryParse(input, out var resultByteSize); + var resultBool = ByteSize.TryParse(input, out var resultByteSize); - Assert.False(resultBool); - Assert.Equal(new(), resultByteSize); + Assert.False(resultBool); + Assert.Equal(new(), resultByteSize); - Assert.Throws(() => { ByteSize.Parse(input); }); - } + Assert.Throws(() => ByteSize.Parse(input)); + } [Fact] public void TryParseWorksWithLotsOfSpaces() => @@ -113,7 +113,7 @@ public void TryParseWorksWithLotsOfSpaces() => [Fact] public void ParseThrowsOnNull() => - Assert.Throws(() => { ByteSize.Parse(null!); }); + Assert.Throws(() => ByteSize.Parse(null!)); [Fact] public void ParseBits() => diff --git a/src/Humanizer.Tests/Bytes/ToStringTests.cs b/src/Humanizer.Tests/Bytes/ToStringTests.cs index beab71fb9..db3d8daa8 100644 --- a/src/Humanizer.Tests/Bytes/ToStringTests.cs +++ b/src/Humanizer.Tests/Bytes/ToStringTests.cs @@ -32,9 +32,9 @@ public void ReturnsLargestMetricSuffix() => [Fact] public void ReturnsDefaultNumberFormat() { - Assert.Equal("10.5 KB", ByteSize.FromKilobytes(10.501).ToString()); - Assert.Equal("10.5 KB", ByteSize.FromKilobytes(10.5).ToString("KB")); - } + Assert.Equal("10.5 KB", ByteSize.FromKilobytes(10.501).ToString()); + Assert.Equal("10.5 KB", ByteSize.FromKilobytes(10.5).ToString("KB")); + } [Fact] public void ReturnsProvidedNumberFormat() => diff --git a/src/Humanizer.Tests/DateHumanize.cs b/src/Humanizer.Tests/DateHumanize.cs index 0897f6ff2..117a1719a 100644 --- a/src/Humanizer.Tests/DateHumanize.cs +++ b/src/Humanizer.Tests/DateHumanize.cs @@ -6,87 +6,95 @@ public class DateHumanize static void VerifyWithCurrentDate(string expectedString, TimeSpan deltaFromNow, CultureInfo? culture) { - var utcNow = DateTime.UtcNow; - var localNow = DateTime.Now; + var utcNow = DateTime.UtcNow; + var localNow = DateTime.Now; - // feels like the only way to avoid breaking tests because CPU ticks over is to inject the base date - VerifyWithDate(expectedString, deltaFromNow, culture, localNow, utcNow); - } + // feels like the only way to avoid breaking tests because CPU ticks over is to inject the base date + VerifyWithDate(expectedString, deltaFromNow, culture, localNow, utcNow); + } static void VerifyWithDateInjection(string expectedString, TimeSpan deltaFromNow, CultureInfo? culture) { - var utcNow = new DateTime(2013, 6, 20, 9, 58, 22, DateTimeKind.Utc); - var now = new DateTime(2013, 6, 20, 11, 58, 22, DateTimeKind.Local); + var utcNow = new DateTime(2013, 6, 20, 9, 58, 22, DateTimeKind.Utc); + var now = new DateTime(2013, 6, 20, 11, 58, 22, DateTimeKind.Local); - VerifyWithDate(expectedString, deltaFromNow, culture, now, utcNow); - } + VerifyWithDate(expectedString, deltaFromNow, culture, now, utcNow); + } static void VerifyWithDate(string expectedString, TimeSpan deltaFromBase, CultureInfo? culture, DateTime baseDate, DateTime baseDateUtc) { - Assert.Equal(expectedString, baseDateUtc.Add(deltaFromBase).Humanize(utcDate: true, dateToCompareAgainst: baseDateUtc, culture: culture)); - Assert.Equal(expectedString, baseDate.Add(deltaFromBase).Humanize(false, baseDate, culture: culture)); + Assert.Equal(expectedString, baseDateUtc + .Add(deltaFromBase) + .Humanize(utcDate: true, dateToCompareAgainst: baseDateUtc, culture: culture)); + Assert.Equal(expectedString, baseDate + .Add(deltaFromBase) + .Humanize(false, baseDate, culture: culture)); - // Compared with default utcDate - Assert.Equal(expectedString, baseDateUtc.Add(deltaFromBase).Humanize(utcDate: null, dateToCompareAgainst: baseDateUtc, culture: culture)); - Assert.Equal(expectedString, baseDate.Add(deltaFromBase).Humanize(null, baseDate, culture: culture)); - } + // Compared with default utcDate + Assert.Equal(expectedString, baseDateUtc + .Add(deltaFromBase) + .Humanize(utcDate: null, dateToCompareAgainst: baseDateUtc, culture: culture)); + Assert.Equal(expectedString, baseDate + .Add(deltaFromBase) + .Humanize(null, baseDate, culture: culture)); + } public static void Verify(string expectedString, int unit, TimeUnit timeUnit, Tense tense, double? precision = null, CultureInfo? culture = null, DateTime? baseDate = null, DateTime? baseDateUtc = null) { - // We lock this as these tests can be multi-threaded and we're setting a static - lock (LockObject) + // We lock this as these tests can be multi-threaded and we're setting a static + lock (LockObject) + { + if (precision.HasValue) { - if (precision.HasValue) - { - Configurator.DateTimeHumanizeStrategy = new PrecisionDateTimeHumanizeStrategy(precision.Value); - } - else - { - Configurator.DateTimeHumanizeStrategy = new DefaultDateTimeHumanizeStrategy(); - } + Configurator.DateTimeHumanizeStrategy = new PrecisionDateTimeHumanizeStrategy(precision.Value); + } + else + { + Configurator.DateTimeHumanizeStrategy = new DefaultDateTimeHumanizeStrategy(); + } - var deltaFromNow = new TimeSpan(); - unit = Math.Abs(unit); + var deltaFromNow = new TimeSpan(); + unit = Math.Abs(unit); - if (tense == Tense.Past) - { - unit = -unit; - } + if (tense == Tense.Past) + { + unit = -unit; + } - switch (timeUnit) - { - case TimeUnit.Millisecond: - deltaFromNow = TimeSpan.FromMilliseconds(unit); - break; - case TimeUnit.Second: - deltaFromNow = TimeSpan.FromSeconds(unit); - break; - case TimeUnit.Minute: - deltaFromNow = TimeSpan.FromMinutes(unit); - break; - case TimeUnit.Hour: - deltaFromNow = TimeSpan.FromHours(unit); - break; - case TimeUnit.Day: - deltaFromNow = TimeSpan.FromDays(unit); - break; - case TimeUnit.Month: - deltaFromNow = TimeSpan.FromDays(unit * 31); - break; - case TimeUnit.Year: - deltaFromNow = TimeSpan.FromDays(unit * 366); - break; - } + switch (timeUnit) + { + case TimeUnit.Millisecond: + deltaFromNow = TimeSpan.FromMilliseconds(unit); + break; + case TimeUnit.Second: + deltaFromNow = TimeSpan.FromSeconds(unit); + break; + case TimeUnit.Minute: + deltaFromNow = TimeSpan.FromMinutes(unit); + break; + case TimeUnit.Hour: + deltaFromNow = TimeSpan.FromHours(unit); + break; + case TimeUnit.Day: + deltaFromNow = TimeSpan.FromDays(unit); + break; + case TimeUnit.Month: + deltaFromNow = TimeSpan.FromDays(unit * 31); + break; + case TimeUnit.Year: + deltaFromNow = TimeSpan.FromDays(unit * 366); + break; + } - if (baseDate == null) - { - VerifyWithCurrentDate(expectedString, deltaFromNow, culture); - VerifyWithDateInjection(expectedString, deltaFromNow, culture); - } - else - { - VerifyWithDate(expectedString, deltaFromNow, culture, baseDate.Value, baseDateUtc!.Value); - } + if (baseDate == null) + { + VerifyWithCurrentDate(expectedString, deltaFromNow, culture); + VerifyWithDateInjection(expectedString, deltaFromNow, culture); + } + else + { + VerifyWithDate(expectedString, deltaFromNow, culture, baseDate.Value, baseDateUtc!.Value); } } + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/DateHumanizeDefaultStrategyTests.cs b/src/Humanizer.Tests/DateHumanizeDefaultStrategyTests.cs index c7f0f86ed..ec8ef1714 100644 --- a/src/Humanizer.Tests/DateHumanizeDefaultStrategyTests.cs +++ b/src/Humanizer.Tests/DateHumanizeDefaultStrategyTests.cs @@ -62,12 +62,12 @@ public void HoursFromNow(int hours, string expected) => [InlineData(40, "2 days from now")] public void HoursFromNowNotTomorrow(int hours, string expected) { - //Only test with injected date, as results are dependent on time of day - var utcNow = new DateTime(2014, 6, 28, 9, 58, 22, DateTimeKind.Utc); - var now = new DateTime(2014, 6, 28, 9, 58, 22, DateTimeKind.Local); + //Only test with injected date, as results are dependent on time of day + var utcNow = new DateTime(2014, 6, 28, 9, 58, 22, DateTimeKind.Utc); + var now = new DateTime(2014, 6, 28, 9, 58, 22, DateTimeKind.Local); - DateHumanize.Verify(expected, hours, TimeUnit.Hour, Tense.Future, null, null, now, utcNow); - } + DateHumanize.Verify(expected, hours, TimeUnit.Hour, Tense.Future, null, null, now, utcNow); + } [Theory] [InlineData(1, "yesterday")] @@ -120,17 +120,17 @@ public void Now() => [Fact] public void Never() { - DateTime? never = null; - Assert.Equal("never", never.Humanize()); - } + DateTime? never = null; + Assert.Equal("never", never.Humanize()); + } [Fact] public void Nullable_ExpectSame() { - DateTime? never = new DateTime(2015, 12, 7, 9, 0, 0); + DateTime? never = new DateTime(2015, 12, 7, 9, 0, 0); - Assert.Equal(never.Value.Humanize(), never.Humanize()); - } + Assert.Equal(never.Value.Humanize(), never.Humanize()); + } [Theory] [InlineData(1, TimeUnit.Year, Tense.Future, "en-US", "one year from now")] diff --git a/src/Humanizer.Tests/DateOnlyHumanizeTests.cs b/src/Humanizer.Tests/DateOnlyHumanizeTests.cs index b249398e2..e61d13225 100644 --- a/src/Humanizer.Tests/DateOnlyHumanizeTests.cs +++ b/src/Humanizer.Tests/DateOnlyHumanizeTests.cs @@ -1,95 +1,94 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests +namespace Humanizer.Tests; + +[UseCulture("en-US")] +public class DateOnlyHumanizeTests { - [UseCulture("en-US")] - public class DateOnlyHumanizeTests + [Fact] + public void DefaultStrategy_SameDate() { - [Fact] - public void DefaultStrategy_SameDate() - { - Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); + Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); - var inputTime = new DateOnly(2015, 07, 05); - var baseTime = new DateOnly(2015, 07, 05); + var inputTime = new DateOnly(2015, 07, 05); + var baseTime = new DateOnly(2015, 07, 05); - const string expectedResult = "now"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "now"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void DefaultStrategy_MonthApart() - { - Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); + [Fact] + public void DefaultStrategy_MonthApart() + { + Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); - var inputTime = new DateOnly(2015, 08, 05); - var baseTime = new DateOnly(2015, 07, 05); + var inputTime = new DateOnly(2015, 08, 05); + var baseTime = new DateOnly(2015, 07, 05); - const string expectedResult = "one month from now"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "one month from now"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void DefaultStrategy_DaysAgo() - { - Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); + [Fact] + public void DefaultStrategy_DaysAgo() + { + Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); - var inputTime = new DateOnly(2015, 07, 02); - var baseTime = new DateOnly(2015, 07, 05); + var inputTime = new DateOnly(2015, 07, 02); + var baseTime = new DateOnly(2015, 07, 05); - const string expectedResult = "3 days ago"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "3 days ago"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void DefaultStrategy_YearsAgo() - { - Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); + [Fact] + public void DefaultStrategy_YearsAgo() + { + Configurator.DateOnlyHumanizeStrategy = new DefaultDateOnlyHumanizeStrategy(); - var baseDate = DateTime.Now; - var inputTime = DateOnly.FromDateTime(baseDate.AddMonths(-24)); - var baseTime = DateOnly.FromDateTime(baseDate); + var baseDate = DateTime.Now; + var inputTime = DateOnly.FromDateTime(baseDate.AddMonths(-24)); + var baseTime = DateOnly.FromDateTime(baseDate); - const string expectedResult = "2 years ago"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "2 years ago"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void PrecisionStrategy_NextDay() - { - Configurator.DateOnlyHumanizeStrategy = new PrecisionDateOnlyHumanizeStrategy(0.75); + [Fact] + public void PrecisionStrategy_NextDay() + { + Configurator.DateOnlyHumanizeStrategy = new PrecisionDateOnlyHumanizeStrategy(0.75); - var inputTime = new DateOnly(2015, 07, 05); - var baseTime = new DateOnly(2015, 07, 04); + var inputTime = new DateOnly(2015, 07, 05); + var baseTime = new DateOnly(2015, 07, 04); - const string expectedResult = "tomorrow"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "tomorrow"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void Never() - { - DateOnly? never = null; - Assert.Equal("never", never.Humanize()); - } + [Fact] + public void Never() + { + DateOnly? never = null; + Assert.Equal("never", never.Humanize()); + } - [Fact] - public void Nullable_ExpectSame() - { - DateOnly? never = new DateOnly(2015, 12, 7); + [Fact] + public void Nullable_ExpectSame() + { + DateOnly? never = new DateOnly(2015, 12, 7); - Assert.Equal(never.Value.Humanize(), never.Humanize()); - } + Assert.Equal(never.Value.Humanize(), never.Humanize()); } } diff --git a/src/Humanizer.Tests/EnumHumanizeTests.cs b/src/Humanizer.Tests/EnumHumanizeTests.cs index 35155be38..01ccb68f2 100644 --- a/src/Humanizer.Tests/EnumHumanizeTests.cs +++ b/src/Humanizer.Tests/EnumHumanizeTests.cs @@ -79,6 +79,7 @@ public void HumanizeMembersWithoutDescriptionAttributeWithLocator() Configurator.ResetUseEnumDescriptionPropertyLocator(); } } + [Fact] public void DehumanizeThrowsForEnumNoMatch() { diff --git a/src/Humanizer.Tests/FluentDate/InDateTests.cs b/src/Humanizer.Tests/FluentDate/InDateTests.cs index abd7b2abd..8c35c1a1b 100644 --- a/src/Humanizer.Tests/FluentDate/InDateTests.cs +++ b/src/Humanizer.Tests/FluentDate/InDateTests.cs @@ -1,33 +1,31 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.FluentDate +namespace Humanizer.Tests.FluentDate; + +public class InDateTests { - public class InDateTests - { - [Fact] - public void InJanuary() => - Assert.Equal(new(DateTime.Now.Year, 1, 1), InDate.January); + [Fact] + public void InJanuary() => + Assert.Equal(new(DateTime.Now.Year, 1, 1), InDate.January); - [Fact] - public void InJanuaryOf2009() => - Assert.Equal(new(2009, 1, 1), InDate.JanuaryOf(2009)); + [Fact] + public void InJanuaryOf2009() => + Assert.Equal(new(2009, 1, 1), InDate.JanuaryOf(2009)); - [Fact] - public void InFebruary() => - Assert.Equal(new(DateTime.Now.Year, 2, 1), InDate.February); + [Fact] + public void InFebruary() => + Assert.Equal(new(DateTime.Now.Year, 2, 1), InDate.February); - [Fact] - public void InTheYear() => - Assert.Equal(new(2009, 1, 1), InDate.TheYear(2009)); + [Fact] + public void InTheYear() => + Assert.Equal(new(2009, 1, 1), InDate.TheYear(2009)); - [Fact] - public void InFiveDays() - { - var baseDate = OnDate.January.The21st; - var date = InDate.Five.DaysFrom(baseDate); - Assert.Equal(baseDate.AddDays(5), date); - } + [Fact] + public void InFiveDays() + { + var baseDate = OnDate.January.The21st; + var date = InDate.Five.DaysFrom(baseDate); + Assert.Equal(baseDate.AddDays(5), date); } } -#endif - +#endif \ No newline at end of file diff --git a/src/Humanizer.Tests/FluentDate/OnDateTests.cs b/src/Humanizer.Tests/FluentDate/OnDateTests.cs index 09f219990..647a41895 100644 --- a/src/Humanizer.Tests/FluentDate/OnDateTests.cs +++ b/src/Humanizer.Tests/FluentDate/OnDateTests.cs @@ -1,21 +1,21 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.FluentDate +namespace Humanizer.Tests.FluentDate; + +public class OnDateTests { - public class OnDateTests - { - [Fact] - public void OnJanuaryThe23rd() => - Assert.Equal(new(DateTime.Now.Year, 1, 23), OnDate.January.The23rd); + [Fact] + public void OnJanuaryThe23rd() => + Assert.Equal(new(DateTime.Now.Year, 1, 23), OnDate.January.The23rd); - [Fact] - public void OnDecemberThe4th() => - Assert.Equal(new(DateTime.Now.Year, 12, 4), OnDate.December.The4th); + [Fact] + public void OnDecemberThe4th() => + Assert.Equal(new(DateTime.Now.Year, 12, 4), OnDate.December.The4th); - [Fact] - public void OnFebruaryThe() => - Assert.Equal(new(DateTime.Now.Year, 2, 11), OnDate.February.The(11)); - } + [Fact] + public void OnFebruaryThe() => + Assert.Equal(new(DateTime.Now.Year, 2, 11), OnDate.February.The(11)); } + #endif diff --git a/src/Humanizer.Tests/InflectorTests.cs b/src/Humanizer.Tests/InflectorTests.cs index 6e3dc30b5..fb76029f1 100644 --- a/src/Humanizer.Tests/InflectorTests.cs +++ b/src/Humanizer.Tests/InflectorTests.cs @@ -38,9 +38,9 @@ public void Pluralize(string singular, string plural) => [ClassData(typeof(PluralTestSource))] public void PluralizeWordsWithUnknownPlurality(string singular, string plural) { - Assert.Equal(plural, plural.Pluralize(false)); - Assert.Equal(plural, singular.Pluralize(false)); - } + Assert.Equal(plural, plural.Pluralize(false)); + Assert.Equal(plural, singular.Pluralize(false)); + } [Theory] [ClassData(typeof(PluralTestSource))] @@ -51,9 +51,9 @@ public void Singularize(string singular, string plural) => [ClassData(typeof(PluralTestSource))] public void SingularizeWordsWithUnknownSingularity(string singular, string plural) { - Assert.Equal(singular, singular.Singularize(false)); - Assert.Equal(singular, plural.Singularize(false)); - } + Assert.Equal(singular, singular.Singularize(false)); + Assert.Equal(singular, plural.Singularize(false)); + } [Theory] [InlineData("tires", "tires")] @@ -156,245 +156,245 @@ class PluralTestSource : IEnumerable { public IEnumerator GetEnumerator() { - yield return ["search", "searches"]; - yield return ["switch", "switches"]; - yield return ["fix", "fixes"]; - yield return ["box", "boxes"]; - yield return ["process", "processes"]; - yield return ["address", "addresses"]; - yield return ["case", "cases"]; - yield return ["stack", "stacks"]; - yield return ["wish", "wishes"]; - yield return ["fish", "fish"]; - - yield return ["category", "categories"]; - yield return ["query", "queries"]; - yield return ["ability", "abilities"]; - yield return ["agency", "agencies"]; - yield return ["movie", "movies"]; - - yield return ["archive", "archives"]; - - yield return ["index", "indices"]; - - yield return ["wife", "wives"]; - yield return ["safe", "saves"]; - yield return ["half", "halves"]; - - yield return ["glove", "gloves"]; - yield return ["move", "moves"]; - - yield return ["salesperson", "salespeople"]; - yield return ["person", "people"]; - - yield return ["spokesman", "spokesmen"]; - yield return ["man", "men"]; - yield return ["woman", "women"]; - yield return ["freshman", "freshmen"]; - yield return ["chairman", "chairmen"]; - yield return ["human", "humans"]; - yield return ["personnel", "personnel"]; - yield return ["staff", "staff"]; - yield return ["training", "training"]; - - yield return ["basis", "bases"]; - yield return ["diagnosis", "diagnoses"]; - - yield return ["datum", "data"]; - yield return ["medium", "media"]; - yield return ["analysis", "analyses"]; - - yield return ["node_child", "node_children"]; - yield return ["child", "children"]; - - yield return ["experience", "experiences"]; - yield return ["day", "days"]; - - yield return ["comment", "comments"]; - yield return ["foobar", "foobars"]; - yield return ["newsletter", "newsletters"]; - - yield return ["old_news", "old_news"]; - yield return ["news", "news"]; - - yield return ["series", "series"]; - yield return ["species", "species"]; - - yield return ["quiz", "quizzes"]; - - yield return ["perspective", "perspectives"]; - - yield return ["ox", "oxen"]; - yield return ["photo", "photos"]; - yield return ["buffalo", "buffaloes"]; - yield return ["tomato", "tomatoes"]; - yield return ["dwarf", "dwarves"]; - yield return ["elf", "elves"]; - yield return ["information", "information"]; - yield return ["equipment", "equipment"]; - yield return ["bus", "buses"]; - yield return ["status", "statuses"]; - yield return ["status_code", "status_codes"]; - yield return ["mouse", "mice"]; - - yield return ["louse", "lice"]; - yield return ["house", "houses"]; - yield return ["octopus", "octopi"]; - yield return ["alias", "aliases"]; - yield return ["portfolio", "portfolios"]; - yield return ["criterion", "criteria"]; - - yield return ["vertex", "vertices"]; - yield return ["matrix", "matrices"]; - - yield return ["axis", "axes"]; - yield return ["testis", "testes"]; - yield return ["crisis", "crises"]; - - yield return ["corn", "corn"]; - yield return ["milk", "milk"]; - yield return ["rice", "rice"]; - yield return ["shoe", "shoes"]; - - yield return ["horse", "horses"]; - yield return ["prize", "prizes"]; - yield return ["edge", "edges"]; - - /* Tests added by Bas Jansen */ - yield return ["goose", "geese"]; - yield return ["deer", "deer"]; - yield return ["sheep", "sheep"]; - yield return ["wolf", "wolves"]; - yield return ["volcano", "volcanoes"]; - yield return ["aircraft", "aircraft"]; - yield return ["alumna", "alumnae"]; - yield return ["alumnus", "alumni"]; - yield return ["fungus", "fungi"]; - - yield return ["water", "water"]; - yield return ["waters", "waters"]; - yield return ["semen", "semen"]; - yield return ["sperm", "sperm"]; - - yield return ["wave", "waves"]; - - yield return ["campus", "campuses"]; - - yield return ["is", "are"]; - - yield return ["addendum", "addenda"]; - yield return ["alga", "algae"]; - yield return ["appendix", "appendices"]; - yield return ["bias", "biases"]; - yield return ["bison", "bison"]; - yield return ["blitz", "blitzes"]; - yield return ["buzz", "buzzes"]; - yield return ["cactus", "cacti"]; - yield return ["corps", "corps"]; - yield return ["curriculum", "curricula"]; - yield return ["database", "databases"]; - yield return ["die", "dice"]; - yield return ["echo", "echoes"]; - yield return ["ellipsis", "ellipses"]; - yield return ["elk", "elk"]; - yield return ["emphasis", "emphases"]; - yield return ["embargo", "embargoes"]; - yield return ["focus", "foci"]; - yield return ["foot", "feet"]; - yield return ["fuse", "fuses"]; - yield return ["grass", "grass"]; - yield return ["hair", "hair"]; - yield return ["hero", "heroes"]; - yield return ["hippopotamus", "hippopotami"]; - yield return ["hoof", "hooves"]; - yield return ["iris", "irises"]; - yield return ["larva", "larvae"]; - yield return ["leaf", "leaves"]; - yield return ["loaf", "loaves"]; - yield return ["luggage", "luggage"]; - yield return ["means", "means"]; - yield return ["mail", "mail"]; - yield return ["millennium", "millennia"]; - yield return ["moose", "moose"]; - yield return ["mosquito", "mosquitoes"]; - yield return ["mud", "mud"]; - yield return ["nucleus", "nuclei"]; - yield return ["neurosis", "neuroses"]; - yield return ["oasis", "oases"]; - yield return ["offspring", "offspring"]; - yield return ["paralysis", "paralyses"]; - yield return ["phenomenon", "phenomena"]; - yield return ["potato", "potatoes"]; - yield return ["radius", "radii"]; - yield return ["salmon", "salmon"]; - yield return ["scissors", "scissors"]; - yield return ["shrimp", "shrimp"]; - yield return ["someone", "someone"]; - yield return ["stimulus", "stimuli"]; - yield return ["swine", "swine"]; - yield return ["syllabus", "syllabi"]; - yield return ["that", "those"]; - yield return ["thief", "thieves"]; - yield return ["this", "these"]; - yield return ["tie", "ties"]; - yield return ["tooth", "teeth"]; - yield return ["torpedo", "torpedoes"]; - yield return ["trellis", "trellises"]; - yield return ["trout", "trout"]; - yield return ["tuna", "tuna"]; - yield return ["vertebra", "vertebrae"]; - yield return ["veto", "vetoes"]; - yield return ["virus", "viruses"]; - yield return ["walrus", "walruses"]; - yield return ["waltz", "waltzes"]; - yield return ["zombie", "zombies"]; - - yield return ["cookie", "cookies"]; - yield return ["bookie", "bookies"]; - yield return ["rookie", "rookies"]; - yield return ["roomie", "roomies"]; - yield return ["smoothie", "smoothies"]; - - //Issue #789 - yield return ["cache", "caches"]; - - //Issue #975, added by Alex Boutin - yield return ["ex", "exes"]; - yield return ["", ""]; - - //Issue #1100 - yield return ["doe", "does"]; - yield return ["hoe", "hoes"]; - yield return ["toe", "toes"]; - yield return ["woe", "woes"]; - - //Issue #1132 - yield return ["metadata", "metadata"]; - - //Issue #1154 - yield return ["a", "as"]; - yield return ["A", "As"]; - yield return ["s", "ss"]; - yield return ["S", "Ss"]; - yield return ["z", "zs"]; - yield return ["Z", "Zs"]; - yield return ["1", "1s"]; - - //Issue #1252 - yield return ["pliers", "pliers"]; - yield return ["sheers", "sheers"]; - yield return ["valve", "valves"]; - yield return ["clothes", "clothes"]; - yield return ["lens", "lenses"]; - yield return ["apparatus", "apparatus"]; - yield return ["clove", "cloves"]; - yield return ["chassis", "chassis"]; - yield return ["explosive", "explosives"]; - yield return ["debris", "debris"]; - - //Issue #1042 - yield return ["database", "databases"]; - } + yield return ["search", "searches"]; + yield return ["switch", "switches"]; + yield return ["fix", "fixes"]; + yield return ["box", "boxes"]; + yield return ["process", "processes"]; + yield return ["address", "addresses"]; + yield return ["case", "cases"]; + yield return ["stack", "stacks"]; + yield return ["wish", "wishes"]; + yield return ["fish", "fish"]; + + yield return ["category", "categories"]; + yield return ["query", "queries"]; + yield return ["ability", "abilities"]; + yield return ["agency", "agencies"]; + yield return ["movie", "movies"]; + + yield return ["archive", "archives"]; + + yield return ["index", "indices"]; + + yield return ["wife", "wives"]; + yield return ["safe", "saves"]; + yield return ["half", "halves"]; + + yield return ["glove", "gloves"]; + yield return ["move", "moves"]; + + yield return ["salesperson", "salespeople"]; + yield return ["person", "people"]; + + yield return ["spokesman", "spokesmen"]; + yield return ["man", "men"]; + yield return ["woman", "women"]; + yield return ["freshman", "freshmen"]; + yield return ["chairman", "chairmen"]; + yield return ["human", "humans"]; + yield return ["personnel", "personnel"]; + yield return ["staff", "staff"]; + yield return ["training", "training"]; + + yield return ["basis", "bases"]; + yield return ["diagnosis", "diagnoses"]; + + yield return ["datum", "data"]; + yield return ["medium", "media"]; + yield return ["analysis", "analyses"]; + + yield return ["node_child", "node_children"]; + yield return ["child", "children"]; + + yield return ["experience", "experiences"]; + yield return ["day", "days"]; + + yield return ["comment", "comments"]; + yield return ["foobar", "foobars"]; + yield return ["newsletter", "newsletters"]; + + yield return ["old_news", "old_news"]; + yield return ["news", "news"]; + + yield return ["series", "series"]; + yield return ["species", "species"]; + + yield return ["quiz", "quizzes"]; + + yield return ["perspective", "perspectives"]; + + yield return ["ox", "oxen"]; + yield return ["photo", "photos"]; + yield return ["buffalo", "buffaloes"]; + yield return ["tomato", "tomatoes"]; + yield return ["dwarf", "dwarves"]; + yield return ["elf", "elves"]; + yield return ["information", "information"]; + yield return ["equipment", "equipment"]; + yield return ["bus", "buses"]; + yield return ["status", "statuses"]; + yield return ["status_code", "status_codes"]; + yield return ["mouse", "mice"]; + + yield return ["louse", "lice"]; + yield return ["house", "houses"]; + yield return ["octopus", "octopi"]; + yield return ["alias", "aliases"]; + yield return ["portfolio", "portfolios"]; + yield return ["criterion", "criteria"]; + + yield return ["vertex", "vertices"]; + yield return ["matrix", "matrices"]; + + yield return ["axis", "axes"]; + yield return ["testis", "testes"]; + yield return ["crisis", "crises"]; + + yield return ["corn", "corn"]; + yield return ["milk", "milk"]; + yield return ["rice", "rice"]; + yield return ["shoe", "shoes"]; + + yield return ["horse", "horses"]; + yield return ["prize", "prizes"]; + yield return ["edge", "edges"]; + + /* Tests added by Bas Jansen */ + yield return ["goose", "geese"]; + yield return ["deer", "deer"]; + yield return ["sheep", "sheep"]; + yield return ["wolf", "wolves"]; + yield return ["volcano", "volcanoes"]; + yield return ["aircraft", "aircraft"]; + yield return ["alumna", "alumnae"]; + yield return ["alumnus", "alumni"]; + yield return ["fungus", "fungi"]; + + yield return ["water", "water"]; + yield return ["waters", "waters"]; + yield return ["semen", "semen"]; + yield return ["sperm", "sperm"]; + + yield return ["wave", "waves"]; + + yield return ["campus", "campuses"]; + + yield return ["is", "are"]; + + yield return ["addendum", "addenda"]; + yield return ["alga", "algae"]; + yield return ["appendix", "appendices"]; + yield return ["bias", "biases"]; + yield return ["bison", "bison"]; + yield return ["blitz", "blitzes"]; + yield return ["buzz", "buzzes"]; + yield return ["cactus", "cacti"]; + yield return ["corps", "corps"]; + yield return ["curriculum", "curricula"]; + yield return ["database", "databases"]; + yield return ["die", "dice"]; + yield return ["echo", "echoes"]; + yield return ["ellipsis", "ellipses"]; + yield return ["elk", "elk"]; + yield return ["emphasis", "emphases"]; + yield return ["embargo", "embargoes"]; + yield return ["focus", "foci"]; + yield return ["foot", "feet"]; + yield return ["fuse", "fuses"]; + yield return ["grass", "grass"]; + yield return ["hair", "hair"]; + yield return ["hero", "heroes"]; + yield return ["hippopotamus", "hippopotami"]; + yield return ["hoof", "hooves"]; + yield return ["iris", "irises"]; + yield return ["larva", "larvae"]; + yield return ["leaf", "leaves"]; + yield return ["loaf", "loaves"]; + yield return ["luggage", "luggage"]; + yield return ["means", "means"]; + yield return ["mail", "mail"]; + yield return ["millennium", "millennia"]; + yield return ["moose", "moose"]; + yield return ["mosquito", "mosquitoes"]; + yield return ["mud", "mud"]; + yield return ["nucleus", "nuclei"]; + yield return ["neurosis", "neuroses"]; + yield return ["oasis", "oases"]; + yield return ["offspring", "offspring"]; + yield return ["paralysis", "paralyses"]; + yield return ["phenomenon", "phenomena"]; + yield return ["potato", "potatoes"]; + yield return ["radius", "radii"]; + yield return ["salmon", "salmon"]; + yield return ["scissors", "scissors"]; + yield return ["shrimp", "shrimp"]; + yield return ["someone", "someone"]; + yield return ["stimulus", "stimuli"]; + yield return ["swine", "swine"]; + yield return ["syllabus", "syllabi"]; + yield return ["that", "those"]; + yield return ["thief", "thieves"]; + yield return ["this", "these"]; + yield return ["tie", "ties"]; + yield return ["tooth", "teeth"]; + yield return ["torpedo", "torpedoes"]; + yield return ["trellis", "trellises"]; + yield return ["trout", "trout"]; + yield return ["tuna", "tuna"]; + yield return ["vertebra", "vertebrae"]; + yield return ["veto", "vetoes"]; + yield return ["virus", "viruses"]; + yield return ["walrus", "walruses"]; + yield return ["waltz", "waltzes"]; + yield return ["zombie", "zombies"]; + + yield return ["cookie", "cookies"]; + yield return ["bookie", "bookies"]; + yield return ["rookie", "rookies"]; + yield return ["roomie", "roomies"]; + yield return ["smoothie", "smoothies"]; + + //Issue #789 + yield return ["cache", "caches"]; + + //Issue #975, added by Alex Boutin + yield return ["ex", "exes"]; + yield return ["", ""]; + + //Issue #1100 + yield return ["doe", "does"]; + yield return ["hoe", "hoes"]; + yield return ["toe", "toes"]; + yield return ["woe", "woes"]; + + //Issue #1132 + yield return ["metadata", "metadata"]; + + //Issue #1154 + yield return ["a", "as"]; + yield return ["A", "As"]; + yield return ["s", "ss"]; + yield return ["S", "Ss"]; + yield return ["z", "zs"]; + yield return ["Z", "Zs"]; + yield return ["1", "1s"]; + + //Issue #1252 + yield return ["pliers", "pliers"]; + yield return ["sheers", "sheers"]; + yield return ["valve", "valves"]; + yield return ["clothes", "clothes"]; + yield return ["lens", "lenses"]; + yield return ["apparatus", "apparatus"]; + yield return ["clove", "cloves"]; + yield return ["chassis", "chassis"]; + yield return ["explosive", "explosives"]; + yield return ["debris", "debris"]; + + //Issue #1042 + yield return ["database", "databases"]; + } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/Humanizer.Tests/Localisation/az/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/az/TimeSpanHumanizeTests.cs index 1eec2c569..c6ecf5b36 100644 --- a/src/Humanizer.Tests/Localisation/az/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/az/TimeSpanHumanizeTests.cs @@ -10,7 +10,9 @@ public class TimeSpanHumanizeTests [InlineData(1096, "3 il")] [InlineData(4018, "11 il")] public void Years(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [Trait("Translation", "Google")] @@ -19,75 +21,89 @@ public void Years(int days, string expected) => [InlineData(92, "3 ay")] [InlineData(335, "11 ay")] public void Months(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(14, "2 həftə")] [InlineData(7, "1 həftə")] public void Weeks(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(6, "6 gün")] [InlineData(2, "2 gün")] public void Days(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 saat")] [InlineData(1, "1 saat")] public void Hours(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 dəqiqə")] [InlineData(1, "1 dəqiqə")] public void Minutes(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 saniyə")] [InlineData(1, "1 saniyə")] public void Seconds(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 millisaniyə")] [InlineData(1, "1 millisaniyə")] public void Milliseconds(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(); + Assert.Equal(expected, actual); + } [Fact] public void NoTime() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(); - Assert.Equal("0 millisaniyə", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(); + Assert.Equal("0 millisaniyə", actual); + } [Fact] public void NoTimeToWords() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(toWords: true); - Assert.Equal("zaman fərqi yoxdur", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(toWords: true); + Assert.Equal("zaman fərqi yoxdur", actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/de/Bytes/ByteRateTests.cs b/src/Humanizer.Tests/Localisation/de/Bytes/ByteRateTests.cs index 0dbe243a5..c0b5d4c15 100644 --- a/src/Humanizer.Tests/Localisation/de/Bytes/ByteRateTests.cs +++ b/src/Humanizer.Tests/Localisation/de/Bytes/ByteRateTests.cs @@ -64,9 +64,6 @@ public void ThrowsOnUnsupportedData(TimeUnit units) { var dummyRate = ByteSize.FromBits(1).Per(TimeSpan.FromSeconds(1)); - Assert.Throws(() => - { - dummyRate.Humanize(units); - }); + Assert.Throws(() => dummyRate.Humanize(units)); } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/de/DateToOrdinalWordsTests.cs b/src/Humanizer.Tests/Localisation/de/DateToOrdinalWordsTests.cs index 615ad5f35..3f7b9af96 100644 --- a/src/Humanizer.Tests/Localisation/de/DateToOrdinalWordsTests.cs +++ b/src/Humanizer.Tests/Localisation/de/DateToOrdinalWordsTests.cs @@ -8,8 +8,8 @@ public void OrdinalizeString() => Assert.Equal("1. Januar 2015", new DateTime(2015, 1, 1).ToOrdinalWords()); #if NET6_0_OR_GREATER - [Fact] - public void OrdinalizeDateOnlyString() => - Assert.Equal("1. Januar 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); + [Fact] + public void OrdinalizeDateOnlyString() => + Assert.Equal("1. Januar 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); #endif } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/en/DateToOrdinalWordsTests.cs b/src/Humanizer.Tests/Localisation/en/DateToOrdinalWordsTests.cs index 43238e0ca..521eb7c9a 100644 --- a/src/Humanizer.Tests/Localisation/en/DateToOrdinalWordsTests.cs +++ b/src/Humanizer.Tests/Localisation/en/DateToOrdinalWordsTests.cs @@ -13,14 +13,14 @@ public void OrdinalizeStringUs() => Assert.Equal("January 1st, 2015", new DateTime(2015, 1, 1).ToOrdinalWords()); #if NET6_0_OR_GREATER - [UseCulture("en-GB")] - [Fact] - public void OrdinalizeDateOnlyStringGb() => - Assert.Equal("1st January 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); + [UseCulture("en-GB")] + [Fact] + public void OrdinalizeDateOnlyStringGb() => + Assert.Equal("1st January 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); - [UseCulture("en-US")] - [Fact] - public void OrdinalizeDateOnlyStringUs() => - Assert.Equal("January 1st, 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); + [UseCulture("en-US")] + [Fact] + public void OrdinalizeDateOnlyStringUs() => + Assert.Equal("January 1st, 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); #endif } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/en/TimeToClockNotationTests.cs b/src/Humanizer.Tests/Localisation/en/TimeToClockNotationTests.cs index a7c14ee15..acc7e5a35 100644 --- a/src/Humanizer.Tests/Localisation/en/TimeToClockNotationTests.cs +++ b/src/Humanizer.Tests/Localisation/en/TimeToClockNotationTests.cs @@ -1,57 +1,56 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.en +namespace Humanizer.Tests.Localisation.en; + +[UseCulture("en")] +public class TimeToClockNotationTests { - [UseCulture("en")] - public class TimeToClockNotationTests + [Theory] + [InlineData(00, 00, "midnight")] + [InlineData(04, 00, "four o'clock")] + [InlineData(05, 01, "five one")] + [InlineData(06, 05, "five past six")] + [InlineData(07, 10, "ten past seven")] + [InlineData(08, 15, "a quarter past eight")] + [InlineData(09, 20, "twenty past nine")] + [InlineData(10, 25, "twenty-five past ten")] + [InlineData(11, 30, "half past eleven")] + [InlineData(12, 00, "noon")] + [InlineData(15, 35, "three thirty-five")] + [InlineData(16, 40, "twenty to five")] + [InlineData(17, 45, "a quarter to six")] + [InlineData(18, 50, "ten to seven")] + [InlineData(19, 55, "five to eight")] + [InlineData(20, 59, "eight fifty-nine")] + public void ConvertToClockNotationTimeOnlyStringEnUs(int hours, int minutes, string expectedResult) { - [Theory] - [InlineData(00, 00, "midnight")] - [InlineData(04, 00, "four o'clock")] - [InlineData(05, 01, "five one")] - [InlineData(06, 05, "five past six")] - [InlineData(07, 10, "ten past seven")] - [InlineData(08, 15, "a quarter past eight")] - [InlineData(09, 20, "twenty past nine")] - [InlineData(10, 25, "twenty-five past ten")] - [InlineData(11, 30, "half past eleven")] - [InlineData(12, 00, "noon")] - [InlineData(15, 35, "three thirty-five")] - [InlineData(16, 40, "twenty to five")] - [InlineData(17, 45, "a quarter to six")] - [InlineData(18, 50, "ten to seven")] - [InlineData(19, 55, "five to eight")] - [InlineData(20, 59, "eight fifty-nine")] - public void ConvertToClockNotationTimeOnlyStringEnUs(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); - Assert.Equal(expectedResult, actualResult); - } + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); + Assert.Equal(expectedResult, actualResult); + } - [Theory] - [InlineData(00, 00, "midnight")] - [InlineData(04, 00, "four o'clock")] - [InlineData(05, 01, "five o'clock")] - [InlineData(06, 05, "five past six")] - [InlineData(07, 10, "ten past seven")] - [InlineData(08, 15, "a quarter past eight")] - [InlineData(09, 20, "twenty past nine")] - [InlineData(10, 25, "twenty-five past ten")] - [InlineData(11, 30, "half past eleven")] - [InlineData(12, 00, "noon")] - [InlineData(13, 23, "twenty-five past one")] - [InlineData(14, 32, "half past two")] - [InlineData(15, 35, "three thirty-five")] - [InlineData(16, 40, "twenty to five")] - [InlineData(17, 45, "a quarter to six")] - [InlineData(18, 50, "ten to seven")] - [InlineData(19, 55, "five to eight")] - [InlineData(20, 59, "nine o'clock")] - public void ConvertToRoundedClockNotationTimeOnlyStringEnUs(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); - Assert.Equal(expectedResult, actualResult); - } + [Theory] + [InlineData(00, 00, "midnight")] + [InlineData(04, 00, "four o'clock")] + [InlineData(05, 01, "five o'clock")] + [InlineData(06, 05, "five past six")] + [InlineData(07, 10, "ten past seven")] + [InlineData(08, 15, "a quarter past eight")] + [InlineData(09, 20, "twenty past nine")] + [InlineData(10, 25, "twenty-five past ten")] + [InlineData(11, 30, "half past eleven")] + [InlineData(12, 00, "noon")] + [InlineData(13, 23, "twenty-five past one")] + [InlineData(14, 32, "half past two")] + [InlineData(15, 35, "three thirty-five")] + [InlineData(16, 40, "twenty to five")] + [InlineData(17, 45, "a quarter to six")] + [InlineData(18, 50, "ten to seven")] + [InlineData(19, 55, "five to eight")] + [InlineData(20, 59, "nine o'clock")] + public void ConvertToRoundedClockNotationTimeOnlyStringEnUs(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); + Assert.Equal(expectedResult, actualResult); } } diff --git a/src/Humanizer.Tests/Localisation/es/OrdinalizeTests.cs b/src/Humanizer.Tests/Localisation/es/OrdinalizeTests.cs index 0412424dc..341a4c08a 100644 --- a/src/Humanizer.Tests/Localisation/es/OrdinalizeTests.cs +++ b/src/Humanizer.Tests/Localisation/es/OrdinalizeTests.cs @@ -26,9 +26,9 @@ public void OrdinalizeZeroOrNegativeNumber(int number, string ordinalized) => [InlineData(21, WordForm.Normal, "21.º")] public void OrdinalizeWithWordForm(int number, WordForm wordForm, string expected) { - Assert.Equal(expected, number.Ordinalize(wordForm)); - Assert.Equal(expected, number.ToString(CultureInfo.CurrentUICulture).Ordinalize(wordForm)); - } + Assert.Equal(expected, number.Ordinalize(wordForm)); + Assert.Equal(expected, number.ToString(CultureInfo.CurrentUICulture).Ordinalize(wordForm)); + } [Theory] [InlineData(1, GrammaticalGender.Masculine, WordForm.Abbreviation, "1.er")] @@ -39,9 +39,9 @@ public void OrdinalizeWithWordForm(int number, WordForm wordForm, string expecte [InlineData(1, GrammaticalGender.Neuter, WordForm.Normal, "1.º")] public void OrdinalizeWithWordFormAndGender(int number, GrammaticalGender gender, WordForm wordForm, string expected) { - Assert.Equal(expected, number.Ordinalize(gender, wordForm)); - Assert.Equal(expected, number.ToString(CultureInfo.CurrentUICulture).Ordinalize(gender, wordForm)); - } + Assert.Equal(expected, number.Ordinalize(gender, wordForm)); + Assert.Equal(expected, number.ToString(CultureInfo.CurrentUICulture).Ordinalize(gender, wordForm)); + } [Theory] [InlineData("1", "1.º")] diff --git a/src/Humanizer.Tests/Localisation/es/TimeToClockNotationTests.cs b/src/Humanizer.Tests/Localisation/es/TimeToClockNotationTests.cs index f4315fafe..b2cc28f2f 100644 --- a/src/Humanizer.Tests/Localisation/es/TimeToClockNotationTests.cs +++ b/src/Humanizer.Tests/Localisation/es/TimeToClockNotationTests.cs @@ -1,67 +1,66 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.es +namespace Humanizer.Tests.Localisation.es; + +[UseCulture("es-ES")] +public class TimeToClockNotationTests { - [UseCulture("es-ES")] - public class TimeToClockNotationTests + [Theory] + [InlineData(0, 0, "medianoche")] + [InlineData(0, 7, "las doce y siete de la noche")] + [InlineData(1, 11, "la una y once de la madrugada")] + [InlineData(4, 0, "las cuatro de la madrugada")] + [InlineData(5, 1, "las cinco y uno de la madrugada")] + [InlineData(6, 0, "las seis de la mañana")] + [InlineData(6, 5, "las seis y cinco de la mañana")] + [InlineData(7, 10, "las siete y diez de la mañana")] + [InlineData(8, 15, "las ocho y cuarto de la mañana")] + [InlineData(9, 20, "las nueve y veinte de la mañana")] + [InlineData(10, 25, "las diez y veinticinco de la mañana")] + [InlineData(11, 30, "las once y media de la mañana")] + [InlineData(12, 00, "mediodía")] + [InlineData(12, 38, "las doce y treinta y ocho de la tarde")] + [InlineData(12, 35, "la una menos veinticinco de la tarde")] + [InlineData(15, 40, "las cuatro menos veinte de la tarde")] + [InlineData(17, 45, "las seis menos cuarto de la tarde")] + [InlineData(19, 50, "las ocho menos diez de la tarde")] + [InlineData(21, 0, "las nueve de la noche")] + [InlineData(21, 55, "las diez menos cinco de la noche")] + [InlineData(22, 59, "las diez y cincuenta y nueve de la noche")] + [InlineData(23, 43, "las once y cuarenta y tres de la noche")] + public void ConvertToClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) { - [Theory] - [InlineData(0, 0, "medianoche")] - [InlineData(0, 7, "las doce y siete de la noche")] - [InlineData(1, 11, "la una y once de la madrugada")] - [InlineData(4, 0, "las cuatro de la madrugada")] - [InlineData(5, 1, "las cinco y uno de la madrugada")] - [InlineData(6, 0, "las seis de la mañana")] - [InlineData(6, 5, "las seis y cinco de la mañana")] - [InlineData(7, 10, "las siete y diez de la mañana")] - [InlineData(8, 15, "las ocho y cuarto de la mañana")] - [InlineData(9, 20, "las nueve y veinte de la mañana")] - [InlineData(10, 25, "las diez y veinticinco de la mañana")] - [InlineData(11, 30, "las once y media de la mañana")] - [InlineData(12, 00, "mediodía")] - [InlineData(12, 38, "las doce y treinta y ocho de la tarde")] - [InlineData(12, 35, "la una menos veinticinco de la tarde")] - [InlineData(15, 40, "las cuatro menos veinte de la tarde")] - [InlineData(17, 45, "las seis menos cuarto de la tarde")] - [InlineData(19, 50, "las ocho menos diez de la tarde")] - [InlineData(21, 0, "las nueve de la noche")] - [InlineData(21, 55, "las diez menos cinco de la noche")] - [InlineData(22, 59, "las diez y cincuenta y nueve de la noche")] - [InlineData(23, 43, "las once y cuarenta y tres de la noche")] - public void ConvertToClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); - Assert.Equal(expectedResult, actualResult); - } + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); + Assert.Equal(expectedResult, actualResult); + } - [Theory] - [InlineData(0, 0, "medianoche")] - [InlineData(0, 7, "las doce y cinco de la noche")] - [InlineData(1, 11, "la una y diez de la madrugada")] - [InlineData(4, 0, "las cuatro de la madrugada")] - [InlineData(5, 1, "las cinco de la madrugada")] - [InlineData(6, 0, "las seis de la mañana")] - [InlineData(6, 5, "las seis y cinco de la mañana")] - [InlineData(7, 10, "las siete y diez de la mañana")] - [InlineData(8, 15, "las ocho y cuarto de la mañana")] - [InlineData(9, 20, "las nueve y veinte de la mañana")] - [InlineData(10, 25, "las diez y veinticinco de la mañana")] - [InlineData(11, 30, "las once y media de la mañana")] - [InlineData(12, 00, "mediodía")] - [InlineData(12, 38, "la una menos veinte de la tarde")] - [InlineData(12, 35, "la una menos veinticinco de la tarde")] - [InlineData(15, 40, "las cuatro menos veinte de la tarde")] - [InlineData(17, 45, "las seis menos cuarto de la tarde")] - [InlineData(19, 50, "las ocho menos diez de la tarde")] - [InlineData(21, 0, "las nueve de la noche")] - [InlineData(21, 55, "las diez menos cinco de la noche")] - [InlineData(22, 59, "las once de la noche")] - [InlineData(23, 43, "las doce menos cuarto de la noche")] - public void ConvertToRoundedClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); - Assert.Equal(expectedResult, actualResult); - } + [Theory] + [InlineData(0, 0, "medianoche")] + [InlineData(0, 7, "las doce y cinco de la noche")] + [InlineData(1, 11, "la una y diez de la madrugada")] + [InlineData(4, 0, "las cuatro de la madrugada")] + [InlineData(5, 1, "las cinco de la madrugada")] + [InlineData(6, 0, "las seis de la mañana")] + [InlineData(6, 5, "las seis y cinco de la mañana")] + [InlineData(7, 10, "las siete y diez de la mañana")] + [InlineData(8, 15, "las ocho y cuarto de la mañana")] + [InlineData(9, 20, "las nueve y veinte de la mañana")] + [InlineData(10, 25, "las diez y veinticinco de la mañana")] + [InlineData(11, 30, "las once y media de la mañana")] + [InlineData(12, 00, "mediodía")] + [InlineData(12, 38, "la una menos veinte de la tarde")] + [InlineData(12, 35, "la una menos veinticinco de la tarde")] + [InlineData(15, 40, "las cuatro menos veinte de la tarde")] + [InlineData(17, 45, "las seis menos cuarto de la tarde")] + [InlineData(19, 50, "las ocho menos diez de la tarde")] + [InlineData(21, 0, "las nueve de la noche")] + [InlineData(21, 55, "las diez menos cinco de la noche")] + [InlineData(22, 59, "las once de la noche")] + [InlineData(23, 43, "las doce menos cuarto de la noche")] + public void ConvertToRoundedClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); + Assert.Equal(expectedResult, actualResult); } } diff --git a/src/Humanizer.Tests/Localisation/fr/DateToOrdinalWordsTests.cs b/src/Humanizer.Tests/Localisation/fr/DateToOrdinalWordsTests.cs index f7eb1c7f9..3c4aa45e3 100644 --- a/src/Humanizer.Tests/Localisation/fr/DateToOrdinalWordsTests.cs +++ b/src/Humanizer.Tests/Localisation/fr/DateToOrdinalWordsTests.cs @@ -12,12 +12,12 @@ public void OrdinalizeString() } #if NET6_0_OR_GREATER - [Fact] - public void OrdinalizeDateOnlyString() - { - Assert.Equal("1er janvier 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); - Assert.Equal("2 mars 2020", new DateOnly(2020, 3, 2).ToOrdinalWords()); - Assert.Equal("31 octobre 2021", new DateOnly(2021, 10, 31).ToOrdinalWords()); - } + [Fact] + public void OrdinalizeDateOnlyString() + { + Assert.Equal("1er janvier 2015", new DateOnly(2015, 1, 1).ToOrdinalWords()); + Assert.Equal("2 mars 2020", new DateOnly(2020, 3, 2).ToOrdinalWords()); + Assert.Equal("31 octobre 2021", new DateOnly(2021, 10, 31).ToOrdinalWords()); + } #endif } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/fr/TimeOnlyHumanizeTests.cs b/src/Humanizer.Tests/Localisation/fr/TimeOnlyHumanizeTests.cs index 6cdb05af8..c3428c146 100644 --- a/src/Humanizer.Tests/Localisation/fr/TimeOnlyHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/fr/TimeOnlyHumanizeTests.cs @@ -1,72 +1,72 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.fr +namespace Humanizer.Tests.Localisation.fr; + +[UseCulture("fr")] +public class TimeOnlyHumanizeTests { - [UseCulture("fr")] - public class TimeOnlyHumanizeTests + [Fact] + public void DefaultStrategy_SameTime() { - [Fact] - public void DefaultStrategy_SameTime() - { - var inputTime = new TimeOnly(13, 07, 05); - var baseTime = new TimeOnly(13, 07, 05); - - const string expectedResult = "maintenant"; - var actualResult = inputTime.Humanize(baseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Fact] - public void DefaultStrategy_HoursApart() - { - var inputTime = new TimeOnly(3, 08, 05); - var baseTime = new TimeOnly(1, 08, 05); - - const string expectedResult = "dans 2 heures"; - var actualResult = inputTime.Humanize(baseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Fact] - public void DefaultStrategy_HoursAgo() - { - var inputTime = new TimeOnly(13, 07, 02); - var baseTime = new TimeOnly(17, 07, 05); - - const string expectedResult = "il y a 4 heures"; - var actualResult = inputTime.Humanize(baseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Fact] - public void PrecisionStrategy_NextDay() - { - var inputTime = new TimeOnly(18, 10, 49); - var baseTime = new TimeOnly(13, 07, 04); - - const string expectedResult = "dans 5 heures"; - var actualResult = inputTime.Humanize(baseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Fact] - public void Never() - { - TimeOnly? never = null; - Assert.Equal("jamais", never.Humanize()); - } - - [Fact] - public void Nullable_ExpectSame() - { - TimeOnly? never = new TimeOnly(23, 12, 7); - Assert.Equal(never.Value.Humanize(), never.Humanize()); - } + var inputTime = new TimeOnly(13, 07, 05); + var baseTime = new TimeOnly(13, 07, 05); + + const string expectedResult = "maintenant"; + var actualResult = inputTime.Humanize(baseTime); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void DefaultStrategy_HoursApart() + { + var inputTime = new TimeOnly(3, 08, 05); + var baseTime = new TimeOnly(1, 08, 05); + + const string expectedResult = "dans 2 heures"; + var actualResult = inputTime.Humanize(baseTime); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void DefaultStrategy_HoursAgo() + { + var inputTime = new TimeOnly(13, 07, 02); + var baseTime = new TimeOnly(17, 07, 05); + + const string expectedResult = "il y a 4 heures"; + var actualResult = inputTime.Humanize(baseTime); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void PrecisionStrategy_NextDay() + { + var inputTime = new TimeOnly(18, 10, 49); + var baseTime = new TimeOnly(13, 07, 04); + + const string expectedResult = "dans 5 heures"; + var actualResult = inputTime.Humanize(baseTime); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void Never() + { + TimeOnly? never = null; + Assert.Equal("jamais", never.Humanize()); + } + + [Fact] + public void Nullable_ExpectSame() + { + TimeOnly? never = new TimeOnly(23, 12, 7); + Assert.Equal(never.Value.Humanize(), never.Humanize()); } } + #endif diff --git a/src/Humanizer.Tests/Localisation/fr/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/fr/TimeSpanHumanizeTests.cs index 5aa55eb72..c313b7822 100644 --- a/src/Humanizer.Tests/Localisation/fr/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/fr/TimeSpanHumanizeTests.cs @@ -9,7 +9,9 @@ public class TimeSpanHumanizeTests [InlineData(1096, "3 ans")] [InlineData(4018, "11 ans")] public void Years(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(366, "un an")] @@ -17,7 +19,9 @@ public void Years(int days, string expected) => [InlineData(1096, "trois ans")] [InlineData(4018, "onze ans")] public void YearsToWord(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year, toWords: true)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year, toWords: true)); [Theory] [InlineData(31, "1 mois")] @@ -25,7 +29,9 @@ public void YearsToWord(int days, string expected) => [InlineData(92, "3 mois")] [InlineData(335, "11 mois")] public void Months(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(31, "un mois")] @@ -33,115 +39,141 @@ public void Months(int days, string expected) => [InlineData(92, "trois mois")] [InlineData(335, "onze mois")] public void MonthsToWords(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year, toWords: true)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year, toWords: true)); [Theory] [InlineData(14, "2 semaines")] [InlineData(7, "1 semaine")] public void Weeks(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(14, "deux semaines")] [InlineData(7, "une semaine")] public void WeeksToWords(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(6, "6 jours")] [InlineData(1, "1 jour")] public void Days(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(6, "six jours")] [InlineData(1, "un jour")] public void DaysToWords(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 heures")] [InlineData(1, "1 heure")] public void Hours(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "deux heures")] [InlineData(1, "une heure")] public void HoursToWords(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 minutes")] [InlineData(1, "1 minute")] public void Minutes(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "deux minutes")] [InlineData(1, "une minute")] public void MinutesToWords(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 secondes")] [InlineData(1, "1 seconde")] public void Seconds(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "deux secondes")] [InlineData(1, "une seconde")] public void SecondsToWords(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 millisecondes")] [InlineData(1, "1 milliseconde")] public void Milliseconds(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "deux millisecondes")] [InlineData(1, "une milliseconde")] public void MillisecondsToWords(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(toWords: true); + Assert.Equal(expected, actual); + } [Theory] [InlineData(4, false, "4 jours")] @@ -151,9 +183,11 @@ public void MillisecondsToWords(int ms, string expected) [InlineData(750, true, "deux ans")] public void Age(int days, bool toWords, string expected) { - var actual = TimeSpan.FromDays(days).ToAge(toWords: toWords); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .ToAge(toWords: toWords); + Assert.Equal(expected, actual); + } [Theory] [InlineData(TimeUnit.Year, "0 an")] @@ -166,16 +200,16 @@ public void Age(int days, bool toWords, string expected) [InlineData(TimeUnit.Millisecond, "0 milliseconde")] public void NoTime(TimeUnit minUnit, string expected) { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(minUnit: minUnit); - Assert.Equal(expected, actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(minUnit: minUnit); + Assert.Equal(expected, actual); + } [Fact] public void NoTimeToWords() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(toWords: true); - Assert.Equal("temps nul", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(toWords: true); + Assert.Equal("temps nul", actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/fr/TimeToClockNotationTests.cs b/src/Humanizer.Tests/Localisation/fr/TimeToClockNotationTests.cs index 8b2ba427d..4b555aab2 100644 --- a/src/Humanizer.Tests/Localisation/fr/TimeToClockNotationTests.cs +++ b/src/Humanizer.Tests/Localisation/fr/TimeToClockNotationTests.cs @@ -1,63 +1,62 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.fr +namespace Humanizer.Tests.Localisation.fr; + +[UseCulture("fr")] +public class TimeToClockNotationTests { - [UseCulture("fr")] - public class TimeToClockNotationTests + [Theory] + [InlineData(00, 00, "minuit")] + [InlineData(00, 07, "minuit sept")] + [InlineData(01, 11, "une heure onze")] + [InlineData(04, 00, "quatre heures")] + [InlineData(05, 01, "cinq heures une")] + [InlineData(06, 05, "six heures cinq")] + [InlineData(07, 10, "sept heures dix")] + [InlineData(08, 15, "huit heures quinze")] + [InlineData(09, 20, "neuf heures vingt")] + [InlineData(10, 25, "dix heures vingt-cinq")] + [InlineData(11, 30, "onze heures trente")] + [InlineData(12, 00, "midi")] + [InlineData(12, 38, "midi trente-huit")] + [InlineData(15, 35, "quinze heures trente-cinq")] + [InlineData(16, 40, "seize heures quarante")] + [InlineData(17, 45, "dix-sept heures quarante-cinq")] + [InlineData(18, 50, "dix-huit heures cinquante")] + [InlineData(19, 55, "dix-neuf heures cinquante-cinq")] + [InlineData(20, 59, "vingt heures cinquante-neuf")] + public void ConvertToClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) { - [Theory] - [InlineData(00, 00, "minuit")] - [InlineData(00, 07, "minuit sept")] - [InlineData(01, 11, "une heure onze")] - [InlineData(04, 00, "quatre heures")] - [InlineData(05, 01, "cinq heures une")] - [InlineData(06, 05, "six heures cinq")] - [InlineData(07, 10, "sept heures dix")] - [InlineData(08, 15, "huit heures quinze")] - [InlineData(09, 20, "neuf heures vingt")] - [InlineData(10, 25, "dix heures vingt-cinq")] - [InlineData(11, 30, "onze heures trente")] - [InlineData(12, 00, "midi")] - [InlineData(12, 38, "midi trente-huit")] - [InlineData(15, 35, "quinze heures trente-cinq")] - [InlineData(16, 40, "seize heures quarante")] - [InlineData(17, 45, "dix-sept heures quarante-cinq")] - [InlineData(18, 50, "dix-huit heures cinquante")] - [InlineData(19, 55, "dix-neuf heures cinquante-cinq")] - [InlineData(20, 59, "vingt heures cinquante-neuf")] - public void ConvertToClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); - Assert.Equal(expectedResult, actualResult); - } + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); + Assert.Equal(expectedResult, actualResult); + } - [Theory] - [InlineData(00, 00, "minuit")] - [InlineData(00, 07, "minuit cinq")] - [InlineData(01, 11, "une heure dix")] - [InlineData(04, 00, "quatre heures")] - [InlineData(05, 01, "cinq heures")] - [InlineData(06, 05, "six heures cinq")] - [InlineData(07, 10, "sept heures dix")] - [InlineData(08, 15, "huit heures quinze")] - [InlineData(09, 20, "neuf heures vingt")] - [InlineData(10, 25, "dix heures vingt-cinq")] - [InlineData(11, 30, "onze heures trente")] - [InlineData(12, 00, "midi")] - [InlineData(12, 38, "midi quarante")] - [InlineData(13, 23, "treize heures vingt-cinq")] - [InlineData(14, 32, "quatorze heures trente")] - [InlineData(15, 35, "quinze heures trente-cinq")] - [InlineData(16, 40, "seize heures quarante")] - [InlineData(17, 45, "dix-sept heures quarante-cinq")] - [InlineData(18, 50, "dix-huit heures cinquante")] - [InlineData(19, 55, "dix-neuf heures cinquante-cinq")] - [InlineData(20, 59, "vingt et une heures")] - public void ConvertToRoundedClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); - Assert.Equal(expectedResult, actualResult); - } + [Theory] + [InlineData(00, 00, "minuit")] + [InlineData(00, 07, "minuit cinq")] + [InlineData(01, 11, "une heure dix")] + [InlineData(04, 00, "quatre heures")] + [InlineData(05, 01, "cinq heures")] + [InlineData(06, 05, "six heures cinq")] + [InlineData(07, 10, "sept heures dix")] + [InlineData(08, 15, "huit heures quinze")] + [InlineData(09, 20, "neuf heures vingt")] + [InlineData(10, 25, "dix heures vingt-cinq")] + [InlineData(11, 30, "onze heures trente")] + [InlineData(12, 00, "midi")] + [InlineData(12, 38, "midi quarante")] + [InlineData(13, 23, "treize heures vingt-cinq")] + [InlineData(14, 32, "quatorze heures trente")] + [InlineData(15, 35, "quinze heures trente-cinq")] + [InlineData(16, 40, "seize heures quarante")] + [InlineData(17, 45, "dix-sept heures quarante-cinq")] + [InlineData(18, 50, "dix-huit heures cinquante")] + [InlineData(19, 55, "dix-neuf heures cinquante-cinq")] + [InlineData(20, 59, "vingt et une heures")] + public void ConvertToRoundedClockNotationTimeOnlyString(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); + Assert.Equal(expectedResult, actualResult); } } diff --git a/src/Humanizer.Tests/Localisation/is/CollectionFormatterTests.cs b/src/Humanizer.Tests/Localisation/is/CollectionFormatterTests.cs index 225b9aa3d..9a3e3c054 100644 --- a/src/Humanizer.Tests/Localisation/is/CollectionFormatterTests.cs +++ b/src/Humanizer.Tests/Localisation/is/CollectionFormatterTests.cs @@ -6,24 +6,24 @@ public class CollectionFormatterTests [Fact] public void OneItem() { - var collection = new List(new[] { 1 }); - var humanized = "1"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List([1]); + var humanized = "1"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void TwoItems() { - var collection = new List(new[] { 1, 2 }); - var humanized = "1 og 2"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List([1, 2]); + var humanized = "1 og 2"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void MoreThanTwoItems() { - var collection = new List(new[] { 1, 2, 3 }); - var humanized = "1, 2 og 3"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List([1, 2, 3]); + var humanized = "1, 2 og 3"; + Assert.Equal(humanized, collection.Humanize()); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/is/TimeOnlyHumanizeTests.cs b/src/Humanizer.Tests/Localisation/is/TimeOnlyHumanizeTests.cs index df2b5c309..b867417ae 100644 --- a/src/Humanizer.Tests/Localisation/is/TimeOnlyHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/is/TimeOnlyHumanizeTests.cs @@ -1,45 +1,44 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.@is +namespace Humanizer.Tests.Localisation.@is; + +[UseCulture("is")] +public class TimeOnlyHumanizeTests { - [UseCulture("is")] - public class TimeOnlyHumanizeTests + [Theory] + [InlineData("13:07:05", "13:07:05", "núna")] + [InlineData("13:08:05", "1:08:05", "eftir 12 klukkustundir")] + [InlineData("13:08:05", "13:38:05", "fyrir 30 mínútum")] + [InlineData("13:07:02", "17:07:05", "fyrir 4 klukkustundum")] + public void DefaultStrategy(string inputTime, string timeToCompareAgainst, string expectedResult) { - [Theory] - [InlineData("13:07:05", "13:07:05", "núna")] - [InlineData("13:08:05", "1:08:05", "eftir 12 klukkustundir")] - [InlineData("13:08:05", "13:38:05", "fyrir 30 mínútum")] - [InlineData("13:07:02", "17:07:05", "fyrir 4 klukkustundum")] - public void DefaultStrategy(string inputTime, string timeToCompareAgainst, string expectedResult) - { - Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); - - var parsedInputTime = TimeOnly.Parse(inputTime); - var parsedBaseTime = TimeOnly.Parse(timeToCompareAgainst); - var actualResult = parsedInputTime.Humanize(parsedBaseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Theory] - [InlineData("18:10:49", "13:07:04", "eftir 5 klukkustundir", 0.75)] - [InlineData("13:10:49", "13:07:04", "eftir 4 mínútur", 0.5)] - [InlineData("18:10:49", "13:07:04", "eftir 5 klukkustundir", 1.0)] - public void PrecisionStrategy(string inputTime, string timeToCompareAgainst, string expectedResult, double precision) - { - Configurator.TimeOnlyHumanizeStrategy = new PrecisionTimeOnlyHumanizeStrategy(precision); - - var parsedInputTime = TimeOnly.Parse(inputTime); - var parsedBaseTime = TimeOnly.Parse(timeToCompareAgainst); - var actualResult = parsedInputTime.Humanize(parsedBaseTime); - - Assert.Equal(expectedResult, actualResult); - } - - [Fact] - public void TestNever() => - Assert.Equal("aldrei", ((TimeOnly?)null).Humanize()); + Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); + + var parsedInputTime = TimeOnly.Parse(inputTime); + var parsedBaseTime = TimeOnly.Parse(timeToCompareAgainst); + var actualResult = parsedInputTime.Humanize(parsedBaseTime); + + Assert.Equal(expectedResult, actualResult); } + + [Theory] + [InlineData("18:10:49", "13:07:04", "eftir 5 klukkustundir", 0.75)] + [InlineData("13:10:49", "13:07:04", "eftir 4 mínútur", 0.5)] + [InlineData("18:10:49", "13:07:04", "eftir 5 klukkustundir", 1.0)] + public void PrecisionStrategy(string inputTime, string timeToCompareAgainst, string expectedResult, double precision) + { + Configurator.TimeOnlyHumanizeStrategy = new PrecisionTimeOnlyHumanizeStrategy(precision); + + var parsedInputTime = TimeOnly.Parse(inputTime); + var parsedBaseTime = TimeOnly.Parse(timeToCompareAgainst); + var actualResult = parsedInputTime.Humanize(parsedBaseTime); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void TestNever() => + Assert.Equal("aldrei", ((TimeOnly?)null).Humanize()); } #endif diff --git a/src/Humanizer.Tests/Localisation/is/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/is/TimeSpanHumanizeTests.cs index adaec0199..a9ab75819 100644 --- a/src/Humanizer.Tests/Localisation/is/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/is/TimeSpanHumanizeTests.cs @@ -128,7 +128,7 @@ public void NoTimeToWords() => [InlineData(1299630020, 5, "tvær vikur, einn dagur, ein klukkustund, þrjátíu sekúndur, tuttugu millisekúndur")] public void TimeSpanWithNumbersConvertedToWords(int milliseconds, int precision, string expected) { - var actual = TimeSpan.FromMilliseconds(milliseconds).Humanize(precision, toWords: true); - Assert.Equal(expected, actual); - } + var actual = TimeSpan.FromMilliseconds(milliseconds).Humanize(precision, toWords: true); + Assert.Equal(expected, actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/it/CollectionFormatterTests.cs b/src/Humanizer.Tests/Localisation/it/CollectionFormatterTests.cs index 5cdaa8f65..5bd89b02b 100644 --- a/src/Humanizer.Tests/Localisation/it/CollectionFormatterTests.cs +++ b/src/Humanizer.Tests/Localisation/it/CollectionFormatterTests.cs @@ -6,24 +6,24 @@ public class CollectionFormatterTests [Fact] public void OneItem() { - var collection = new List(new[] { 1 }); - var humanized = "1"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1 }); + var humanized = "1"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void TwoItems() { - var collection = new List(new[] { 1, 2 }); - var humanized = "1 e 2"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1, 2 }); + var humanized = "1 e 2"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void MoreThanTwoItems() { - var collection = new List(new[] { 1, 2, 3 }); - var humanized = "1, 2 e 3"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1, 2, 3 }); + var humanized = "1, 2 e 3"; + Assert.Equal(humanized, collection.Humanize()); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/lb/Bytes/ByteRateTests.cs b/src/Humanizer.Tests/Localisation/lb/Bytes/ByteRateTests.cs index d49320ce6..e826ab4c7 100644 --- a/src/Humanizer.Tests/Localisation/lb/Bytes/ByteRateTests.cs +++ b/src/Humanizer.Tests/Localisation/lb/Bytes/ByteRateTests.cs @@ -15,7 +15,9 @@ public void HumanizesRates(long inputBytes, double perSeconds, string expectedVa var size = new ByteSize(inputBytes); var interval = TimeSpan.FromSeconds(perSeconds); - var rate = size.Per(interval).Humanize(); + var rate = size + .Per(interval) + .Humanize(); Assert.Equal(expectedValue, rate); } @@ -62,11 +64,10 @@ public void FormattedTimeUnitTests(long bytes, int measurementIntervalSeconds, T [InlineData(TimeUnit.Year)] public void ThrowsOnUnsupportedData(TimeUnit units) { - var dummyRate = ByteSize.FromBits(1).Per(TimeSpan.FromSeconds(1)); + var dummyRate = ByteSize + .FromBits(1) + .Per(TimeSpan.FromSeconds(1)); - Assert.Throws(() => - { - dummyRate.Humanize(units); - }); + Assert.Throws(() => dummyRate.Humanize(units)); } -} +} \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/pt-BR/TimeToClockNotationTests.cs b/src/Humanizer.Tests/Localisation/pt-BR/TimeToClockNotationTests.cs index 83eb8b038..22f9a4518 100644 --- a/src/Humanizer.Tests/Localisation/pt-BR/TimeToClockNotationTests.cs +++ b/src/Humanizer.Tests/Localisation/pt-BR/TimeToClockNotationTests.cs @@ -1,57 +1,56 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests.Localisation.ptBR +namespace Humanizer.Tests.Localisation.ptBR; + +[UseCulture("pt-BR")] +public class TimeToClockNotationTests { - [UseCulture("pt-BR")] - public class TimeToClockNotationTests + [Theory] + [InlineData(00, 00, "meia-noite")] + [InlineData(04, 00, "quatro em ponto")] + [InlineData(05, 01, "cinco e um")] + [InlineData(06, 05, "seis e cinco")] + [InlineData(07, 10, "sete e dez")] + [InlineData(08, 15, "oito e quinze")] + [InlineData(09, 20, "nove e vinte")] + [InlineData(10, 25, "dez e vinte e cinco")] + [InlineData(11, 30, "onze e meia")] + [InlineData(12, 00, "meio-dia")] + [InlineData(15, 35, "três e trinta e cinco")] + [InlineData(16, 40, "vinte para as cinco")] + [InlineData(17, 45, "quinze para as seis")] + [InlineData(18, 50, "dez para as sete")] + [InlineData(19, 55, "cinco para as oito")] + [InlineData(20, 59, "oito e cinquenta e nove")] + public void ConvertToClockNotationTimeOnlyStringPtBr(int hours, int minutes, string expectedResult) { - [Theory] - [InlineData(00, 00, "meia-noite")] - [InlineData(04, 00, "quatro em ponto")] - [InlineData(05, 01, "cinco e um")] - [InlineData(06, 05, "seis e cinco")] - [InlineData(07, 10, "sete e dez")] - [InlineData(08, 15, "oito e quinze")] - [InlineData(09, 20, "nove e vinte")] - [InlineData(10, 25, "dez e vinte e cinco")] - [InlineData(11, 30, "onze e meia")] - [InlineData(12, 00, "meio-dia")] - [InlineData(15, 35, "três e trinta e cinco")] - [InlineData(16, 40, "vinte para as cinco")] - [InlineData(17, 45, "quinze para as seis")] - [InlineData(18, 50, "dez para as sete")] - [InlineData(19, 55, "cinco para as oito")] - [InlineData(20, 59, "oito e cinquenta e nove")] - public void ConvertToClockNotationTimeOnlyStringPtBr(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); - Assert.Equal(expectedResult, actualResult); - } + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); + Assert.Equal(expectedResult, actualResult); + } - [Theory] - [InlineData(00, 00, "meia-noite")] - [InlineData(04, 00, "quatro em ponto")] - [InlineData(05, 01, "cinco em ponto")] - [InlineData(06, 05, "seis e cinco")] - [InlineData(07, 10, "sete e dez")] - [InlineData(08, 15, "oito e quinze")] - [InlineData(09, 20, "nove e vinte")] - [InlineData(10, 25, "dez e vinte e cinco")] - [InlineData(11, 30, "onze e meia")] - [InlineData(12, 00, "meio-dia")] - [InlineData(13, 23, "uma e vinte e cinco")] - [InlineData(14, 32, "duas e meia")] - [InlineData(15, 35, "três e trinta e cinco")] - [InlineData(16, 40, "vinte para as cinco")] - [InlineData(17, 45, "quinze para as seis")] - [InlineData(18, 50, "dez para as sete")] - [InlineData(19, 55, "cinco para as oito")] - [InlineData(20, 59, "nove em ponto")] - public void ConvertToRoundedClockNotationTimeOnlyStringPtBr(int hours, int minutes, string expectedResult) - { - var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); - Assert.Equal(expectedResult, actualResult); - } + [Theory] + [InlineData(00, 00, "meia-noite")] + [InlineData(04, 00, "quatro em ponto")] + [InlineData(05, 01, "cinco em ponto")] + [InlineData(06, 05, "seis e cinco")] + [InlineData(07, 10, "sete e dez")] + [InlineData(08, 15, "oito e quinze")] + [InlineData(09, 20, "nove e vinte")] + [InlineData(10, 25, "dez e vinte e cinco")] + [InlineData(11, 30, "onze e meia")] + [InlineData(12, 00, "meio-dia")] + [InlineData(13, 23, "uma e vinte e cinco")] + [InlineData(14, 32, "duas e meia")] + [InlineData(15, 35, "três e trinta e cinco")] + [InlineData(16, 40, "vinte para as cinco")] + [InlineData(17, 45, "quinze para as seis")] + [InlineData(18, 50, "dez para as sete")] + [InlineData(19, 55, "cinco para as oito")] + [InlineData(20, 59, "nove em ponto")] + public void ConvertToRoundedClockNotationTimeOnlyStringPtBr(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); + Assert.Equal(expectedResult, actualResult); } } diff --git a/src/Humanizer.Tests/Localisation/ro-Ro/CollectionFormatterTests.cs b/src/Humanizer.Tests/Localisation/ro-Ro/CollectionFormatterTests.cs index 8e8aff920..99ca6f106 100644 --- a/src/Humanizer.Tests/Localisation/ro-Ro/CollectionFormatterTests.cs +++ b/src/Humanizer.Tests/Localisation/ro-Ro/CollectionFormatterTests.cs @@ -6,24 +6,24 @@ public class CollectionFormatterTests [Fact] public void OneItem() { - var collection = new List(new[] { 1 }); - var humanized = "1"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1 }); + var humanized = "1"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void TwoItems() { - var collection = new List(new[] { 1, 2 }); - var humanized = "1 și 2"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1, 2 }); + var humanized = "1 și 2"; + Assert.Equal(humanized, collection.Humanize()); + } [Fact] public void MoreThanTwoItems() { - var collection = new List(new[] { 1, 2, 3 }); - var humanized = "1, 2 și 3"; - Assert.Equal(humanized, collection.Humanize()); - } + var collection = new List(new[] { 1, 2, 3 }); + var humanized = "1, 2 și 3"; + Assert.Equal(humanized, collection.Humanize()); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/sr-Latn/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/sr-Latn/TimeSpanHumanizeTests.cs index 190336743..a71398b99 100644 --- a/src/Humanizer.Tests/Localisation/sr-Latn/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/sr-Latn/TimeSpanHumanizeTests.cs @@ -10,7 +10,9 @@ public class TimeSpanHumanizeTests [InlineData(1096, "3 godine")] [InlineData(4018, "11 godina")] public void Years(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [Trait("Translation", "Google")] @@ -19,7 +21,9 @@ public void Years(int days, string expected) => [InlineData(92, "3 meseca")] [InlineData(335, "11 meseci")] public void Months(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(35, "5 nedelja")] @@ -27,68 +31,80 @@ public void Months(int days, string expected) => [InlineData(7, "1 nedelja")] public void Weeks(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 dana")] [InlineData(1, "1 dan")] public void Days(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 sata")] [InlineData(1, "1 sat")] public void Hours(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 minuta")] [InlineData(1, "1 minut")] public void Minutes(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 sekunde")] [InlineData(1, "1 sekunda")] public void Seconds(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 milisekunde")] [InlineData(1, "1 milisekunda")] public void Milliseconds(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(); + Assert.Equal(expected, actual); + } [Fact] public void NoTime() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(); - Assert.Equal("0 milisekundi", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(); + Assert.Equal("0 milisekundi", actual); + } [Fact] public void NoTimeToWords() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(toWords: true); - Assert.Equal("bez proteklog vremena", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(toWords: true); + Assert.Equal("bez proteklog vremena", actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/sr/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/sr/TimeSpanHumanizeTests.cs index a83966021..f92a9ee12 100644 --- a/src/Humanizer.Tests/Localisation/sr/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/sr/TimeSpanHumanizeTests.cs @@ -10,7 +10,9 @@ public class TimeSpanHumanizeTests [InlineData(1096, "3 године")] [InlineData(4018, "11 година")] public void Years(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [Trait("Translation", "Google")] @@ -19,7 +21,9 @@ public void Years(int days, string expected) => [InlineData(92, "3 месеца")] [InlineData(335, "11 месеци")] public void Months(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(35, "5 недеља")] @@ -27,9 +31,11 @@ public void Months(int days, string expected) => [InlineData(7, "1 недеља")] public void Weeks(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(6, "6 дана")] @@ -37,9 +43,11 @@ public void Weeks(int days, string expected) [InlineData(1, "1 дан")] public void Days(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(5, "5 сати")] @@ -47,50 +55,58 @@ public void Days(int days, string expected) [InlineData(1, "1 сат")] public void Hours(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 минута")] [InlineData(1, "1 минут")] public void Minutes(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 секунде")] [InlineData(1, "1 секунда")] public void Seconds(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 милисекунде")] [InlineData(1, "1 милисекунда")] public void Milliseconds(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(); + Assert.Equal(expected, actual); + } [Fact] public void NoTime() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(); - Assert.Equal("0 милисекунди", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(); + Assert.Equal("0 милисекунди", actual); + } [Fact] public void NoTimeToWords() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(toWords: true); - Assert.Equal("без протеклог времена", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(toWords: true); + Assert.Equal("без протеклог времена", actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/vi/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/vi/TimeSpanHumanizeTests.cs index 4af882eab..b45b23f97 100644 --- a/src/Humanizer.Tests/Localisation/vi/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/vi/TimeSpanHumanizeTests.cs @@ -10,7 +10,9 @@ public class TimeSpanHumanizeTests [InlineData(1096, "3 năm")] [InlineData(4018, "11 năm")] public void Years(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [Trait("Translation", "Google")] @@ -19,75 +21,89 @@ public void Years(int days, string expected) => [InlineData(92, "3 tháng")] [InlineData(335, "11 tháng")] public void Months(int days, string expected) => - Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year)); + Assert.Equal(expected, TimeSpan + .FromDays(days) + .Humanize(maxUnit: TimeUnit.Year)); [Theory] [InlineData(14, "2 tuần")] [InlineData(7, "1 tuần")] public void Weeks(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 ngày")] [InlineData(1, "1 ngày")] public void Days(int days, string expected) { - var actual = TimeSpan.FromDays(days).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromDays(days) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 giờ")] [InlineData(1, "1 giờ")] public void Hours(int hours, string expected) { - var actual = TimeSpan.FromHours(hours).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromHours(hours) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 phút")] [InlineData(1, "1 phút")] public void Minutes(int minutes, string expected) { - var actual = TimeSpan.FromMinutes(minutes).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMinutes(minutes) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 giây")] [InlineData(1, "1 giây")] public void Seconds(int seconds, string expected) { - var actual = TimeSpan.FromSeconds(seconds).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromSeconds(seconds) + .Humanize(); + Assert.Equal(expected, actual); + } [Theory] [InlineData(2, "2 phần ngàn giây")] [InlineData(1, "1 phần ngàn giây")] public void Milliseconds(int ms, string expected) { - var actual = TimeSpan.FromMilliseconds(ms).Humanize(); - Assert.Equal(expected, actual); - } + var actual = TimeSpan + .FromMilliseconds(ms) + .Humanize(); + Assert.Equal(expected, actual); + } [Fact] public void NoTime() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(); - Assert.Equal("0 phần ngàn giây", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(); + Assert.Equal("0 phần ngàn giây", actual); + } [Fact] public void NoTimeToWords() { - var noTime = TimeSpan.Zero; - var actual = noTime.Humanize(toWords: true); - Assert.Equal("không giờ", actual); - } + var noTime = TimeSpan.Zero; + var actual = noTime.Humanize(toWords: true); + Assert.Equal("không giờ", actual); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/MetricNumeralTests.cs b/src/Humanizer.Tests/MetricNumeralTests.cs index ffda65ee4..5814b57d9 100644 --- a/src/Humanizer.Tests/MetricNumeralTests.cs +++ b/src/Humanizer.Tests/MetricNumeralTests.cs @@ -4,7 +4,12 @@ public class MetricNumeralTests { // Return a sequence of -24 -> 26 - public static IEnumerable SymbolRange => Enumerable.Range(-24, 51).Select(e => new object[] { e }); + public static IEnumerable SymbolRange => Enumerable + .Range(-24, 51) + .Select(e => new object[] + { + e + }); [Theory] [InlineData(0, "0")] @@ -39,16 +44,16 @@ public void FromMetricOnNull() => [MemberData(nameof(SymbolRange))] public void TestAllSymbols(int e) { - var origin = Math.Pow(10, e); - var to = origin.ToMetric(); - var from = to.FromMetric(); + var origin = Math.Pow(10, e); + var to = origin.ToMetric(); + var from = to.FromMetric(); - var c = Equals( - origin.ToString("0.##E+0", CultureInfo.InvariantCulture), - from.ToString("0.##E+0", CultureInfo.InvariantCulture)); + var c = Equals( + origin.ToString("0.##E+0", CultureInfo.InvariantCulture), + from.ToString("0.##E+0", CultureInfo.InvariantCulture)); - Assert.True(c); - } + Assert.True(c); + } [Theory] [InlineData(-9)] @@ -62,20 +67,21 @@ public void TestAllSymbols(int e) [InlineData(9)] public void TestAllSymbolsAsInt(int exponent) { - var origin = Convert.ToInt32(Math.Pow(10, exponent)); - var isEquals = Equals( - origin.ToString("0.##E+0", CultureInfo.InvariantCulture), - origin.ToMetric() - .FromMetric() - .ToString("0.##E+0", CultureInfo.InvariantCulture)); - if (!isEquals) - { - Debugger.Break(); - } - - Assert.True(isEquals); + var origin = Convert.ToInt32(Math.Pow(10, exponent)); + var isEquals = Equals( + origin.ToString("0.##E+0", CultureInfo.InvariantCulture), + origin + .ToMetric() + .FromMetric() + .ToString("0.##E+0", CultureInfo.InvariantCulture)); + if (!isEquals) + { + Debugger.Break(); } + Assert.True(isEquals); + } + [Theory] [InlineData("1.3M", 1300000, null, null)] [InlineData("1.3million", 1300000, MetricNumeralFormats.UseShortScaleWord, null)] diff --git a/src/Humanizer.Tests/NumberToNumberTests.cs b/src/Humanizer.Tests/NumberToNumberTests.cs index 091515738..c551de118 100644 --- a/src/Humanizer.Tests/NumberToNumberTests.cs +++ b/src/Humanizer.Tests/NumberToNumberTests.cs @@ -5,175 +5,175 @@ public class NumberToNumberTests [Fact] public void IntToTens() { - const int number = 1; - Assert.Equal(10, number.Tens()); - } + const int number = 1; + Assert.Equal(10, number.Tens()); + } [Fact] public void UintToTens() { - const uint number = 1; - Assert.Equal(10U, number.Tens()); - } + const uint number = 1; + Assert.Equal(10U, number.Tens()); + } [Fact] public void LongToTens() { - const long number = 1; - Assert.Equal(10L, number.Tens()); - } + const long number = 1; + Assert.Equal(10L, number.Tens()); + } [Fact] public void UlongToTens() { - const ulong number = 1; - Assert.Equal(10UL, number.Tens()); - } + const ulong number = 1; + Assert.Equal(10UL, number.Tens()); + } [Fact] public void DoubleToTens() { - const double number = 1; - Assert.Equal(10d, number.Tens()); - } + const double number = 1; + Assert.Equal(10d, number.Tens()); + } [Fact] public void IntToHundreds() { - const int number = 2; - Assert.Equal(200, number.Hundreds()); - } + const int number = 2; + Assert.Equal(200, number.Hundreds()); + } [Fact] public void UintToHundreds() { - const uint number = 2; - Assert.Equal(200U, number.Hundreds()); - } + const uint number = 2; + Assert.Equal(200U, number.Hundreds()); + } [Fact] public void LongToHundreds() { - const long number = 2; - Assert.Equal(200L, number.Hundreds()); - } + const long number = 2; + Assert.Equal(200L, number.Hundreds()); + } [Fact] public void UlongToHundreds() { - const ulong number = 2; - Assert.Equal(200UL, number.Hundreds()); - } + const ulong number = 2; + Assert.Equal(200UL, number.Hundreds()); + } [Fact] public void DoubleToHundreds() { - const double number = 2; - Assert.Equal(200d, number.Hundreds()); - } + const double number = 2; + Assert.Equal(200d, number.Hundreds()); + } [Fact] public void IntToThousands() { - const int number = 3; - Assert.Equal(3000, number.Thousands()); - } + const int number = 3; + Assert.Equal(3000, number.Thousands()); + } [Fact] public void UintToThousands() { - const uint number = 3; - Assert.Equal(3000U, number.Thousands()); - } + const uint number = 3; + Assert.Equal(3000U, number.Thousands()); + } [Fact] public void LongToThousands() { - const long number = 3; - Assert.Equal(3000L, number.Thousands()); - } + const long number = 3; + Assert.Equal(3000L, number.Thousands()); + } [Fact] public void UlongToThousands() { - const ulong number = 3; - Assert.Equal(3000UL, number.Thousands()); - } + const ulong number = 3; + Assert.Equal(3000UL, number.Thousands()); + } [Fact] public void DoubleToThousands() { - const double number = 3; - Assert.Equal(3000d, number.Thousands()); - } + const double number = 3; + Assert.Equal(3000d, number.Thousands()); + } [Fact] public void IntToMillions() { - const int number = 4; - Assert.Equal(4000000, number.Millions()); - } + const int number = 4; + Assert.Equal(4000000, number.Millions()); + } [Fact] public void UintToMillions() { - const uint number = 4; - Assert.Equal(4000000U, number.Millions()); - } + const uint number = 4; + Assert.Equal(4000000U, number.Millions()); + } [Fact] public void LongToMillions() { - const long number = 4; - Assert.Equal(4000000L, number.Millions()); - } + const long number = 4; + Assert.Equal(4000000L, number.Millions()); + } [Fact] public void UlongToMillions() { - const ulong number = 4; - Assert.Equal(4000000UL, number.Millions()); - } + const ulong number = 4; + Assert.Equal(4000000UL, number.Millions()); + } [Fact] public void DoubleToMillions() { - const double number = 4; - Assert.Equal(4000000d, number.Millions()); - } + const double number = 4; + Assert.Equal(4000000d, number.Millions()); + } [Fact] public void IntToBillions() { - const int number = 1; - Assert.Equal(1000000000, number.Billions()); - } + const int number = 1; + Assert.Equal(1000000000, number.Billions()); + } [Fact] public void UintToBillions() { - const uint number = 1; - Assert.Equal(1000000000U, number.Billions()); - } + const uint number = 1; + Assert.Equal(1000000000U, number.Billions()); + } [Fact] public void LongToBillions() { - const long number = 1; - Assert.Equal(1000000000L, number.Billions()); - } + const long number = 1; + Assert.Equal(1000000000L, number.Billions()); + } [Fact] public void UlongToBillions() { - const ulong number = 1; - Assert.Equal(1000000000UL, number.Billions()); - } + const ulong number = 1; + Assert.Equal(1000000000UL, number.Billions()); + } [Fact] public void DoubleToBillions() { - const double number = 1; - Assert.Equal(1000000000d, number.Billions()); - } + const double number = 1; + Assert.Equal(1000000000d, number.Billions()); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/NumberToTimeSpanTests.cs b/src/Humanizer.Tests/NumberToTimeSpanTests.cs index a24508c2d..7684cf408 100644 --- a/src/Humanizer.Tests/NumberToTimeSpanTests.cs +++ b/src/Humanizer.Tests/NumberToTimeSpanTests.cs @@ -5,344 +5,344 @@ public class NumberToTimeSpanTests [Fact] public void ByteToMilliseconds() { - const byte number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const byte number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void SbyteToMilliseconds() { - const sbyte number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const sbyte number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void ShortToMilliseconds() { - const short number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const short number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void UshortToMilliseconds() { - const ushort number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const ushort number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void IntToMilliseconds() { - const int number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const int number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void UintToMilliseconds() { - const uint number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const uint number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void LongToMilliseconds() { - const long number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const long number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void UlongToMilliseconds() { - const ulong number = 1; - Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); - } + const ulong number = 1; + Assert.Equal(new(0, 0, 0, 0, 1), number.Milliseconds()); + } [Fact] public void ByteToMinutes() { - const byte number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const byte number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void SbyteToMinutes() { - const sbyte number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const sbyte number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void ShortToMinutes() { - const short number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const short number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void UshortToMinutes() { - const ushort number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const ushort number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void IntToMinutes() { - const int number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const int number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void UintToMinutes() { - const uint number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const uint number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void LongToMinutes() { - const long number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const long number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void UlongToMinutes() { - const ulong number = 2; - Assert.Equal(new(0, 0, 2, 0), number.Minutes()); - } + const ulong number = 2; + Assert.Equal(new(0, 0, 2, 0), number.Minutes()); + } [Fact] public void ByteToSeconds() { - const byte number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const byte number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void SbyteToSeconds() { - const sbyte number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const sbyte number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void ShortToSeconds() { - const short number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const short number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void UshortToSeconds() { - const ushort number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const ushort number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void IntToSeconds() { - const int number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const int number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void UintToSeconds() { - const uint number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const uint number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void LongToSeconds() { - const long number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const long number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void UlongToSeconds() { - const ulong number = 3; - Assert.Equal(new(0, 0, 0, 3), number.Seconds()); - } + const ulong number = 3; + Assert.Equal(new(0, 0, 0, 3), number.Seconds()); + } [Fact] public void ByteToHours() { - const byte number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const byte number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void SbyteToHours() { - const sbyte number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const sbyte number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void ShortToHours() { - const short number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const short number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void UshortToHours() { - const ushort number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const ushort number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void IntToHours() { - const int number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const int number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void UintToHours() { - const uint number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const uint number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void LongToHours() { - const long number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const long number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void UlongToHours() { - const ulong number = 4; - Assert.Equal(new(0, 4, 0, 0), number.Hours()); - } + const ulong number = 4; + Assert.Equal(new(0, 4, 0, 0), number.Hours()); + } [Fact] public void ByteToDays() { - const byte number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const byte number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void SbyteToDays() { - const sbyte number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const sbyte number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void ShortToDays() { - const short number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const short number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void UshortToDays() { - const ushort number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const ushort number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void IntToDays() { - const int number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const int number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void UintToDays() { - const uint number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const uint number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void LongToDays() { - const long number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const long number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void UlongToDays() { - const ulong number = 5; - Assert.Equal(new(5, 0, 0, 0), number.Days()); - } + const ulong number = 5; + Assert.Equal(new(5, 0, 0, 0), number.Days()); + } [Fact] public void ByteToWeeks() { - const byte number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const byte number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void SbyteToWeeks() { - const sbyte number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const sbyte number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void ShortToWeeks() { - const short number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const short number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void UshortToWeeks() { - const ushort number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const ushort number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void IntToWeeks() { - const int number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const int number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void UintToWeeks() { - const uint number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const uint number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void LongToWeeks() { - const long number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const long number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } [Fact] public void UlongToWeeks() { - const ulong number = 6; - var now = DateTime.Now; - Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); - } + const ulong number = 6; + var now = DateTime.Now; + Assert.Equal(now.AddDays(42), now.Add(number.Weeks())); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/NumberToWordsTests.cs b/src/Humanizer.Tests/NumberToWordsTests.cs index f67690625..48b4baa2e 100644 --- a/src/Humanizer.Tests/NumberToWordsTests.cs +++ b/src/Humanizer.Tests/NumberToWordsTests.cs @@ -63,15 +63,21 @@ public void ToOrdinalWords_CanSpecifyCultureExplicitly(int number, string cultur [InlineData(3, "third")] public void ToOrdinalWords_WordFormIsIgnored(int number, string expected) { - var normalForm1 = number.ToOrdinalWords(WordForm.Normal); - var abbrForm1 = number.ToOrdinalWords(WordForm.Abbreviation); - var normalForm2 = number.ToOrdinalWords(default, WordForm.Normal); - var abbrForm2 = number.ToOrdinalWords(default, WordForm.Abbreviation); - - Assert.All( - new[] { normalForm1, abbrForm1, normalForm2, abbrForm2 }, - item => Assert.Equal(expected, item)); - } + var normalForm1 = number.ToOrdinalWords(WordForm.Normal); + var abbrForm1 = number.ToOrdinalWords(WordForm.Abbreviation); + var normalForm2 = number.ToOrdinalWords(default, WordForm.Normal); + var abbrForm2 = number.ToOrdinalWords(default, WordForm.Abbreviation); + + Assert.All( + new[] + { + normalForm1, + abbrForm1, + normalForm2, + abbrForm2 + }, + item => Assert.Equal(expected, item)); + } [Theory] [InlineData(1, "en-US", "first")] @@ -82,18 +88,25 @@ public void ToOrdinalWords_WordFormIsIgnored(int number, string expected) [InlineData(3, "ko-KR", "세번째")] public void ToOrdinalWords_WordFormIsIgnoredWithSpecificCulture(int number, string culture, string expected) { - var cultureInfo = new CultureInfo(culture); - - var cultureSpecificNumber = number.ToOrdinalWords(cultureInfo); - var normalForm1 = number.ToOrdinalWords(WordForm.Normal, cultureInfo); - var abbrForm1 = number.ToOrdinalWords(WordForm.Abbreviation, cultureInfo); - var normalForm2 = number.ToOrdinalWords(default, WordForm.Normal, cultureInfo); - var abbrForm2 = number.ToOrdinalWords(default, WordForm.Abbreviation, cultureInfo); - - Assert.All( - new[] { cultureSpecificNumber, normalForm1, abbrForm1, normalForm2, abbrForm2 }, - item => Assert.Equal(expected, item)); - } + var cultureInfo = new CultureInfo(culture); + + var cultureSpecificNumber = number.ToOrdinalWords(cultureInfo); + var normalForm1 = number.ToOrdinalWords(WordForm.Normal, cultureInfo); + var abbrForm1 = number.ToOrdinalWords(WordForm.Abbreviation, cultureInfo); + var normalForm2 = number.ToOrdinalWords(default, WordForm.Normal, cultureInfo); + var abbrForm2 = number.ToOrdinalWords(default, WordForm.Abbreviation, cultureInfo); + + Assert.All( + new[] + { + cultureSpecificNumber, + normalForm1, + abbrForm1, + normalForm2, + abbrForm2 + }, + item => Assert.Equal(expected, item)); + } [Theory] [InlineData(0, "0-tuple")] @@ -128,17 +141,26 @@ public void ToWords_CanSpecifyCultureExplicitly(int number, string culture, stri [InlineData(3, "three")] public void ToWords_WordFormIsIgnored(int number, string expected) { - var normalForm1 = number.ToWords(WordForm.Normal); - var abbrForm1 = number.ToWords(WordForm.Abbreviation); - var normalForm2 = number.ToWords(addAnd: true, WordForm.Normal); - var abbrForm2 = number.ToWords(addAnd: true, WordForm.Abbreviation); - var normalForm3 = ((long)number).ToWords(WordForm.Normal, default(GrammaticalGender)); - var abbrFrom3 = ((long)number).ToWords(WordForm.Abbreviation, default(GrammaticalGender)); - - Assert.All( - new[] { normalForm1, abbrForm1, normalForm2, abbrForm2, normalForm3, normalForm3, abbrFrom3 }, - item => Assert.Equal(expected, item)); - } + var normalForm1 = number.ToWords(WordForm.Normal); + var abbrForm1 = number.ToWords(WordForm.Abbreviation); + var normalForm2 = number.ToWords(addAnd: true, WordForm.Normal); + var abbrForm2 = number.ToWords(addAnd: true, WordForm.Abbreviation); + var normalForm3 = ((long) number).ToWords(WordForm.Normal, default(GrammaticalGender)); + var abbrFrom3 = ((long) number).ToWords(WordForm.Abbreviation, default(GrammaticalGender)); + + Assert.All( + new[] + { + normalForm1, + abbrForm1, + normalForm2, + abbrForm2, + normalForm3, + normalForm3, + abbrFrom3 + }, + item => Assert.Equal(expected, item)); + } [Theory] [InlineData(1, "en-US", "one")] @@ -149,18 +171,25 @@ public void ToWords_WordFormIsIgnored(int number, string expected) [InlineData(3, "ko-KR", "삼")] public void ToWords_WordFormIsIgnoredWithSpecificCulture(int number, string culture, string expected) { - var cultureInfo = new CultureInfo(culture); - - var cultureSpecificNumber = number.ToWords(cultureInfo); - var normalForm1 = number.ToWords(addAnd: true, WordForm.Normal, cultureInfo); - var abbrForm1 = number.ToWords(addAnd: true, WordForm.Abbreviation, cultureInfo); - var normalForm2 = ((long)number).ToWords(WordForm.Normal, default(GrammaticalGender), cultureInfo); - var abbrForm2 = ((long)number).ToWords(WordForm.Abbreviation, default(GrammaticalGender), cultureInfo); - - Assert.All( - new[] { cultureSpecificNumber, normalForm1, abbrForm1, normalForm2, abbrForm2 }, - item => Assert.Equal(expected, item)); - } + var cultureInfo = new CultureInfo(culture); + + var cultureSpecificNumber = number.ToWords(cultureInfo); + var normalForm1 = number.ToWords(addAnd: true, WordForm.Normal, cultureInfo); + var abbrForm1 = number.ToWords(addAnd: true, WordForm.Abbreviation, cultureInfo); + var normalForm2 = ((long) number).ToWords(WordForm.Normal, default(GrammaticalGender), cultureInfo); + var abbrForm2 = ((long) number).ToWords(WordForm.Abbreviation, default(GrammaticalGender), cultureInfo); + + Assert.All( + new[] + { + cultureSpecificNumber, + normalForm1, + abbrForm1, + normalForm2, + abbrForm2 + }, + item => Assert.Equal(expected, item)); + } [Theory] [InlineData(-1, "minus one")] diff --git a/src/Humanizer.Tests/OrdinalizeTests.cs b/src/Humanizer.Tests/OrdinalizeTests.cs index be789535e..dcffcf3ab 100644 --- a/src/Humanizer.Tests/OrdinalizeTests.cs +++ b/src/Humanizer.Tests/OrdinalizeTests.cs @@ -73,10 +73,10 @@ public void OrdinalizeNumber(int number, string ordinalized) => [InlineData(8)] public void OrdinalizeNumberGenderIsImmaterial(int number) { - var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine); - var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine); - Assert.Equal(masculineOrdinalized, feminineOrdinalized); - } + var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine); + var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine); + Assert.Equal(masculineOrdinalized, feminineOrdinalized); + } [Theory] [InlineData("0")] @@ -84,28 +84,28 @@ public void OrdinalizeNumberGenderIsImmaterial(int number) [InlineData("8")] public void OrdinalizeStringGenderIsImmaterial(string number) { - var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine); - var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine); - Assert.Equal(masculineOrdinalized, feminineOrdinalized); - } + var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine); + var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine); + Assert.Equal(masculineOrdinalized, feminineOrdinalized); + } [Theory] [InlineData("en-US", "1", "1st")] [InlineData("nl-NL", "1", "1e")] public void OrdinalizeStringWithCultureOverridesCurrentCulture(string cultureName, string number, string ordinalized) { - var culture = new CultureInfo(cultureName); - Assert.Equal(number.Ordinalize(culture), ordinalized); - } + var culture = new CultureInfo(cultureName); + Assert.Equal(number.Ordinalize(culture), ordinalized); + } [Theory] [InlineData("en-US", 1, "1st")] [InlineData("nl-NL", 1, "1e")] public void OrdinalizeNumberWithCultureOverridesCurrentCulture(string cultureName, int number, string ordinalized) { - var culture = new CultureInfo(cultureName); - Assert.Equal(number.Ordinalize(culture), ordinalized); - } + var culture = new CultureInfo(cultureName); + Assert.Equal(number.Ordinalize(culture), ordinalized); + } [Theory] [InlineData(0)] @@ -113,11 +113,11 @@ public void OrdinalizeNumberWithCultureOverridesCurrentCulture(string cultureNam [InlineData(8)] public void OrdinalizeNumberWithOverridenCultureGenderIsImmaterial(int number) { - var culture = new CultureInfo("nl-NL"); - var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine, culture); - var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine, culture); - Assert.Equal(masculineOrdinalized, feminineOrdinalized); - } + var culture = new CultureInfo("nl-NL"); + var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine, culture); + var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine, culture); + Assert.Equal(masculineOrdinalized, feminineOrdinalized); + } [Theory] [InlineData("0")] @@ -125,11 +125,11 @@ public void OrdinalizeNumberWithOverridenCultureGenderIsImmaterial(int number) [InlineData("8")] public void OrdinalizeStringWithOverridenGenderIsImmaterial(string number) { - var culture = new CultureInfo("nl-NL"); - var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine, culture); - var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine, culture); - Assert.Equal(masculineOrdinalized, feminineOrdinalized); - } + var culture = new CultureInfo("nl-NL"); + var masculineOrdinalized = number.Ordinalize(GrammaticalGender.Masculine, culture); + var feminineOrdinalized = number.Ordinalize(GrammaticalGender.Feminine, culture); + Assert.Equal(masculineOrdinalized, feminineOrdinalized); + } [Theory] [InlineData(1, WordForm.Normal, "es-ES", "1.º")] @@ -138,10 +138,12 @@ public void OrdinalizeStringWithOverridenGenderIsImmaterial(string number) [InlineData(1, WordForm.Abbreviation, "en-US", "1st")] public void OrdinalizeNumberWithOverridenCultureAndSpecificForm(int number, WordForm wordForm, string cultureName, string expected) { - var culture = new CultureInfo(cultureName); - Assert.Equal(expected, number.Ordinalize(culture, wordForm)); - Assert.Equal(expected, number.ToString(culture).Ordinalize(culture, wordForm)); - } + var culture = new CultureInfo(cultureName); + Assert.Equal(expected, number.Ordinalize(culture, wordForm)); + Assert.Equal(expected, number + .ToString(culture) + .Ordinalize(culture, wordForm)); + } [Theory] [InlineData(1, WordForm.Normal, GrammaticalGender.Masculine, "es-ES", "1.º")] @@ -157,8 +159,10 @@ public void OrdinalizeNumberWithOverridenCultureAndGenderAndForm( string cultureName, string expected) { - var culture = new CultureInfo(cultureName); - Assert.Equal(expected, number.Ordinalize(gender, culture, wordForm)); - Assert.Equal(expected, number.ToString(culture).Ordinalize(gender, culture, wordForm)); - } + var culture = new CultureInfo(cultureName); + Assert.Equal(expected, number.Ordinalize(gender, culture, wordForm)); + Assert.Equal(expected, number + .ToString(culture) + .Ordinalize(gender, culture, wordForm)); + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/TimeOnlyHumanizeTests.cs b/src/Humanizer.Tests/TimeOnlyHumanizeTests.cs index cacf68cff..9d321a859 100644 --- a/src/Humanizer.Tests/TimeOnlyHumanizeTests.cs +++ b/src/Humanizer.Tests/TimeOnlyHumanizeTests.cs @@ -1,80 +1,79 @@ #if NET6_0_OR_GREATER -namespace Humanizer.Tests +namespace Humanizer.Tests; + +[UseCulture("en-US")] +public class TimeOnlyHumanizeTests { - [UseCulture("en-US")] - public class TimeOnlyHumanizeTests + [Fact] + public void DefaultStrategy_SameTime() { - [Fact] - public void DefaultStrategy_SameTime() - { - Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); + Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); - var inputTime = new TimeOnly(13, 07, 05); - var baseTime = new TimeOnly(13, 07, 05); + var inputTime = new TimeOnly(13, 07, 05); + var baseTime = new TimeOnly(13, 07, 05); - const string expectedResult = "now"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "now"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void DefaultStrategy_HoursApart() - { - Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); + [Fact] + public void DefaultStrategy_HoursApart() + { + Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); - var inputTime = new TimeOnly(13, 08, 05); - var baseTime = new TimeOnly(1, 08, 05); + var inputTime = new TimeOnly(13, 08, 05); + var baseTime = new TimeOnly(1, 08, 05); - const string expectedResult = "12 hours from now"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "12 hours from now"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void DefaultStrategy_HoursAgo() - { - Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); + [Fact] + public void DefaultStrategy_HoursAgo() + { + Configurator.TimeOnlyHumanizeStrategy = new DefaultTimeOnlyHumanizeStrategy(); - var inputTime = new TimeOnly(13, 07, 02); - var baseTime = new TimeOnly(17, 07, 05); + var inputTime = new TimeOnly(13, 07, 02); + var baseTime = new TimeOnly(17, 07, 05); - const string expectedResult = "4 hours ago"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "4 hours ago"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void PrecisionStrategy_NextDay() - { - Configurator.TimeOnlyHumanizeStrategy = new PrecisionTimeOnlyHumanizeStrategy(0.75); + [Fact] + public void PrecisionStrategy_NextDay() + { + Configurator.TimeOnlyHumanizeStrategy = new PrecisionTimeOnlyHumanizeStrategy(0.75); - var inputTime = new TimeOnly(18, 10, 49); - var baseTime = new TimeOnly(13, 07, 04); + var inputTime = new TimeOnly(18, 10, 49); + var baseTime = new TimeOnly(13, 07, 04); - const string expectedResult = "5 hours from now"; - var actualResult = inputTime.Humanize(baseTime); + const string expectedResult = "5 hours from now"; + var actualResult = inputTime.Humanize(baseTime); - Assert.Equal(expectedResult, actualResult); - } + Assert.Equal(expectedResult, actualResult); + } - [Fact] - public void Never() - { - TimeOnly? never = null; - Assert.Equal("never", never.Humanize()); - } + [Fact] + public void Never() + { + TimeOnly? never = null; + Assert.Equal("never", never.Humanize()); + } - [Fact] - public void Nullable_ExpectSame() - { - TimeOnly? never = new TimeOnly(23, 12, 7); + [Fact] + public void Nullable_ExpectSame() + { + TimeOnly? never = new TimeOnly(23, 12, 7); - Assert.Equal(never.Value.Humanize(), never.Humanize()); - } + Assert.Equal(never.Value.Humanize(), never.Humanize()); } } diff --git a/src/Humanizer.Tests/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/TimeSpanHumanizeTests.cs index bbc9ec15c..04f9fb760 100644 --- a/src/Humanizer.Tests/TimeSpanHumanizeTests.cs +++ b/src/Humanizer.Tests/TimeSpanHumanizeTests.cs @@ -448,6 +448,7 @@ public void CanSpecifyCultureExplicitly(int ms, int precision, string culture, s var actual = TimeSpan.FromMilliseconds(ms).Humanize(precision: precision, culture: new(culture), collectionSeparator: collectionSeparator); Assert.Equal(expected, actual); } + [Theory] [InlineData(31 * 4, 1, "en-US", "four months")] [InlineData(236, 2, "ar", "سبعة أشهر, اثنان و عشرون يوم")] diff --git a/src/Humanizer/ArticlePrefixSort.cs b/src/Humanizer/ArticlePrefixSort.cs index 03ef2e0a2..993724e4e 100644 --- a/src/Humanizer/ArticlePrefixSort.cs +++ b/src/Humanizer/ArticlePrefixSort.cs @@ -14,31 +14,38 @@ public static class EnglishArticle /// Sorted string array public static string[] AppendArticlePrefix(string[] items) { - if (items.Length == 0) + if (items.Length == 0) + { + throw new ArgumentOutOfRangeException(nameof(items)); + } + + var transformed = new string[items.Length]; + + for (var i = 0; i < items.Length; i++) + { + var item = items[i] + .AsSpan(); + if (_regex.IsMatch(item)) { - throw new ArgumentOutOfRangeException(nameof(items)); + var indexOf = item.IndexOf(' '); + var removed = item[indexOf..] + .TrimStart(); + var article = item[..indexOf] + .TrimEnd(); + transformed[i] = $"{removed} {article}"; } - var transformed = new string[items.Length]; - - for (var i = 0; i < items.Length; i++) + else { - var item = items[i].AsSpan(); - if (_regex.IsMatch(item)) - { - var indexOf = item.IndexOf(' '); - var removed = item[indexOf..].TrimStart(); - var article = item[..indexOf].TrimEnd(); - transformed[i] = $"{removed} {article}"; - } - else - { - transformed[i] = item.Trim().ToString(); - } + transformed[i] = item + .Trim() + .ToString(); } - Array.Sort(transformed); - return transformed; } + Array.Sort(transformed); + return transformed; + } + /// /// Removes the previously appended article and prepends it to the same string. /// @@ -46,34 +53,36 @@ public static string[] AppendArticlePrefix(string[] items) /// String array public static string[] PrependArticleSuffix(string[] appended) { - var inserted = new string[appended.Length]; - var the = " the".AsSpan(); - var an = " an".AsSpan(); - var a = " a".AsSpan(); + var inserted = new string[appended.Length]; + var the = " the".AsSpan(); + var an = " an".AsSpan(); + var a = " a".AsSpan(); - for (var i = 0; i < appended.Length; i++) + for (var i = 0; i < appended.Length; i++) + { + var append = appended[i] + .AsSpan(); + if (append.EndsWith(the, StringComparison.OrdinalIgnoreCase)) + { + inserted[i] = ToOriginalFormat(append, 3); + } + else if (append.EndsWith(an, StringComparison.OrdinalIgnoreCase)) + { + inserted[i] = ToOriginalFormat(append, 2); + } + else if (append.EndsWith(a, StringComparison.OrdinalIgnoreCase)) { - var append = appended[i].AsSpan(); - if (append.EndsWith(the, StringComparison.OrdinalIgnoreCase)) - { - inserted[i] = ToOriginalFormat(append, 3); - } - else if (append.EndsWith(an, StringComparison.OrdinalIgnoreCase)) - { - inserted[i] = ToOriginalFormat(append, 2); - } - else if (append.EndsWith(a, StringComparison.OrdinalIgnoreCase)) - { - inserted[i] = ToOriginalFormat(append, 1); - } - else - { - inserted[i] = appended[i]; - } + inserted[i] = ToOriginalFormat(append, 1); + } + else + { + inserted[i] = appended[i]; } - return inserted; } + return inserted; + } + static string ToOriginalFormat(CharSpan value, int suffixLength) => $"{value[^suffixLength..]} {value[..^(suffixLength + 1)]}"; } \ No newline at end of file diff --git a/src/Humanizer/Bytes/ByteRate.cs b/src/Humanizer/Bytes/ByteRate.cs index 640e85e18..f4e512cae 100644 --- a/src/Humanizer/Bytes/ByteRate.cs +++ b/src/Humanizer/Bytes/ByteRate.cs @@ -20,9 +20,9 @@ public class ByteRate /// public ByteRate(ByteSize size, TimeSpan interval) { - this.Size = size; - this.Interval = interval; - } + this.Size = size; + this.Interval = interval; + } /// /// Calculate rate for the quantity of bytes and interval defined by this instance @@ -39,14 +39,14 @@ public string Humanize(TimeUnit timeUnit = TimeUnit.Second) => /// Culture to use. If null, current thread's UI culture is used. public string Humanize(string? format, TimeUnit timeUnit = TimeUnit.Second, CultureInfo? culture = null) { - var displayInterval = timeUnit switch - { - TimeUnit.Second => TimeSpan.FromSeconds(1), - TimeUnit.Minute => TimeSpan.FromMinutes(1), - TimeUnit.Hour => TimeSpan.FromHours(1), - _ => throw new NotSupportedException("timeUnit must be Second, Minute, or Hour"), - }; - return new ByteSize(Size.Bytes / Interval.TotalSeconds * displayInterval.TotalSeconds) - .Humanize(format, culture) + '/' + timeUnit.ToSymbol(culture); - } + var displayInterval = timeUnit switch + { + TimeUnit.Second => TimeSpan.FromSeconds(1), + TimeUnit.Minute => TimeSpan.FromMinutes(1), + TimeUnit.Hour => TimeSpan.FromHours(1), + _ => throw new NotSupportedException("timeUnit must be Second, Minute, or Hour"), + }; + return new ByteSize(Size.Bytes / Interval.TotalSeconds * displayInterval.TotalSeconds) + .Humanize(format, culture) + '/' + timeUnit.ToSymbol(culture); + } } \ No newline at end of file diff --git a/src/Humanizer/Bytes/ByteSize.cs b/src/Humanizer/Bytes/ByteSize.cs index 86b18e964..f9f6e35d3 100644 --- a/src/Humanizer/Bytes/ByteSize.cs +++ b/src/Humanizer/Bytes/ByteSize.cs @@ -52,7 +52,7 @@ public struct ByteSize(double byteSize) : public const string TerabyteSymbol = "TB"; public const string Terabyte = "terabyte"; - public long Bits { get; } = (long)Math.Ceiling(byteSize * BitsInByte); + public long Bits { get; } = (long) Math.Ceiling(byteSize * BitsInByte); public double Bytes { get; } = byteSize; public double Kilobytes { get; } = byteSize / BytesInKilobyte; public double Megabytes { get; } = byteSize / BytesInMegabyte; @@ -63,104 +63,104 @@ public struct ByteSize(double byteSize) : public string GetLargestWholeNumberSymbol(IFormatProvider? provider = null) { - var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); + var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); - // Absolute value is used to deal with negative values - if (Math.Abs(Terabytes) >= 1) - { - return cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol: true); - } - - if (Math.Abs(Gigabytes) >= 1) - { - return cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol: true); - } + // Absolute value is used to deal with negative values + if (Math.Abs(Terabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol: true); + } - if (Math.Abs(Megabytes) >= 1) - { - return cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol: true); - } + if (Math.Abs(Gigabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol: true); + } - if (Math.Abs(Kilobytes) >= 1) - { - return cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol: true); - } + if (Math.Abs(Megabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol: true); + } - if (Math.Abs(Bytes) >= 1) - { - return cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol: true); - } + if (Math.Abs(Kilobytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol: true); + } - return cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol: true); + if (Math.Abs(Bytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol: true); } + return cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol: true); + } + public string LargestWholeNumberFullWord => GetLargestWholeNumberFullWord(); public string GetLargestWholeNumberFullWord(IFormatProvider? provider = null) { - var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); + var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); + + // Absolute value is used to deal with negative values + if (Math.Abs(Terabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol: false); + } + + if (Math.Abs(Gigabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol: false); + } + + if (Math.Abs(Megabytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol: false); + } + if (Math.Abs(Kilobytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol: false); + } + + if (Math.Abs(Bytes) >= 1) + { + return cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol: false); + } + + return cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol: false); + } + + public double LargestWholeNumberValue + { + get + { // Absolute value is used to deal with negative values if (Math.Abs(Terabytes) >= 1) { - return cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol: false); + return Terabytes; } if (Math.Abs(Gigabytes) >= 1) { - return cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol: false); + return Gigabytes; } if (Math.Abs(Megabytes) >= 1) { - return cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol: false); + return Megabytes; } if (Math.Abs(Kilobytes) >= 1) { - return cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol: false); + return Kilobytes; } if (Math.Abs(Bytes) >= 1) { - return cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol: false); + return Bytes; } - return cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol: false); + return Bits; } - - public double LargestWholeNumberValue - { - get - { - // Absolute value is used to deal with negative values - if (Math.Abs(Terabytes) >= 1) - { - return Terabytes; - } - - if (Math.Abs(Gigabytes) >= 1) - { - return Gigabytes; - } - - if (Math.Abs(Megabytes) >= 1) - { - return Megabytes; - } - - if (Math.Abs(Kilobytes) >= 1) - { - return Kilobytes; - } - - if (Math.Abs(Bytes) >= 1) - { - return Bytes; - } - - return Bits; - } } // Get ceiling because bis are whole units @@ -194,10 +194,10 @@ public override string ToString() => public string ToString(IFormatProvider? provider) { - provider ??= CultureInfo.CurrentCulture; + provider ??= CultureInfo.CurrentCulture; - return string.Format(provider, "{0:0.##} {1}", LargestWholeNumberValue, GetLargestWholeNumberSymbol(provider)); - } + return string.Format(provider, "{0:0.##} {1}", LargestWholeNumberValue, GetLargestWholeNumberSymbol(provider)); + } public string ToString(string? format) => ToString(format, NumberFormatInfo.CurrentInfo); @@ -207,71 +207,71 @@ public string ToString(string? format, IFormatProvider? provider) => string ToString(string? format, IFormatProvider? provider, bool toSymbol) { - format ??= "G"; - provider ??= CultureInfo.CurrentCulture; + format ??= "G"; + provider ??= CultureInfo.CurrentCulture; - if (format == "G") - format = "0.##"; + if (format == "G") + format = "0.##"; - if (!format.Contains("#") && !format.Contains("0")) - { - format = "0.## " + format; - } + if (!format.Contains("#") && !format.Contains("0")) + { + format = "0.## " + format; + } - format = format.Replace("#.##", "0.##"); + format = format.Replace("#.##", "0.##"); - var culture = provider as CultureInfo ?? CultureInfo.CurrentCulture; + var culture = provider as CultureInfo ?? CultureInfo.CurrentCulture; - bool has(string s) => culture.CompareInfo.IndexOf(format, s, CompareOptions.IgnoreCase) != -1; - string output(double n) => n.ToString(format, provider); + bool has(string s) => culture.CompareInfo.IndexOf(format, s, CompareOptions.IgnoreCase) != -1; + string output(double n) => n.ToString(format, provider); - var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); + var cultureFormatter = Configurator.GetFormatter(provider as CultureInfo); - if (has(TerabyteSymbol)) - { - format = format.Replace(TerabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol)); - return output(Terabytes); - } + if (has(TerabyteSymbol)) + { + format = format.Replace(TerabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Terabyte, Terabytes, toSymbol)); + return output(Terabytes); + } - if (has(GigabyteSymbol)) - { - format = format.Replace(GigabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol)); - return output(Gigabytes); - } + if (has(GigabyteSymbol)) + { + format = format.Replace(GigabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Gigabyte, Gigabytes, toSymbol)); + return output(Gigabytes); + } - if (has(MegabyteSymbol)) - { - format = format.Replace(MegabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol)); - return output(Megabytes); - } + if (has(MegabyteSymbol)) + { + format = format.Replace(MegabyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Megabyte, Megabytes, toSymbol)); + return output(Megabytes); + } - if (has(KilobyteSymbol)) - { - format = format.Replace(KilobyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol)); - return output(Kilobytes); - } + if (has(KilobyteSymbol)) + { + format = format.Replace(KilobyteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Kilobyte, Kilobytes, toSymbol)); + return output(Kilobytes); + } - // Byte and Bit symbol look must be case-sensitive - if (format.IndexOf(ByteSymbol, StringComparison.Ordinal) != -1) - { - format = format.Replace(ByteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol)); - return output(Bytes); - } + // Byte and Bit symbol look must be case-sensitive + if (format.IndexOf(ByteSymbol, StringComparison.Ordinal) != -1) + { + format = format.Replace(ByteSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Byte, Bytes, toSymbol)); + return output(Bytes); + } - if (format.IndexOf(BitSymbol, StringComparison.Ordinal) != -1) - { - format = format.Replace(BitSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol)); - return output(Bits); - } + if (format.IndexOf(BitSymbol, StringComparison.Ordinal) != -1) + { + format = format.Replace(BitSymbol, cultureFormatter.DataUnitHumanize(DataUnit.Bit, Bits, toSymbol)); + return output(Bits); + } - var formattedLargeWholeNumberValue = LargestWholeNumberValue.ToString(format, provider); + var formattedLargeWholeNumberValue = LargestWholeNumberValue.ToString(format, provider); - formattedLargeWholeNumberValue = formattedLargeWholeNumberValue.Equals(string.Empty) - ? "0" - : formattedLargeWholeNumberValue; + formattedLargeWholeNumberValue = formattedLargeWholeNumberValue.Equals(string.Empty) + ? "0" + : formattedLargeWholeNumberValue; - return $"{formattedLargeWholeNumberValue} {(toSymbol ? GetLargestWholeNumberSymbol(provider) : GetLargestWholeNumberFullWord(provider))}"; - } + return $"{formattedLargeWholeNumberValue} {(toSymbol ? GetLargestWholeNumberSymbol(provider) : GetLargestWholeNumberFullWord(provider))}"; + } /// /// Converts the value of the current ByteSize object to a string with @@ -284,23 +284,23 @@ public string ToFullWords(string? format = null, IFormatProvider? provider = nul public override bool Equals(object? value) { - if (value == null) - { - return false; - } - - ByteSize other; - if (value is ByteSize size) - { - other = size; - } - else - { - return false; - } + if (value == null) + { + return false; + } - return Equals(other); + ByteSize other; + if (value is ByteSize size) + { + other = size; } + else + { + return false; + } + + return Equals(other); + } public bool Equals(ByteSize value) => Bits == value.Bits; @@ -310,19 +310,19 @@ public override int GetHashCode() => public int CompareTo(object? obj) { - if (obj == null) - { - return 1; - } - - if (obj is ByteSize size) - { - return CompareTo(size); - } + if (obj == null) + { + return 1; + } - throw new ArgumentException("Object is not a ByteSize"); + if (obj is ByteSize size) + { + return CompareTo(size); } + throw new ArgumentException("Object is not a ByteSize"); + } + public int CompareTo(ByteSize other) => Bits.CompareTo(other.Bits); @@ -388,129 +388,136 @@ public static bool TryParse(string? s, out ByteSize result) => public static bool TryParse(string? s, IFormatProvider? formatProvider, out ByteSize result) { - // Arg checking - if (string.IsNullOrWhiteSpace(s)) - { - result = default; - return false; - } + // Arg checking + if (string.IsNullOrWhiteSpace(s)) + { + result = default; + return false; + } - // Acquiring culture-specific parsing info - var numberFormat = GetNumberFormatInfo(formatProvider); + // Acquiring culture-specific parsing info + var numberFormat = GetNumberFormatInfo(formatProvider); - const NumberStyles numberStyles = AllowDecimalPoint | AllowThousands | AllowLeadingSign; - var numberSpecialChars = new[] - { - Convert.ToChar(numberFormat.NumberDecimalSeparator), - Convert.ToChar(numberFormat.NumberGroupSeparator), - Convert.ToChar(numberFormat.PositiveSign), - Convert.ToChar(numberFormat.NegativeSign), - }; + const NumberStyles numberStyles = AllowDecimalPoint | AllowThousands | AllowLeadingSign; + var numberSpecialChars = new[] + { + Convert.ToChar(numberFormat.NumberDecimalSeparator), + Convert.ToChar(numberFormat.NumberGroupSeparator), + Convert.ToChar(numberFormat.PositiveSign), + Convert.ToChar(numberFormat.NegativeSign), + }; - // Setup the result - result = new(); + // Setup the result + result = new(); - // Get the index of the first non-digit character - s = s!.TrimStart(); // Protect against leading spaces + // Get the index of the first non-digit character + s = s!.TrimStart(); // Protect against leading spaces - int num; - var found = false; + int num; + var found = false; - // Pick first non-digit number - for (num = 0; num < s.Length; num++) + // Pick first non-digit number + for (num = 0; num < s.Length; num++) + { + if (!(char.IsDigit(s[num]) || numberSpecialChars.Contains(s[num]))) { - if (!(char.IsDigit(s[num]) || numberSpecialChars.Contains(s[num]))) - { - found = true; - break; - } + found = true; + break; } + } - if (found == false) - { - return false; - } + if (found == false) + { + return false; + } - var lastNumber = num; + var lastNumber = num; - // Cut the input string in half - var numberPart = s.Substring(0, lastNumber).Trim(); - var sizePart = s.Substring(lastNumber, s.Length - lastNumber).Trim(); + // Cut the input string in half + var numberPart = s + .Substring(0, lastNumber) + .Trim(); + var sizePart = s + .Substring(lastNumber, s.Length - lastNumber) + .Trim(); - // Get the numeric part - if (!double.TryParse(numberPart, numberStyles, formatProvider, out var number)) - { - return false; - } + // Get the numeric part + if (!double.TryParse(numberPart, numberStyles, formatProvider, out var number)) + { + return false; + } - // Get the magnitude part - switch (sizePart.ToUpper()) - { - case ByteSymbol: - if (sizePart == BitSymbol) - { // Bits - if (number % 1 != 0) // Can't have partial bits - { - return false; - } - - result = FromBits((long)number); - } - else - { // Bytes - result = FromBytes(number); + // Get the magnitude part + switch (sizePart.ToUpper()) + { + case ByteSymbol: + if (sizePart == BitSymbol) + { + // Bits + if (number % 1 != 0) // Can't have partial bits + { + return false; } - break; - case KilobyteSymbol: - result = FromKilobytes(number); - break; + result = FromBits((long) number); + } + else + { + // Bytes + result = FromBytes(number); + } + + break; - case MegabyteSymbol: - result = FromMegabytes(number); - break; + case KilobyteSymbol: + result = FromKilobytes(number); + break; - case GigabyteSymbol: - result = FromGigabytes(number); - break; + case MegabyteSymbol: + result = FromMegabytes(number); + break; - case TerabyteSymbol: - result = FromTerabytes(number); - break; + case GigabyteSymbol: + result = FromGigabytes(number); + break; - default: - return false; - } + case TerabyteSymbol: + result = FromTerabytes(number); + break; - return true; + default: + return false; } + return true; + } + static NumberFormatInfo GetNumberFormatInfo(IFormatProvider? formatProvider) { - if (formatProvider is NumberFormatInfo numberFormat) - return numberFormat; + if (formatProvider is NumberFormatInfo numberFormat) + return numberFormat; - var culture = formatProvider as CultureInfo ?? CultureInfo.CurrentCulture; + var culture = formatProvider as CultureInfo ?? CultureInfo.CurrentCulture; - return culture.NumberFormat; - } + return culture.NumberFormat; + } public static ByteSize Parse(string s) => Parse(s, null); public static ByteSize Parse(string s, IFormatProvider? formatProvider) { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - if (TryParse(s, formatProvider, out var result)) - { - return result; - } + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } - throw new FormatException("Value is not in the correct format"); + if (TryParse(s, formatProvider, out var result)) + { + return result; } + + throw new FormatException("Value is not in the correct format"); + } } #pragma warning restore 1591 diff --git a/src/Humanizer/CasingExtensions.cs b/src/Humanizer/CasingExtensions.cs index b875749fe..1c66e9759 100644 --- a/src/Humanizer/CasingExtensions.cs +++ b/src/Humanizer/CasingExtensions.cs @@ -10,22 +10,22 @@ public static class CasingExtensions /// public static string ApplyCase(this string input, LetterCasing casing) { - switch (casing) - { - case LetterCasing.Title: - return input.Transform(To.TitleCase); + switch (casing) + { + case LetterCasing.Title: + return input.Transform(To.TitleCase); - case LetterCasing.LowerCase: - return input.Transform(To.LowerCase); + case LetterCasing.LowerCase: + return input.Transform(To.LowerCase); - case LetterCasing.AllCaps: - return input.Transform(To.UpperCase); + case LetterCasing.AllCaps: + return input.Transform(To.UpperCase); - case LetterCasing.Sentence: - return input.Transform(To.SentenceCase); + case LetterCasing.Sentence: + return input.Transform(To.SentenceCase); - default: - throw new ArgumentOutOfRangeException(nameof(casing)); - } + default: + throw new ArgumentOutOfRangeException(nameof(casing)); } + } } \ No newline at end of file diff --git a/src/Humanizer/CollectionHumanizeExtensions.cs b/src/Humanizer/CollectionHumanizeExtensions.cs index 7d7c57bf9..36f3ded0f 100644 --- a/src/Humanizer/CollectionHumanizeExtensions.cs +++ b/src/Humanizer/CollectionHumanizeExtensions.cs @@ -18,28 +18,28 @@ public static string Humanize(this IEnumerable collection) => /// public static string Humanize(this IEnumerable collection, Func displayFormatter) { - if (displayFormatter == null) - { - throw new ArgumentNullException(nameof(displayFormatter)); - } - - return Configurator.CollectionFormatter.Humanize(collection, displayFormatter); + if (displayFormatter == null) + { + throw new ArgumentNullException(nameof(displayFormatter)); } + return Configurator.CollectionFormatter.Humanize(collection, displayFormatter); + } + /// /// Formats the collection for display, calling on each element /// and using the default separator for the current culture. /// public static string Humanize(this IEnumerable collection, Func displayFormatter) { - if (displayFormatter == null) - { - throw new ArgumentNullException(nameof(displayFormatter)); - } - - return Configurator.CollectionFormatter.Humanize(collection, displayFormatter); + if (displayFormatter == null) + { + throw new ArgumentNullException(nameof(displayFormatter)); } + return Configurator.CollectionFormatter.Humanize(collection, displayFormatter); + } + /// /// Formats the collection for display, calling ToString() on each object /// and using the provided separator. @@ -53,25 +53,25 @@ public static string Humanize(this IEnumerable collection, string separato /// public static string Humanize(this IEnumerable collection, Func displayFormatter, string separator) { - if (displayFormatter == null) - { - throw new ArgumentNullException(nameof(displayFormatter)); - } - - return Configurator.CollectionFormatter.Humanize(collection, displayFormatter, separator); + if (displayFormatter == null) + { + throw new ArgumentNullException(nameof(displayFormatter)); } + return Configurator.CollectionFormatter.Humanize(collection, displayFormatter, separator); + } + /// /// Formats the collection for display, calling on each element /// and using the provided separator. /// public static string Humanize(this IEnumerable collection, Func displayFormatter, string separator) { - if (displayFormatter == null) - { - throw new ArgumentNullException(nameof(displayFormatter)); - } - - return Configurator.CollectionFormatter.Humanize(collection, displayFormatter, separator); + if (displayFormatter == null) + { + throw new ArgumentNullException(nameof(displayFormatter)); } + + return Configurator.CollectionFormatter.Humanize(collection, displayFormatter, separator); + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/CollectionFormatterRegistry.cs b/src/Humanizer/Configuration/CollectionFormatterRegistry.cs index 46af9ce46..f6643c101 100644 --- a/src/Humanizer/Configuration/CollectionFormatterRegistry.cs +++ b/src/Humanizer/Configuration/CollectionFormatterRegistry.cs @@ -5,18 +5,18 @@ class CollectionFormatterRegistry : LocaliserRegistry public CollectionFormatterRegistry() : base(new DefaultCollectionFormatter("&")) { - Register("en", new OxfordStyleCollectionFormatter()); - Register("it", new DefaultCollectionFormatter("e")); - Register("de", new DefaultCollectionFormatter("und")); - Register("dk", new DefaultCollectionFormatter("og")); - Register("nl", new DefaultCollectionFormatter("en")); - Register("pt", new DefaultCollectionFormatter("e")); - Register("ro", new DefaultCollectionFormatter("și")); - Register("nn", new DefaultCollectionFormatter("og")); - Register("nb", new DefaultCollectionFormatter("og")); - Register("sv", new DefaultCollectionFormatter("och")); - Register("is", new DefaultCollectionFormatter("og")); - Register("es", new DefaultCollectionFormatter("y")); - Register("lb", new DefaultCollectionFormatter("an")); - } + Register("en", new OxfordStyleCollectionFormatter()); + Register("it", new DefaultCollectionFormatter("e")); + Register("de", new DefaultCollectionFormatter("und")); + Register("dk", new DefaultCollectionFormatter("og")); + Register("nl", new DefaultCollectionFormatter("en")); + Register("pt", new DefaultCollectionFormatter("e")); + Register("ro", new DefaultCollectionFormatter("și")); + Register("nn", new DefaultCollectionFormatter("og")); + Register("nb", new DefaultCollectionFormatter("og")); + Register("sv", new DefaultCollectionFormatter("och")); + Register("is", new DefaultCollectionFormatter("og")); + Register("es", new DefaultCollectionFormatter("y")); + Register("lb", new DefaultCollectionFormatter("an")); + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/Configurator.cs b/src/Humanizer/Configuration/Configurator.cs index 2bffe6705..617b3622b 100644 --- a/src/Humanizer/Configuration/Configurator.cs +++ b/src/Humanizer/Configuration/Configurator.cs @@ -107,9 +107,9 @@ internal static Func EnumDescriptionPropertyLocator { get { - enumDescriptionPropertyLocatorHasBeenUsed = true; - return enumDescriptionPropertyLocator; - } + enumDescriptionPropertyLocatorHasBeenUsed = true; + return enumDescriptionPropertyLocator; + } private set => enumDescriptionPropertyLocator = value; } @@ -118,17 +118,17 @@ internal static Func EnumDescriptionPropertyLocator /// public static void UseEnumDescriptionPropertyLocator(Func func) { - if (enumDescriptionPropertyLocatorHasBeenUsed) - { - throw new("UseEnumDescriptionPropertyLocator must be called before any Enum.Humanize has already been. Move the call to UseEnumDescriptionPropertyLocator to the app startup or a ModuleInitializer."); - } - - EnumDescriptionPropertyLocator = func; + if (enumDescriptionPropertyLocatorHasBeenUsed) + { + throw new("UseEnumDescriptionPropertyLocator must be called before any Enum.Humanize has already been. Move the call to UseEnumDescriptionPropertyLocator to the app startup or a ModuleInitializer."); } + EnumDescriptionPropertyLocator = func; + } + internal static void ResetUseEnumDescriptionPropertyLocator() { - enumDescriptionPropertyLocatorHasBeenUsed = false; - EnumDescriptionPropertyLocator = DefaultEnumDescriptionPropertyLocator; - } + enumDescriptionPropertyLocatorHasBeenUsed = false; + EnumDescriptionPropertyLocator = DefaultEnumDescriptionPropertyLocator; + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/DateOnlyToOrdinalWordsConverterRegistry.cs b/src/Humanizer/Configuration/DateOnlyToOrdinalWordsConverterRegistry.cs index 8720dc079..9e2fb82d1 100644 --- a/src/Humanizer/Configuration/DateOnlyToOrdinalWordsConverterRegistry.cs +++ b/src/Humanizer/Configuration/DateOnlyToOrdinalWordsConverterRegistry.cs @@ -1,15 +1,14 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class DateOnlyToOrdinalWordsConverterRegistry : LocaliserRegistry { - class DateOnlyToOrdinalWordsConverterRegistry : LocaliserRegistry + public DateOnlyToOrdinalWordsConverterRegistry() : base(new DefaultDateOnlyToOrdinalWordConverter()) { - public DateOnlyToOrdinalWordsConverterRegistry() : base(new DefaultDateOnlyToOrdinalWordConverter()) - { - Register("en-US", new UsDateOnlyToOrdinalWordsConverter()); - Register("fr", new FrDateOnlyToOrdinalWordsConverter()); - Register("es", new EsDateOnlyToOrdinalWordsConverter()); - Register("lt", new LtDateOnlyToOrdinalWordsConverter()); - } + Register("en-US", new UsDateOnlyToOrdinalWordsConverter()); + Register("fr", new FrDateOnlyToOrdinalWordsConverter()); + Register("es", new EsDateOnlyToOrdinalWordsConverter()); + Register("lt", new LtDateOnlyToOrdinalWordsConverter()); } } #endif diff --git a/src/Humanizer/Configuration/DateToOrdinalWordsConverterRegistry.cs b/src/Humanizer/Configuration/DateToOrdinalWordsConverterRegistry.cs index 6d03ce4f0..7315f0d66 100644 --- a/src/Humanizer/Configuration/DateToOrdinalWordsConverterRegistry.cs +++ b/src/Humanizer/Configuration/DateToOrdinalWordsConverterRegistry.cs @@ -2,11 +2,12 @@ class DateToOrdinalWordsConverterRegistry : LocaliserRegistry { - public DateToOrdinalWordsConverterRegistry() : base(new DefaultDateToOrdinalWordConverter()) + public DateToOrdinalWordsConverterRegistry() + : base(new DefaultDateToOrdinalWordConverter()) { - Register("en-US", new UsDateToOrdinalWordsConverter()); - Register("fr", new FrDateToOrdinalWordsConverter()); - Register("es", new EsDateToOrdinalWordsConverter()); - Register("lt", new LtDateToOrdinalWordsConverter()); - } + Register("en-US", new UsDateToOrdinalWordsConverter()); + Register("fr", new FrDateToOrdinalWordsConverter()); + Register("es", new EsDateToOrdinalWordsConverter()); + Register("lt", new LtDateToOrdinalWordsConverter()); + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/FormatterRegistry.cs b/src/Humanizer/Configuration/FormatterRegistry.cs index ecf503094..005db2f16 100644 --- a/src/Humanizer/Configuration/FormatterRegistry.cs +++ b/src/Humanizer/Configuration/FormatterRegistry.cs @@ -2,75 +2,76 @@ class FormatterRegistry : LocaliserRegistry { - public FormatterRegistry() : base(new DefaultFormatter("en-US")) + public FormatterRegistry() + : base(new DefaultFormatter("en-US")) { - Register("ar", new ArabicFormatter()); - Register("de", new GermanFormatter()); - Register("he", new HebrewFormatter()); - Register("ro", new RomanianFormatter()); - Register("ru", new RussianFormatter()); - Register("sl", new SlovenianFormatter()); - Register("hr", new CroatianFormatter()); - Register("sr", new SerbianFormatter("sr")); - Register("sr-Latn", new SerbianFormatter("sr-Latn")); - Register("uk", new UkrainianFormatter()); - Register("fr", new FrenchFormatter("fr")); - Register("fr-BE", new FrenchFormatter("fr-BE")); - RegisterCzechSlovakPolishFormatter("cs"); - RegisterCzechSlovakPolishFormatter("pl"); - RegisterCzechSlovakPolishFormatter("sk"); - RegisterDefaultFormatter("bg"); - RegisterDefaultFormatter("ku"); - RegisterDefaultFormatter("pt"); - RegisterDefaultFormatter("sv"); - RegisterDefaultFormatter("tr"); - RegisterDefaultFormatter("vi"); - RegisterDefaultFormatter("en-US"); - RegisterDefaultFormatter("af"); - RegisterDefaultFormatter("az"); - RegisterDefaultFormatter("da"); - RegisterDefaultFormatter("el"); - RegisterDefaultFormatter("es"); - RegisterDefaultFormatter("fa"); - RegisterDefaultFormatter("fi-FI"); - RegisterDefaultFormatter("fil-PH"); - RegisterDefaultFormatter("hu"); - RegisterDefaultFormatter("hy"); - RegisterDefaultFormatter("id"); - Register("is", new IcelandicFormatter()); - RegisterDefaultFormatter("ja"); - RegisterDefaultFormatter("ko-KR"); - RegisterDefaultFormatter("lv"); - Register("mt", new MalteseFormatter("mt")); - RegisterDefaultFormatter("ms-MY"); - RegisterDefaultFormatter("nb"); - RegisterDefaultFormatter("nb-NO"); - RegisterDefaultFormatter("nl"); - RegisterDefaultFormatter("bn-BD"); - RegisterDefaultFormatter("it"); - RegisterDefaultFormatter("ta"); - RegisterDefaultFormatter("uz-Latn-UZ"); - RegisterDefaultFormatter("uz-Cyrl-UZ"); - RegisterDefaultFormatter("zh-CN"); - RegisterDefaultFormatter("zh-Hans"); - RegisterDefaultFormatter("zh-Hant"); - RegisterDefaultFormatter("th-TH"); - RegisterDefaultFormatter("en-IN"); - Register("lt", new LithuanianFormatter()); - Register("lb", new LuxembourgishFormatter()); - } + Register("ar", new ArabicFormatter()); + Register("de", new GermanFormatter()); + Register("he", new HebrewFormatter()); + Register("ro", new RomanianFormatter()); + Register("ru", new RussianFormatter()); + Register("sl", new SlovenianFormatter()); + Register("hr", new CroatianFormatter()); + Register("sr", new SerbianFormatter("sr")); + Register("sr-Latn", new SerbianFormatter("sr-Latn")); + Register("uk", new UkrainianFormatter()); + Register("fr", new FrenchFormatter("fr")); + Register("fr-BE", new FrenchFormatter("fr-BE")); + RegisterCzechSlovakPolishFormatter("cs"); + RegisterCzechSlovakPolishFormatter("pl"); + RegisterCzechSlovakPolishFormatter("sk"); + RegisterDefaultFormatter("bg"); + RegisterDefaultFormatter("ku"); + RegisterDefaultFormatter("pt"); + RegisterDefaultFormatter("sv"); + RegisterDefaultFormatter("tr"); + RegisterDefaultFormatter("vi"); + RegisterDefaultFormatter("en-US"); + RegisterDefaultFormatter("af"); + RegisterDefaultFormatter("az"); + RegisterDefaultFormatter("da"); + RegisterDefaultFormatter("el"); + RegisterDefaultFormatter("es"); + RegisterDefaultFormatter("fa"); + RegisterDefaultFormatter("fi-FI"); + RegisterDefaultFormatter("fil-PH"); + RegisterDefaultFormatter("hu"); + RegisterDefaultFormatter("hy"); + RegisterDefaultFormatter("id"); + Register("is", new IcelandicFormatter()); + RegisterDefaultFormatter("ja"); + RegisterDefaultFormatter("ko-KR"); + RegisterDefaultFormatter("lv"); + Register("mt", new MalteseFormatter("mt")); + RegisterDefaultFormatter("ms-MY"); + RegisterDefaultFormatter("nb"); + RegisterDefaultFormatter("nb-NO"); + RegisterDefaultFormatter("nl"); + RegisterDefaultFormatter("bn-BD"); + RegisterDefaultFormatter("it"); + RegisterDefaultFormatter("ta"); + RegisterDefaultFormatter("uz-Latn-UZ"); + RegisterDefaultFormatter("uz-Cyrl-UZ"); + RegisterDefaultFormatter("zh-CN"); + RegisterDefaultFormatter("zh-Hans"); + RegisterDefaultFormatter("zh-Hant"); + RegisterDefaultFormatter("th-TH"); + RegisterDefaultFormatter("en-IN"); + Register("lt", new LithuanianFormatter()); + Register("lb", new LuxembourgishFormatter()); + } void RegisterDefaultFormatter(string localeCode) { - try - { - Register(localeCode, new DefaultFormatter(localeCode)); - } - catch (CultureNotFoundException) - { - // Some OS's may not support the particular culture. Not much we can do for those. - } + try + { + Register(localeCode, new DefaultFormatter(localeCode)); + } + catch (CultureNotFoundException) + { + // Some OS's may not support the particular culture. Not much we can do for those. } + } void RegisterCzechSlovakPolishFormatter(string localeCode) => Register(localeCode, new CzechSlovakPolishFormatter(localeCode)); diff --git a/src/Humanizer/Configuration/LocaliserRegistry.cs b/src/Humanizer/Configuration/LocaliserRegistry.cs index f6e098456..ed0f9b92a 100644 --- a/src/Humanizer/Configuration/LocaliserRegistry.cs +++ b/src/Humanizer/Configuration/LocaliserRegistry.cs @@ -48,14 +48,14 @@ public void Register(string localeCode, Func localiser Func FindLocaliser(CultureInfo culture) { - for (var c = culture; !string.IsNullOrEmpty(c?.Name); c = c.Parent) + for (var c = culture; !string.IsNullOrEmpty(c?.Name); c = c.Parent) + { + if (_localisers.TryGetValue(c!.Name, out var localiser)) { - if (_localisers.TryGetValue(c!.Name, out var localiser)) - { - return localiser; - } + return localiser; } - - return _defaultLocaliser; } + + return _defaultLocaliser; + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/NumberToWordsConverterRegistry.cs b/src/Humanizer/Configuration/NumberToWordsConverterRegistry.cs index e24954d00..136071d4e 100644 --- a/src/Humanizer/Configuration/NumberToWordsConverterRegistry.cs +++ b/src/Humanizer/Configuration/NumberToWordsConverterRegistry.cs @@ -5,54 +5,54 @@ class NumberToWordsConverterRegistry : LocaliserRegistry new EnglishNumberToWordsConverter()) { - Register("af", new AfrikaansNumberToWordsConverter()); - Register("en", new EnglishNumberToWordsConverter()); - Register("ar", new ArabicNumberToWordsConverter()); - Register("cs", _ => new CzechNumberToWordsConverter(_)); - Register("fa", new FarsiNumberToWordsConverter()); - Register("es", new SpanishNumberToWordsConverter()); - Register("pl", _ => new PolishNumberToWordsConverter(_)); - Register("pt", new PortugueseNumberToWordsConverter()); - Register("pt-BR", new BrazilianPortugueseNumberToWordsConverter()); - Register("ro", new RomanianNumberToWordsConverter()); - Register("ru", new RussianNumberToWordsConverter()); - Register("fi", new FinnishNumberToWordsConverter()); - Register("fr-BE", new FrenchBelgianNumberToWordsConverter()); - Register("fr-CH", new FrenchSwissNumberToWordsConverter()); - Register("fr", new FrenchNumberToWordsConverter()); - Register("nl", new DutchNumberToWordsConverter()); - Register("he", _ => new HebrewNumberToWordsConverter(_)); - Register("sl", _ => new SlovenianNumberToWordsConverter(_)); - Register("de", new GermanNumberToWordsConverter()); - Register("de-CH", new GermanSwissLiechtensteinNumberToWordsConverter()); - Register("de-LI", new GermanSwissLiechtensteinNumberToWordsConverter()); - Register("bn-BD", new BanglaNumberToWordsConverter()); - Register("tr", new TurkishNumberToWordConverter()); - Register("is", new IcelandicNumberToWordsConverter()); - Register("it", new ItalianNumberToWordsConverter()); - Register("mt", new MalteseNumberToWordsConvertor()); - Register("uk", new UkrainianNumberToWordsConverter()); - Register("uz-Latn-UZ", new UzbekLatnNumberToWordConverter()); - Register("uz-Cyrl-UZ", new UzbekCyrlNumberToWordConverter()); - Register("sv", new SwedishNumberToWordsConverter()); - Register("sr", _ => new SerbianCyrlNumberToWordsConverter(_)); - Register("sr-Latn", _ => new SerbianNumberToWordsConverter(_)); - Register("ta", new TamilNumberToWordsConverter()); - Register("hr", _ => new CroatianNumberToWordsConverter(_)); - Register("nb", new NorwegianBokmalNumberToWordsConverter()); - Register("vi", new VietnameseNumberToWordsConverter()); - Register("zh-CN", new ChineseNumberToWordsConverter()); - Register("bg", new BulgarianNumberToWordsConverter()); - Register("hy", new ArmenianNumberToWordsConverter()); - Register("az", new AzerbaijaniNumberToWordsConverter()); - Register("ja", new JapaneseNumberToWordsConverter()); - Register("ku", new CentralKurdishNumberToWordsConverter()); - Register("el", new GreekNumberToWordsConverter()); - Register("th-TH", new ThaiNumberToWordsConverter()); - Register("lv", new LatvianNumberToWordsConverter()); - Register("ko-KR", new KoreanNumberToWordsConverter()); - Register("en-IN", new IndianNumberToWordsConverter()); - Register("lt", new LithuanianNumberToWordsConverter()); - Register("lb", new LuxembourgishNumberToWordsConverter()); - } + Register("af", new AfrikaansNumberToWordsConverter()); + Register("en", new EnglishNumberToWordsConverter()); + Register("ar", new ArabicNumberToWordsConverter()); + Register("cs", _ => new CzechNumberToWordsConverter(_)); + Register("fa", new FarsiNumberToWordsConverter()); + Register("es", new SpanishNumberToWordsConverter()); + Register("pl", _ => new PolishNumberToWordsConverter(_)); + Register("pt", new PortugueseNumberToWordsConverter()); + Register("pt-BR", new BrazilianPortugueseNumberToWordsConverter()); + Register("ro", new RomanianNumberToWordsConverter()); + Register("ru", new RussianNumberToWordsConverter()); + Register("fi", new FinnishNumberToWordsConverter()); + Register("fr-BE", new FrenchBelgianNumberToWordsConverter()); + Register("fr-CH", new FrenchSwissNumberToWordsConverter()); + Register("fr", new FrenchNumberToWordsConverter()); + Register("nl", new DutchNumberToWordsConverter()); + Register("he", _ => new HebrewNumberToWordsConverter(_)); + Register("sl", _ => new SlovenianNumberToWordsConverter(_)); + Register("de", new GermanNumberToWordsConverter()); + Register("de-CH", new GermanSwissLiechtensteinNumberToWordsConverter()); + Register("de-LI", new GermanSwissLiechtensteinNumberToWordsConverter()); + Register("bn-BD", new BanglaNumberToWordsConverter()); + Register("tr", new TurkishNumberToWordConverter()); + Register("is", new IcelandicNumberToWordsConverter()); + Register("it", new ItalianNumberToWordsConverter()); + Register("mt", new MalteseNumberToWordsConvertor()); + Register("uk", new UkrainianNumberToWordsConverter()); + Register("uz-Latn-UZ", new UzbekLatnNumberToWordConverter()); + Register("uz-Cyrl-UZ", new UzbekCyrlNumberToWordConverter()); + Register("sv", new SwedishNumberToWordsConverter()); + Register("sr", _ => new SerbianCyrlNumberToWordsConverter(_)); + Register("sr-Latn", _ => new SerbianNumberToWordsConverter(_)); + Register("ta", new TamilNumberToWordsConverter()); + Register("hr", _ => new CroatianNumberToWordsConverter(_)); + Register("nb", new NorwegianBokmalNumberToWordsConverter()); + Register("vi", new VietnameseNumberToWordsConverter()); + Register("zh-CN", new ChineseNumberToWordsConverter()); + Register("bg", new BulgarianNumberToWordsConverter()); + Register("hy", new ArmenianNumberToWordsConverter()); + Register("az", new AzerbaijaniNumberToWordsConverter()); + Register("ja", new JapaneseNumberToWordsConverter()); + Register("ku", new CentralKurdishNumberToWordsConverter()); + Register("el", new GreekNumberToWordsConverter()); + Register("th-TH", new ThaiNumberToWordsConverter()); + Register("lv", new LatvianNumberToWordsConverter()); + Register("ko-KR", new KoreanNumberToWordsConverter()); + Register("en-IN", new IndianNumberToWordsConverter()); + Register("lt", new LithuanianNumberToWordsConverter()); + Register("lb", new LuxembourgishNumberToWordsConverter()); + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/OrdinalizerRegistry.cs b/src/Humanizer/Configuration/OrdinalizerRegistry.cs index 0c21c6eb6..91570daa3 100644 --- a/src/Humanizer/Configuration/OrdinalizerRegistry.cs +++ b/src/Humanizer/Configuration/OrdinalizerRegistry.cs @@ -2,22 +2,23 @@ class OrdinalizerRegistry : LocaliserRegistry { - public OrdinalizerRegistry() : base(new DefaultOrdinalizer()) + public OrdinalizerRegistry() + : base(new DefaultOrdinalizer()) { - Register("de", new GermanOrdinalizer()); - Register("en", new EnglishOrdinalizer()); - Register("es", new SpanishOrdinalizer()); - Register("fr", new FrenchOrdinalizer()); - Register("is", new IcelandicOrdinalizer()); - Register("it", new ItalianOrdinalizer()); - Register("nl", new DutchOrdinalizer()); - Register("pt", new PortugueseOrdinalizer()); - Register("ro", new RomanianOrdinalizer()); - Register("ru", new RussianOrdinalizer()); - Register("tr", new TurkishOrdinalizer()); - Register("uk", new UkrainianOrdinalizer()); - Register("hy", new ArmenianOrdinalizer()); - Register("az", new AzerbaijaniOrdinalizer()); - Register("lb", new LuxembourgishOrdinalizer()); - } + Register("de", new GermanOrdinalizer()); + Register("en", new EnglishOrdinalizer()); + Register("es", new SpanishOrdinalizer()); + Register("fr", new FrenchOrdinalizer()); + Register("is", new IcelandicOrdinalizer()); + Register("it", new ItalianOrdinalizer()); + Register("nl", new DutchOrdinalizer()); + Register("pt", new PortugueseOrdinalizer()); + Register("ro", new RomanianOrdinalizer()); + Register("ru", new RussianOrdinalizer()); + Register("tr", new TurkishOrdinalizer()); + Register("uk", new UkrainianOrdinalizer()); + Register("hy", new ArmenianOrdinalizer()); + Register("az", new AzerbaijaniOrdinalizer()); + Register("lb", new LuxembourgishOrdinalizer()); + } } \ No newline at end of file diff --git a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs index 11fa208e1..bdc9c53b6 100644 --- a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs +++ b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs @@ -1,16 +1,15 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class TimeOnlyToClockNotationConvertersRegistry : LocaliserRegistry { - class TimeOnlyToClockNotationConvertersRegistry : LocaliserRegistry + public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToClockNotationConverter()) { - public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToClockNotationConverter()) - { - Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter()); - Register("fr", new FrTimeOnlyToClockNotationConverter()); - Register("es", new EsTimeOnlyToClockNotationConverter()); - Register("lb", new LbTimeOnlyToClockNotationConverter()); - } + Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter()); + Register("fr", new FrTimeOnlyToClockNotationConverter()); + Register("es", new EsTimeOnlyToClockNotationConverter()); + Register("lb", new LbTimeOnlyToClockNotationConverter()); } } diff --git a/src/Humanizer/DateHumanizeExtensions.cs b/src/Humanizer/DateHumanizeExtensions.cs index a8d640dbe..36ba7bb2a 100644 --- a/src/Humanizer/DateHumanizeExtensions.cs +++ b/src/Humanizer/DateHumanizeExtensions.cs @@ -15,12 +15,12 @@ public static class DateHumanizeExtensions /// distance of time in words public static string Humanize(this DateTime input, bool? utcDate = null, DateTime? dateToCompareAgainst = null, CultureInfo? culture = null) { - var comparisonBase = dateToCompareAgainst ?? DateTime.UtcNow; - utcDate ??= input.Kind != DateTimeKind.Local; - comparisonBase = utcDate.Value ? comparisonBase.ToUniversalTime() : comparisonBase.ToLocalTime(); + var comparisonBase = dateToCompareAgainst ?? DateTime.UtcNow; + utcDate ??= input.Kind != DateTimeKind.Local; + comparisonBase = utcDate.Value ? comparisonBase.ToUniversalTime() : comparisonBase.ToLocalTime(); - return Configurator.DateTimeHumanizeStrategy.Humanize(input, comparisonBase, culture); - } + return Configurator.DateTimeHumanizeStrategy.Humanize(input, comparisonBase, culture); + } /// /// Turns the current or provided date into a human readable sentence, overload for the nullable DateTime, returning 'never' in case null @@ -32,14 +32,16 @@ public static string Humanize(this DateTime input, bool? utcDate = null, DateTim /// distance of time in words public static string Humanize(this DateTime? input, bool? utcDate = null, DateTime? dateToCompareAgainst = null, CultureInfo? culture = null) { - if (input.HasValue) - { - return Humanize(input.Value, utcDate, dateToCompareAgainst, culture); - } - - return Configurator.GetFormatter(culture).DateHumanize_Never(); + if (input.HasValue) + { + return Humanize(input.Value, utcDate, dateToCompareAgainst, culture); } + return Configurator + .GetFormatter(culture) + .DateHumanize_Never(); + } + /// /// Turns the current or provided date into a human readable sentence /// @@ -49,10 +51,10 @@ public static string Humanize(this DateTime? input, bool? utcDate = null, DateTi /// distance of time in words public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToCompareAgainst = null, CultureInfo? culture = null) { - var comparisonBase = dateToCompareAgainst ?? DateTimeOffset.UtcNow; + var comparisonBase = dateToCompareAgainst ?? DateTimeOffset.UtcNow; - return Configurator.DateTimeOffsetHumanizeStrategy.Humanize(input, comparisonBase, culture); - } + return Configurator.DateTimeOffsetHumanizeStrategy.Humanize(input, comparisonBase, culture); + } /// /// Turns the current or provided date into a human readable sentence, overload for the nullable DateTimeOffset, returning 'never' in case null @@ -63,14 +65,16 @@ public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToC /// distance of time in words public static string Humanize(this DateTimeOffset? input, DateTimeOffset? dateToCompareAgainst = null, CultureInfo? culture = null) { - if (input.HasValue) - { - return Humanize(input.Value, dateToCompareAgainst, culture); - } - - return Configurator.GetFormatter(culture).DateHumanize_Never(); + if (input.HasValue) + { + return Humanize(input.Value, dateToCompareAgainst, culture); } + return Configurator + .GetFormatter(culture) + .DateHumanize_Never(); + } + #if NET6_0_OR_GREATER /// /// Turns the current or provided date into a human readable sentence @@ -81,9 +85,9 @@ public static string Humanize(this DateTimeOffset? input, DateTimeOffset? dateTo /// distance of time in words public static string Humanize(this DateOnly input, DateOnly? dateToCompareAgainst = null, CultureInfo? culture = null) { - var comparisonBase = dateToCompareAgainst ?? DateOnly.FromDateTime(DateTime.UtcNow); - return Configurator.DateOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); - } + var comparisonBase = dateToCompareAgainst ?? DateOnly.FromDateTime(DateTime.UtcNow); + return Configurator.DateOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); + } /// /// Turns the current or provided date into a human readable sentence, overload for the nullable DateTime, returning 'never' in case null @@ -94,14 +98,16 @@ public static string Humanize(this DateOnly input, DateOnly? dateToCompareAgains /// distance of time in words public static string Humanize(this DateOnly? input, DateOnly? dateToCompareAgainst = null, CultureInfo? culture = null) { - if (input.HasValue) - { - return Humanize(input.Value, dateToCompareAgainst, culture); - } - - return Configurator.GetFormatter(culture).DateHumanize_Never(); + if (input.HasValue) + { + return Humanize(input.Value, dateToCompareAgainst, culture); } + return Configurator + .GetFormatter(culture) + .DateHumanize_Never(); + } + /// /// Turns the current or provided time into a human readable sentence /// @@ -112,10 +118,10 @@ public static string Humanize(this DateOnly? input, DateOnly? dateToCompareAgain /// distance of time in words public static string Humanize(this TimeOnly input, TimeOnly? timeToCompareAgainst = null, bool useUtc = true, CultureInfo? culture = null) { - var comparisonBase = timeToCompareAgainst ?? TimeOnly.FromDateTime(useUtc ? DateTime.UtcNow : DateTime.Now); + var comparisonBase = timeToCompareAgainst ?? TimeOnly.FromDateTime(useUtc ? DateTime.UtcNow : DateTime.Now); - return Configurator.TimeOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); - } + return Configurator.TimeOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); + } /// /// Turns the current or provided time into a human readable sentence, overload for the nullable TimeOnly, returning 'never' in case null @@ -127,13 +133,15 @@ public static string Humanize(this TimeOnly input, TimeOnly? timeToCompareAgains /// distance of time in words public static string Humanize(this TimeOnly? input, TimeOnly? timeToCompareAgainst = null, bool useUtc = true, CultureInfo? culture = null) { - if (input.HasValue) - { - return Humanize(input.Value, timeToCompareAgainst, useUtc, culture); - } - - return Configurator.GetFormatter(culture).DateHumanize_Never(); + if (input.HasValue) + { + return Humanize(input.Value, timeToCompareAgainst, useUtc, culture); } + return Configurator + .GetFormatter(culture) + .DateHumanize_Never(); + } + #endif } \ No newline at end of file diff --git a/src/Humanizer/DateTimeHumanizeStrategy/DefaultDateOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/DefaultDateOnlyHumanizeStrategy.cs index 3f941ecb0..30cd9d953 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/DefaultDateOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/DefaultDateOnlyHumanizeStrategy.cs @@ -1,18 +1,17 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// The default 'distance of time' -> words calculator. +/// +public class DefaultDateOnlyHumanizeStrategy : IDateOnlyHumanizeStrategy { /// - /// The default 'distance of time' -> words calculator. + /// Calculates the distance of time in words between two provided dates /// - public class DefaultDateOnlyHumanizeStrategy : IDateOnlyHumanizeStrategy - { - /// - /// Calculates the distance of time in words between two provided dates - /// - public string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) => - DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture); - } + public string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) => + DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture); } #endif diff --git a/src/Humanizer/DateTimeHumanizeStrategy/DefaultTimeOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/DefaultTimeOnlyHumanizeStrategy.cs index ab180a38a..42e284000 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/DefaultTimeOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/DefaultTimeOnlyHumanizeStrategy.cs @@ -1,18 +1,17 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// The default 'distance of time' -> words calculator. +/// +public class DefaultTimeOnlyHumanizeStrategy : ITimeOnlyHumanizeStrategy { /// - /// The default 'distance of time' -> words calculator. + /// Calculates the distance of time in words between two provided times /// - public class DefaultTimeOnlyHumanizeStrategy : ITimeOnlyHumanizeStrategy - { - /// - /// Calculates the distance of time in words between two provided times - /// - public string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) => - DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture); - } + public string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) => + DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture); } #endif diff --git a/src/Humanizer/DateTimeHumanizeStrategy/IDateOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/IDateOnlyHumanizeStrategy.cs index 306e4affb..dc374486f 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/IDateOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/IDateOnlyHumanizeStrategy.cs @@ -1,17 +1,16 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// Implement this interface to create a new strategy for DateOnly.Humanize and hook it in the Configurator.DateOnlyHumanizeStrategy +/// +public interface IDateOnlyHumanizeStrategy { /// - /// Implement this interface to create a new strategy for DateOnly.Humanize and hook it in the Configurator.DateOnlyHumanizeStrategy + /// Calculates the distance of time in words between two provided dates used for DateOnly.Humanize /// - public interface IDateOnlyHumanizeStrategy - { - /// - /// Calculates the distance of time in words between two provided dates used for DateOnly.Humanize - /// - string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture); - } + string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture); } #endif diff --git a/src/Humanizer/DateTimeHumanizeStrategy/ITimeOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/ITimeOnlyHumanizeStrategy.cs index af44db8c3..444820767 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/ITimeOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/ITimeOnlyHumanizeStrategy.cs @@ -1,17 +1,16 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// Implement this interface to create a new strategy for TimeOnly.Humanize and hook it in the Configurator.TimeOnlyHumanizeStrategy +/// +public interface ITimeOnlyHumanizeStrategy { /// - /// Implement this interface to create a new strategy for TimeOnly.Humanize and hook it in the Configurator.TimeOnlyHumanizeStrategy + /// Calculates the distance of time in words between two provided dates used for TimeOnly.Humanize /// - public interface ITimeOnlyHumanizeStrategy - { - /// - /// Calculates the distance of time in words between two provided dates used for TimeOnly.Humanize - /// - string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture); - } + string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture); } #endif diff --git a/src/Humanizer/DateTimeHumanizeStrategy/PrecisionDateOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/PrecisionDateOnlyHumanizeStrategy.cs index aa543db1d..40891dca8 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/PrecisionDateOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/PrecisionDateOnlyHumanizeStrategy.cs @@ -1,27 +1,26 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// Precision-based calculator for distance between two times +/// +public class PrecisionDateOnlyHumanizeStrategy : IDateOnlyHumanizeStrategy { + readonly double _precision; + /// - /// Precision-based calculator for distance between two times + /// Constructs a precision-based calculator for distance of time with default precision 0.75. /// - public class PrecisionDateOnlyHumanizeStrategy : IDateOnlyHumanizeStrategy - { - readonly double _precision; - - /// - /// Constructs a precision-based calculator for distance of time with default precision 0.75. - /// - /// precision of approximation, if not provided 0.75 will be used as a default precision. - public PrecisionDateOnlyHumanizeStrategy(double precision = .75) => - _precision = precision; + /// precision of approximation, if not provided 0.75 will be used as a default precision. + public PrecisionDateOnlyHumanizeStrategy(double precision = .75) => + _precision = precision; - /// - /// Returns localized & humanized distance of time between two dates; given a specific precision. - /// - public string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) => - DateTimeHumanizeAlgorithms.PrecisionHumanize(input, comparisonBase, _precision, culture); - } + /// + /// Returns localized & humanized distance of time between two dates; given a specific precision. + /// + public string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) => + DateTimeHumanizeAlgorithms.PrecisionHumanize(input, comparisonBase, _precision, culture); } #endif diff --git a/src/Humanizer/DateTimeHumanizeStrategy/PrecisionTimeOnlyHumanizeStrategy.cs b/src/Humanizer/DateTimeHumanizeStrategy/PrecisionTimeOnlyHumanizeStrategy.cs index 6f1c19261..3b959dbbd 100644 --- a/src/Humanizer/DateTimeHumanizeStrategy/PrecisionTimeOnlyHumanizeStrategy.cs +++ b/src/Humanizer/DateTimeHumanizeStrategy/PrecisionTimeOnlyHumanizeStrategy.cs @@ -1,27 +1,26 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// Precision-based calculator for distance between two times +/// +public class PrecisionTimeOnlyHumanizeStrategy : ITimeOnlyHumanizeStrategy { + readonly double _precision; + /// - /// Precision-based calculator for distance between two times + /// Constructs a precision-based calculator for distance of time with default precision 0.75. /// - public class PrecisionTimeOnlyHumanizeStrategy : ITimeOnlyHumanizeStrategy - { - readonly double _precision; - - /// - /// Constructs a precision-based calculator for distance of time with default precision 0.75. - /// - /// precision of approximation, if not provided 0.75 will be used as a default precision. - public PrecisionTimeOnlyHumanizeStrategy(double precision = .75) => - _precision = precision; + /// precision of approximation, if not provided 0.75 will be used as a default precision. + public PrecisionTimeOnlyHumanizeStrategy(double precision = .75) => + _precision = precision; - /// - /// Returns localized & humanized distance of time between two dates; given a specific precision. - /// - public string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) => - DateTimeHumanizeAlgorithms.PrecisionHumanize(input, comparisonBase, _precision, culture); - } + /// + /// Returns localized & humanized distance of time between two dates; given a specific precision. + /// + public string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) => + DateTimeHumanizeAlgorithms.PrecisionHumanize(input, comparisonBase, _precision, culture); } #endif diff --git a/src/Humanizer/FluentDate/InDate.cs b/src/Humanizer/FluentDate/InDate.cs index 31d3058d3..cb023d86b 100644 --- a/src/Humanizer/FluentDate/InDate.cs +++ b/src/Humanizer/FluentDate/InDate.cs @@ -1,13 +1,12 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +public partial class InDate { - public partial class InDate - { - /// - /// Returns the first of January of the provided year - /// - public static DateOnly TheYear(int year) => - new(year, 1, 1); - } + /// + /// Returns the first of January of the provided year + /// + public static DateOnly TheYear(int year) => + new(year, 1, 1); } #endif diff --git a/src/Humanizer/HeadingExtensions.cs b/src/Humanizer/HeadingExtensions.cs index 4d2b2e845..8521b3843 100644 --- a/src/Humanizer/HeadingExtensions.cs +++ b/src/Humanizer/HeadingExtensions.cs @@ -37,18 +37,18 @@ public static class HeadingExtensions /// The culture to return the textual representation in public static string ToHeading(this double heading, HeadingStyle style = HeadingStyle.Abbreviated, CultureInfo? culture = null) { - var val = (int)(heading / 22.5 + .5); + var val = (int) (heading / 22.5 + .5); - var result = Headings[val % 16]; + var result = Headings[val % 16]; - if (style == HeadingStyle.Abbreviated) - { - return Resources.GetResource($"{result}_Short", culture); - } - - return Resources.GetResource(result, culture); + if (style == HeadingStyle.Abbreviated) + { + return Resources.GetResource($"{result}_Short", culture); } + return Resources.GetResource(result, culture); + } + /// /// Returns a char arrow indicating the heading. /// @@ -57,10 +57,10 @@ public static string ToHeading(this double heading, HeadingStyle style = Heading /// The heading arrow. public static char ToHeadingArrow(this double heading) { - var val = (int)(heading / 45 + .5); + var val = (int) (heading / 45 + .5); - return HeadingArrows[val % 8]; - } + return HeadingArrows[val % 8]; + } /// /// Returns a heading based on the short textual representation of the heading. @@ -78,56 +78,57 @@ public static double FromAbbreviatedHeading(this string heading) => /// The heading. -1 if the heading could not be parsed. public static double FromAbbreviatedHeading(this string heading, CultureInfo? culture = null) { - if (heading == null) - { - throw new ArgumentNullException(nameof(heading)); - } + if (heading == null) + { + throw new ArgumentNullException(nameof(heading)); + } - culture ??= CultureInfo.CurrentCulture; + culture ??= CultureInfo.CurrentCulture; - var upperCaseHeading = culture.TextInfo.ToUpper(heading); - for (var index = 0; index < Headings.Length; ++index) + var upperCaseHeading = culture.TextInfo.ToUpper(heading); + for (var index = 0; index < Headings.Length; ++index) + { + var localizedShortHeading = Resources.GetResource($"{Headings[index]}_Short", culture); + if (culture.CompareInfo.Compare(upperCaseHeading, localizedShortHeading) == 0) { - var localizedShortHeading = Resources.GetResource($"{Headings[index]}_Short", culture); - if (culture.CompareInfo.Compare(upperCaseHeading, localizedShortHeading) == 0) - { - return index * 22.5; - } + return index * 22.5; } - - return -1; } + return -1; + } + /// /// Returns a heading based on the heading arrow. /// public static double FromHeadingArrow(this char heading) { - var index = Array.IndexOf(HeadingArrows, heading); - - if (index == -1) - { - return -1; - } + var index = Array.IndexOf(HeadingArrows, heading); - return index * 45.0; + if (index == -1) + { + return -1; } + return index * 45.0; + } + /// /// Returns a heading based on the heading arrow. /// public static double FromHeadingArrow(this string heading) { - if (heading == null) - { - throw new ArgumentNullException(nameof(heading)); - } - - if (heading.Length != 1) - { - return -1; - } + if (heading == null) + { + throw new ArgumentNullException(nameof(heading)); + } - return heading[0].FromHeadingArrow(); + if (heading.Length != 1) + { + return -1; } + + return heading[0] + .FromHeadingArrow(); + } } \ No newline at end of file diff --git a/src/Humanizer/Inflections/Vocabularies.cs b/src/Humanizer/Inflections/Vocabularies.cs index 84432d200..e6099a7ea 100644 --- a/src/Humanizer/Inflections/Vocabularies.cs +++ b/src/Humanizer/Inflections/Vocabularies.cs @@ -19,136 +19,136 @@ static Vocabularies() => static Vocabulary BuildDefault() { - var _default = new Vocabulary(); + var _default = new Vocabulary(); - _default.AddPlural("$", "s"); - _default.AddPlural("s$", "s"); - _default.AddPlural("(ax|test)is$", "$1es"); - _default.AddPlural("(octop|vir|alumn|fung|cact|foc|hippopotam|radi|stimul|syllab|nucle)us$", "$1i"); - _default.AddPlural("(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis)$", "$1es"); - _default.AddPlural("(buffal|tomat|volcan|ech|embarg|her|mosquit|potat|torped|vet)o$", "$1oes"); - _default.AddPlural("([dti])um$", "$1a"); - _default.AddPlural("sis$", "ses"); - _default.AddPlural("(?:([^f])fe|([lr])f)$", "$1$2ves"); - _default.AddPlural("(hive)$", "$1s"); - _default.AddPlural("([^aeiouy]|qu)y$", "$1ies"); - _default.AddPlural("(x|ch|ss|sh)$", "$1es"); - _default.AddPlural("(matr|vert|ind|d)(ix|ex)$", "$1ices"); - _default.AddPlural("(^[m|l])ouse$", "$1ice"); - _default.AddPlural("^(ox)$", "$1en"); - _default.AddPlural("(quiz)$", "$1zes"); - _default.AddPlural("(buz|blit|walt)z$", "$1zes"); - _default.AddPlural("(hoo|lea|loa|thie)f$", "$1ves"); - _default.AddPlural("(alumn|alg|larv|vertebr)a$", "$1ae"); - _default.AddPlural("(criteri|phenomen)on$", "$1a"); + _default.AddPlural("$", "s"); + _default.AddPlural("s$", "s"); + _default.AddPlural("(ax|test)is$", "$1es"); + _default.AddPlural("(octop|vir|alumn|fung|cact|foc|hippopotam|radi|stimul|syllab|nucle)us$", "$1i"); + _default.AddPlural("(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis)$", "$1es"); + _default.AddPlural("(buffal|tomat|volcan|ech|embarg|her|mosquit|potat|torped|vet)o$", "$1oes"); + _default.AddPlural("([dti])um$", "$1a"); + _default.AddPlural("sis$", "ses"); + _default.AddPlural("(?:([^f])fe|([lr])f)$", "$1$2ves"); + _default.AddPlural("(hive)$", "$1s"); + _default.AddPlural("([^aeiouy]|qu)y$", "$1ies"); + _default.AddPlural("(x|ch|ss|sh)$", "$1es"); + _default.AddPlural("(matr|vert|ind|d)(ix|ex)$", "$1ices"); + _default.AddPlural("(^[m|l])ouse$", "$1ice"); + _default.AddPlural("^(ox)$", "$1en"); + _default.AddPlural("(quiz)$", "$1zes"); + _default.AddPlural("(buz|blit|walt)z$", "$1zes"); + _default.AddPlural("(hoo|lea|loa|thie)f$", "$1ves"); + _default.AddPlural("(alumn|alg|larv|vertebr)a$", "$1ae"); + _default.AddPlural("(criteri|phenomen)on$", "$1a"); - _default.AddSingular("s$", ""); - _default.AddSingular("(n)ews$", "$1ews"); - _default.AddSingular("([dti])a$", "$1um"); - _default.AddSingular("(analy|ba|diagno|parenthe|progno|synop|the|ellip|empha|neuro|oa|paraly)ses$", "$1sis"); - _default.AddSingular("([^f])ves$", "$1fe"); - _default.AddSingular("(hive)s$", "$1"); - _default.AddSingular("(tive)s$", "$1"); - _default.AddSingular("([lr]|hoo|lea|loa|thie)ves$", "$1f"); - _default.AddSingular("(^zomb)?([^aeiouy]|qu)ies$", "$2y"); - _default.AddSingular("(s)eries$", "$1eries"); - _default.AddSingular("(m)ovies$", "$1ovie"); - _default.AddSingular("(x|ch|ss|sh)es$", "$1"); - _default.AddSingular("(^[m|l])ice$", "$1ouse"); - _default.AddSingular("(? /// By default, pascalize converts strings to UpperCamelCase also removing underscores /// public static string Pascalize(this string input) => - Regex.Replace(input, @"(?:[ _-]+|^)([a-zA-Z])", match => match.Groups[1].Value.ToUpper()); + Regex.Replace(input, @"(?:[ _-]+|^)([a-zA-Z])", match => match + .Groups[1] + .Value.ToUpper()); /// /// Same as Pascalize except that the first character is lower case /// public static string Camelize(this string input) { - var word = input.Pascalize(); - return word.Length > 0 ? word.Substring(0, 1).ToLower() + word.Substring(1) : word; - } + var word = input.Pascalize(); + return word.Length > 0 + ? word + .Substring(0, 1) + .ToLower() + word.Substring(1) + : word; + } /// /// Separates the input words with underscore /// /// The string to be underscored public static string Underscore(this string input) => - Regex.Replace( - Regex.Replace( - Regex.Replace(input, @"([\p{Lu}]+)([\p{Lu}][\p{Ll}])", "$1_$2"), @"([\p{Ll}\d])([\p{Lu}])", "$1_$2"), @"[-\s]", "_").ToLower(); + Regex + .Replace( + Regex.Replace( + Regex.Replace(input, @"([\p{Lu}]+)([\p{Lu}][\p{Ll}])", "$1_$2"), @"([\p{Ll}\d])([\p{Lu}])", "$1_$2"), @"[-\s]", "_") + .ToLower(); /// /// Replaces underscores with dashes in the string @@ -90,5 +98,6 @@ public static string Hyphenate(this string underscoredWord) => /// Separates the input words with hyphens and all the words are converted to lowercase /// public static string Kebaberize(this string input) => - Underscore(input).Dasherize(); + Underscore(input) + .Dasherize(); } \ No newline at end of file diff --git a/src/Humanizer/Localisation/CollectionFormatters/DefaultCollectionFormatter.cs b/src/Humanizer/Localisation/CollectionFormatters/DefaultCollectionFormatter.cs index 1daf9ee11..87d04e4d5 100644 --- a/src/Humanizer/Localisation/CollectionFormatters/DefaultCollectionFormatter.cs +++ b/src/Humanizer/Localisation/CollectionFormatters/DefaultCollectionFormatter.cs @@ -21,65 +21,69 @@ public virtual string Humanize(IEnumerable collection, string separator) = public virtual string Humanize(IEnumerable collection, Func objectFormatter, string separator) { - if (collection == null) - { - throw new ArgumentNullException(nameof(collection)); - } - - if (objectFormatter == null) - { - throw new ArgumentNullException(nameof(objectFormatter)); - } - - return HumanizeDisplayStrings( - collection.Select(objectFormatter), - separator); + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); } + if (objectFormatter == null) + { + throw new ArgumentNullException(nameof(objectFormatter)); + } + + return HumanizeDisplayStrings( + collection.Select(objectFormatter), + separator); + } + public string Humanize(IEnumerable collection, Func objectFormatter, string separator) { - if (collection == null) - { - throw new ArgumentNullException(nameof(collection)); - } - - if (objectFormatter == null) - { - throw new ArgumentNullException(nameof(objectFormatter)); - } - - return HumanizeDisplayStrings( - collection.Select(objectFormatter).Select(o => o?.ToString()), - separator); + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); } + if (objectFormatter == null) + { + throw new ArgumentNullException(nameof(objectFormatter)); + } + + return HumanizeDisplayStrings( + collection + .Select(objectFormatter) + .Select(o => o?.ToString()), + separator); + } + string HumanizeDisplayStrings(IEnumerable strings, string separator) { - var itemsArray = strings - .Select(item => item == null ? string.Empty : item.Trim()) - .Where(item => !string.IsNullOrWhiteSpace(item)) - .ToArray(); - - var count = itemsArray.Length; - - if (count == 0) - { - return ""; - } - - if (count == 1) - { - return itemsArray[0]; - } - - var itemsBeforeLast = itemsArray.Take(count - 1); - var lastItem = itemsArray.Skip(count - 1).First(); - - return string.Format(GetConjunctionFormatString(count), - string.Join(", ", itemsBeforeLast), - separator, - lastItem); + var itemsArray = strings + .Select(item => item == null ? string.Empty : item.Trim()) + .Where(item => !string.IsNullOrWhiteSpace(item)) + .ToArray(); + + var count = itemsArray.Length; + + if (count == 0) + { + return ""; + } + + if (count == 1) + { + return itemsArray[0]; } + var itemsBeforeLast = itemsArray.Take(count - 1); + var lastItem = itemsArray + .Skip(count - 1) + .First(); + + return string.Format(GetConjunctionFormatString(count), + string.Join(", ", itemsBeforeLast), + separator, + lastItem); + } + protected virtual string GetConjunctionFormatString(int itemCount) => "{0} {1} {2}"; } \ No newline at end of file diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/DefaultDateOnlyToOrdinalWordConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/DefaultDateOnlyToOrdinalWordConverter.cs index aec5d5d10..24ae99819 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/DefaultDateOnlyToOrdinalWordConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/DefaultDateOnlyToOrdinalWordConverter.cs @@ -1,15 +1,14 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class DefaultDateOnlyToOrdinalWordConverter : IDateOnlyToOrdinalWordConverter { - class DefaultDateOnlyToOrdinalWordConverter : IDateOnlyToOrdinalWordConverter - { - public virtual string Convert(DateOnly date) => - date.Day.Ordinalize() + date.ToString(" MMMM yyyy"); - - public virtual string Convert(DateOnly date, GrammaticalCase grammaticalCase) => - Convert(date); - } + public virtual string Convert(DateOnly date) => + date.Day.Ordinalize() + date.ToString(" MMMM yyyy"); + + public virtual string Convert(DateOnly date, GrammaticalCase grammaticalCase) => + Convert(date); } #endif diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/EsDateOnlyToOrdinalWordsConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/EsDateOnlyToOrdinalWordsConverter.cs index a86d69687..79046bc80 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/EsDateOnlyToOrdinalWordsConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/EsDateOnlyToOrdinalWordsConverter.cs @@ -1,14 +1,13 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class EsDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter { - class EsDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter + public override string Convert(DateOnly date) { - public override string Convert(DateOnly date) - { - var equivalentDateTime = date.ToDateTime(TimeOnly.MinValue); - return Configurator.DateToOrdinalWordsConverter.Convert(equivalentDateTime); - } + var equivalentDateTime = date.ToDateTime(TimeOnly.MinValue); + return Configurator.DateToOrdinalWordsConverter.Convert(equivalentDateTime); } } diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/FrDateOnlyToOrdinalWordsConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/FrDateOnlyToOrdinalWordsConverter.cs index bce7e9424..3c07138bd 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/FrDateOnlyToOrdinalWordsConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/FrDateOnlyToOrdinalWordsConverter.cs @@ -1,14 +1,13 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class FrDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter { - class FrDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter + public override string Convert(DateOnly date) { - public override string Convert(DateOnly date) - { - var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize(); - return day + date.ToString(" MMMM yyyy"); - } + var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize(); + return day + date.ToString(" MMMM yyyy"); } } #endif diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/FrDateToOrdinalWordsConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/FrDateToOrdinalWordsConverter.cs index c2333c466..f0890bfa4 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/FrDateToOrdinalWordsConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/FrDateToOrdinalWordsConverter.cs @@ -4,7 +4,7 @@ class FrDateToOrdinalWordsConverter : DefaultDateToOrdinalWordConverter { public override string Convert(DateTime date) { - var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize(); - return day + date.ToString(" MMMM yyyy"); - } + var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize(); + return day + date.ToString(" MMMM yyyy"); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/IDateOnlyToOrdinalWordConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/IDateOnlyToOrdinalWordConverter.cs index 7ba40fd99..9a5cb1511 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/IDateOnlyToOrdinalWordConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/IDateOnlyToOrdinalWordConverter.cs @@ -1,21 +1,20 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// The interface used to localise the ToOrdinalWords method. +/// +public interface IDateOnlyToOrdinalWordConverter { /// - /// The interface used to localise the ToOrdinalWords method. + /// Converts the date to Ordinal Words /// - public interface IDateOnlyToOrdinalWordConverter - { - /// - /// Converts the date to Ordinal Words - /// - string Convert(DateOnly date); + string Convert(DateOnly date); - /// - /// Converts the date to Ordinal Words using the provided grammatical case - /// - string Convert(DateOnly date, GrammaticalCase grammaticalCase); - } + /// + /// Converts the date to Ordinal Words using the provided grammatical case + /// + string Convert(DateOnly date, GrammaticalCase grammaticalCase); } #endif diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/LtDateOnlyToOrdinalWordsConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/LtDateOnlyToOrdinalWordsConverter.cs index 9423e3d6e..83f01e0f4 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/LtDateOnlyToOrdinalWordsConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/LtDateOnlyToOrdinalWordsConverter.cs @@ -1,14 +1,13 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class LtDateOnlyToOrdinalWordsConverter : IDateOnlyToOrdinalWordConverter { - class LtDateOnlyToOrdinalWordsConverter : IDateOnlyToOrdinalWordConverter - { - public string Convert(DateOnly date) => - date.ToString("yyyy 'm.' MMMM d 'd.'"); + public string Convert(DateOnly date) => + date.ToString("yyyy 'm.' MMMM d 'd.'"); - public string Convert(DateOnly date, GrammaticalCase grammaticalCase) => - Convert(date); - } + public string Convert(DateOnly date, GrammaticalCase grammaticalCase) => + Convert(date); } #endif diff --git a/src/Humanizer/Localisation/DateToOrdinalWords/UsDateOnlyToOrdinalWordsConverter.cs b/src/Humanizer/Localisation/DateToOrdinalWords/UsDateOnlyToOrdinalWordsConverter.cs index 20e73b9df..a0adb4db9 100644 --- a/src/Humanizer/Localisation/DateToOrdinalWords/UsDateOnlyToOrdinalWordsConverter.cs +++ b/src/Humanizer/Localisation/DateToOrdinalWords/UsDateOnlyToOrdinalWordsConverter.cs @@ -1,11 +1,10 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class UsDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter { - class UsDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter - { - public override string Convert(DateOnly date) => - date.ToString("MMMM ") + date.Day.Ordinalize() + date.ToString(", yyyy"); - } + public override string Convert(DateOnly date) => + date.ToString("MMMM ") + date.Day.Ordinalize() + date.ToString(", yyyy"); } #endif diff --git a/src/Humanizer/Localisation/Formatters/ArabicFormatter.cs b/src/Humanizer/Localisation/Formatters/ArabicFormatter.cs index 390151db6..96164fb03 100644 --- a/src/Humanizer/Localisation/Formatters/ArabicFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/ArabicFormatter.cs @@ -8,18 +8,18 @@ class ArabicFormatter() : protected override string GetResourceKey(string resourceKey, int number) { - //In Arabic pluralization 2 entities gets a different word. - if (number == 2) - { - return resourceKey + DualPostfix; - } - - //In Arabic pluralization entities where the count is between 3 and 10 gets a different word. - if (number is >= 3 and <= 10) - { - return resourceKey + PluralPostfix; - } + //In Arabic pluralization 2 entities gets a different word. + if (number == 2) + { + return resourceKey + DualPostfix; + } - return resourceKey; + //In Arabic pluralization entities where the count is between 3 and 10 gets a different word. + if (number is >= 3 and <= 10) + { + return resourceKey + PluralPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/CroatianFormatter.cs b/src/Humanizer/Localisation/Formatters/CroatianFormatter.cs index d99e79236..6e9976543 100644 --- a/src/Humanizer/Localisation/Formatters/CroatianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/CroatianFormatter.cs @@ -7,12 +7,12 @@ class CroatianFormatter() : protected override string GetResourceKey(string resourceKey, int number) { - var mod10 = number % 10; - if (mod10 is > 1 and < 5 && number != 12 && number != 13 && number != 14) - { - return resourceKey + PaucalPostfix; - } - - return resourceKey; + var mod10 = number % 10; + if (mod10 is > 1 and < 5 && number != 12 && number != 13 && number != 14) + { + return resourceKey + PaucalPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/CzechSlovakPolishFormatter.cs b/src/Humanizer/Localisation/Formatters/CzechSlovakPolishFormatter.cs index 65ca8f415..edacdd327 100644 --- a/src/Humanizer/Localisation/Formatters/CzechSlovakPolishFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/CzechSlovakPolishFormatter.cs @@ -7,11 +7,11 @@ class CzechSlovakPolishFormatter(string localeCode) : protected override string GetResourceKey(string resourceKey, int number) { - if (number is > 1 and < 5) - { - return resourceKey + PaucalPostfix; - } - - return resourceKey; + if (number is > 1 and < 5) + { + return resourceKey + PaucalPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs index 2c1df2c01..d20f48d3a 100644 --- a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs @@ -41,41 +41,41 @@ public virtual string TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords /// public virtual string TimeSpanHumanize_Age() { - if (Resources.TryGetResource("TimeSpanHumanize_Age", _culture, out var ageFormat)) - return ageFormat; - return "{0}"; - } + if (Resources.TryGetResource("TimeSpanHumanize_Age", _culture, out var ageFormat)) + return ageFormat; + return "{0}"; + } /// public virtual string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true) { - var resourceKey = toSymbol ? $"DataUnit_{dataUnit}Symbol" : $"DataUnit_{dataUnit}"; - var resourceValue = Format(resourceKey); + var resourceKey = toSymbol ? $"DataUnit_{dataUnit}Symbol" : $"DataUnit_{dataUnit}"; + var resourceValue = Format(resourceKey); - if (!toSymbol && count > 1) - resourceValue += 's'; + if (!toSymbol && count > 1) + resourceValue += 's'; - return resourceValue; - } + return resourceValue; + } /// public virtual string TimeUnitHumanize(TimeUnit timeUnit) { - var resourceKey = ResourceKeys.TimeUnitSymbol.GetResourceKey(timeUnit); - return Format(resourceKey); - } + var resourceKey = ResourceKeys.TimeUnitSymbol.GetResourceKey(timeUnit); + return Format(resourceKey); + } string GetResourceForDate(TimeUnit unit, Tense timeUnitTense, int count) { - var resourceKey = ResourceKeys.DateHumanize.GetResourceKey(unit, timeUnitTense: timeUnitTense, count: count); - return count == 1 ? Format(resourceKey) : Format(resourceKey, count); - } + var resourceKey = ResourceKeys.DateHumanize.GetResourceKey(unit, timeUnitTense: timeUnitTense, count: count); + return count == 1 ? Format(resourceKey) : Format(resourceKey, count); + } string GetResourceForTimeSpan(TimeUnit unit, int count, bool toWords = false) { - var resourceKey = ResourceKeys.TimeSpanHumanize.GetResourceKey(unit, count, toWords); - return count == 1 ? Format(resourceKey + (toWords ? "_Words" : "")) : Format(resourceKey, count, toWords); - } + var resourceKey = ResourceKeys.TimeSpanHumanize.GetResourceKey(unit, count, toWords); + return count == 1 ? Format(resourceKey + (toWords ? "_Words" : "")) : Format(resourceKey, count, toWords); + } /// /// Formats the specified resource key. @@ -84,9 +84,9 @@ string GetResourceForTimeSpan(TimeUnit unit, int count, bool toWords = false) /// If the resource not exists on the specified culture. protected virtual string Format(string resourceKey) { - var resolvedKey = GetResourceKey(resourceKey); - return Resources.GetResource(resolvedKey, _culture); - } + var resolvedKey = GetResourceKey(resourceKey); + return Resources.GetResource(resolvedKey, _culture); + } /// /// Formats the specified resource key. @@ -96,17 +96,17 @@ protected virtual string Format(string resourceKey) /// If the resource not exists on the specified culture. protected virtual string Format(string resourceKey, int number, bool toWords = false) { - var resolvedKey = GetResourceKey(resourceKey, number); - var resourceString = Resources.GetResource(resolvedKey, _culture); + var resolvedKey = GetResourceKey(resourceKey, number); + var resourceString = Resources.GetResource(resolvedKey, _culture); - if (toWords) - { - return string.Format(resourceString, number.ToWords(_culture)); - } - - return string.Format(resourceString, number); + if (toWords) + { + return string.Format(resourceString, number.ToWords(_culture)); } + return string.Format(resourceString, number); + } + /// /// Override this method if your locale has complex rules around multiple units; e.g. Arabic, Russian /// diff --git a/src/Humanizer/Localisation/Formatters/FrenchFormatter.cs b/src/Humanizer/Localisation/Formatters/FrenchFormatter.cs index 5fb21b85c..8b0d98e4a 100644 --- a/src/Humanizer/Localisation/Formatters/FrenchFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/FrenchFormatter.cs @@ -7,16 +7,16 @@ class FrenchFormatter(string localeCode) : protected override string GetResourceKey(string resourceKey, int number) { - if (number == 2 && resourceKey is "DateHumanize_MultipleDaysAgo" or "DateHumanize_MultipleDaysFromNow") - { - return resourceKey + DualPostfix; - } - - if (number == 0 && resourceKey.StartsWith("TimeSpanHumanize_Multiple")) - { - return resourceKey + "_Singular"; - } + if (number == 2 && resourceKey is "DateHumanize_MultipleDaysAgo" or "DateHumanize_MultipleDaysFromNow") + { + return resourceKey + DualPostfix; + } - return resourceKey; + if (number == 0 && resourceKey.StartsWith("TimeSpanHumanize_Multiple")) + { + return resourceKey + "_Singular"; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs b/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs index a3e38ca6a..98d7eae01 100644 --- a/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs @@ -8,19 +8,19 @@ class HebrewFormatter() : protected override string GetResourceKey(string resourceKey, int number) { - //In Hebrew pluralization 2 entities gets a different word. - if (number == 2) - { - return resourceKey + DualPostfix; - } - - //In Hebrew pluralization entities where the count is between 3 and 10 gets a different word. - //See http://lib.cet.ac.il/pages/item.asp?item=21585 for explanation - if (number is >= 3 and <= 10) - { - return resourceKey + PluralPostfix; - } + //In Hebrew pluralization 2 entities gets a different word. + if (number == 2) + { + return resourceKey + DualPostfix; + } - return resourceKey; + //In Hebrew pluralization entities where the count is between 3 and 10 gets a different word. + //See http://lib.cet.ac.il/pages/item.asp?item=21585 for explanation + if (number is >= 3 and <= 10) + { + return resourceKey + PluralPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/LithuanianFormatter.cs b/src/Humanizer/Localisation/Formatters/LithuanianFormatter.cs index 12ddffe20..5e7e4ab3b 100644 --- a/src/Humanizer/Localisation/Formatters/LithuanianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/LithuanianFormatter.cs @@ -5,28 +5,28 @@ class LithuanianFormatter() : { protected override string GetResourceKey(string resourceKey, int number) { - if (resourceKey == "TimeSpanHumanize_Zero") - { - return resourceKey; - } - - var grammaticalNumber = LithuanianNumberFormDetector.Detect(number); - var suffix = GetSuffix(grammaticalNumber); - return resourceKey + suffix; + if (resourceKey == "TimeSpanHumanize_Zero") + { + return resourceKey; } + var grammaticalNumber = LithuanianNumberFormDetector.Detect(number); + var suffix = GetSuffix(grammaticalNumber); + return resourceKey + suffix; + } + static string GetSuffix(LithuanianNumberForm form) { - if (form == LithuanianNumberForm.Singular) - { - return "_Singular"; - } - - if (form == LithuanianNumberForm.GenitivePlural) - { - return "_Plural"; - } + if (form == LithuanianNumberForm.Singular) + { + return "_Singular"; + } - return ""; + if (form == LithuanianNumberForm.GenitivePlural) + { + return "_Plural"; } + + return ""; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/MalteseFormatter.cs b/src/Humanizer/Localisation/Formatters/MalteseFormatter.cs index a260b58ed..891403344 100644 --- a/src/Humanizer/Localisation/Formatters/MalteseFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/MalteseFormatter.cs @@ -7,7 +7,7 @@ class MalteseFormatter(string localeCode) : static readonly string[] DualResourceKeys = [ - "DateHumanize_MultipleDaysAgo", "DateHumanize_MultipleDaysFromNow", "DateHumanize_MultipleHoursAgo", "DateHumanize_MultipleHoursFromNow" , + "DateHumanize_MultipleDaysAgo", "DateHumanize_MultipleDaysFromNow", "DateHumanize_MultipleHoursAgo", "DateHumanize_MultipleHoursFromNow", "DateHumanize_MultipleMonthsAgo", "DateHumanize_MultipleMonthsFromNow", "DateHumanize_MultipleYearsAgo", "DateHumanize_MultipleYearsFromNow", "TimeSpanHumanize_MultipleDays", "TimeSpanHumanize_MultipleYears", "TimeSpanHumanize_MultipleMonths", "TimeSpanHumanize_MultipleHours", "TimeSpanHumanize_MultipleWeeks" @@ -15,11 +15,11 @@ class MalteseFormatter(string localeCode) : protected override string GetResourceKey(string resourceKey, int number) { - if (number == 2 && DualResourceKeys.Contains(resourceKey)) - { - return resourceKey + DualPostfix; - } - - return resourceKey; + if (number == 2 && DualResourceKeys.Contains(resourceKey)) + { + return resourceKey + DualPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/RussianFormatter.cs b/src/Humanizer/Localisation/Formatters/RussianFormatter.cs index 8e0d75117..d59c464e8 100644 --- a/src/Humanizer/Localisation/Formatters/RussianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/RussianFormatter.cs @@ -5,23 +5,23 @@ class RussianFormatter() : { protected override string GetResourceKey(string resourceKey, int number) { - var grammaticalNumber = RussianGrammaticalNumberDetector.Detect(number); - var suffix = GetSuffix(grammaticalNumber); - return resourceKey + suffix; - } + var grammaticalNumber = RussianGrammaticalNumberDetector.Detect(number); + var suffix = GetSuffix(grammaticalNumber); + return resourceKey + suffix; + } static string GetSuffix(RussianGrammaticalNumber grammaticalNumber) { - if (grammaticalNumber == RussianGrammaticalNumber.Singular) - { - return "_Singular"; - } - - if (grammaticalNumber == RussianGrammaticalNumber.Paucal) - { - return "_Paucal"; - } + if (grammaticalNumber == RussianGrammaticalNumber.Singular) + { + return "_Singular"; + } - return ""; + if (grammaticalNumber == RussianGrammaticalNumber.Paucal) + { + return "_Paucal"; } + + return ""; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/SerbianFormatter.cs b/src/Humanizer/Localisation/Formatters/SerbianFormatter.cs index 5805a9daa..f8dfa6913 100644 --- a/src/Humanizer/Localisation/Formatters/SerbianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/SerbianFormatter.cs @@ -7,12 +7,12 @@ class SerbianFormatter(string localeCode) : protected override string GetResourceKey(string resourceKey, int number) { - var mod10 = number % 10; - if (mod10 is > 1 and < 5) - { - return resourceKey + PaucalPostfix; - } - - return resourceKey; + var mod10 = number % 10; + if (mod10 is > 1 and < 5) + { + return resourceKey + PaucalPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/SlovenianFormatter.cs b/src/Humanizer/Localisation/Formatters/SlovenianFormatter.cs index 15aea4f05..9ec7c9edb 100644 --- a/src/Humanizer/Localisation/Formatters/SlovenianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/SlovenianFormatter.cs @@ -8,17 +8,17 @@ class SlovenianFormatter() : protected override string GetResourceKey(string resourceKey, int number) { - if (number == 2) - { - return resourceKey + DualPostfix; - } - - // When the count is three or four some some words have a different form when counting in Slovenian language - if (number is 3 or 4) - { - return resourceKey + TrialQuadralPostfix; - } + if (number == 2) + { + return resourceKey + DualPostfix; + } - return resourceKey; + // When the count is three or four some some words have a different form when counting in Slovenian language + if (number is 3 or 4) + { + return resourceKey + TrialQuadralPostfix; } + + return resourceKey; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs b/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs index ab7da5176..8e6e2bc7c 100644 --- a/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs @@ -4,23 +4,23 @@ class UkrainianFormatter() : DefaultFormatter("uk") { protected override string GetResourceKey(string resourceKey, int number) { - var grammaticalNumber = RussianGrammaticalNumberDetector.Detect(number); - var suffix = GetSuffix(grammaticalNumber); - return resourceKey + suffix; - } + var grammaticalNumber = RussianGrammaticalNumberDetector.Detect(number); + var suffix = GetSuffix(grammaticalNumber); + return resourceKey + suffix; + } static string GetSuffix(RussianGrammaticalNumber grammaticalNumber) { - if (grammaticalNumber == RussianGrammaticalNumber.Singular) - { - return "_Singular"; - } - - if (grammaticalNumber == RussianGrammaticalNumber.Paucal) - { - return "_Paucal"; - } + if (grammaticalNumber == RussianGrammaticalNumber.Singular) + { + return "_Singular"; + } - return ""; + if (grammaticalNumber == RussianGrammaticalNumber.Paucal) + { + return "_Paucal"; } + + return ""; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/GrammaticalNumber/RussianGrammaticalNumberDetector.cs b/src/Humanizer/Localisation/GrammaticalNumber/RussianGrammaticalNumberDetector.cs index 648b1d896..76f93376d 100644 --- a/src/Humanizer/Localisation/GrammaticalNumber/RussianGrammaticalNumberDetector.cs +++ b/src/Humanizer/Localisation/GrammaticalNumber/RussianGrammaticalNumberDetector.cs @@ -4,22 +4,22 @@ static class RussianGrammaticalNumberDetector { public static RussianGrammaticalNumber Detect(long number) { - var tens = number % 100 / 10; - if (tens != 1) - { - var unity = number % 10; - - if (unity == 1) // 1, 21, 31, 41 ... 91, 101, 121 ... - { - return RussianGrammaticalNumber.Singular; - } + var tens = number % 100 / 10; + if (tens != 1) + { + var unity = number % 10; - if (unity is > 1 and < 5) // 2, 3, 4, 22, 23, 24 ... - { - return RussianGrammaticalNumber.Paucal; - } + if (unity == 1) // 1, 21, 31, 41 ... 91, 101, 121 ... + { + return RussianGrammaticalNumber.Singular; } - return RussianGrammaticalNumber.Plural; + if (unity is > 1 and < 5) // 2, 3, 4, 22, 23, 24 ... + { + return RussianGrammaticalNumber.Paucal; + } } + + return RussianGrammaticalNumber.Plural; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/AfrikaansNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/AfrikaansNumberToWordsConverter.cs index 44b3ab395..0a2e5b5cc 100644 --- a/src/Humanizer/Localisation/NumberToWords/AfrikaansNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/AfrikaansNumberToWordsConverter.cs @@ -8,150 +8,172 @@ class AfrikaansNumberToWordsConverter : static readonly Dictionary OrdinalExceptions = new() { - {0, "nulste"}, - {1, "eerste"}, - {3, "derde"}, - {7, "sewende"}, - {8, "agste"}, - {9, "negende"}, - {10, "tiende"}, - {14, "veertiende"}, - {17, "sewentiende"}, - {19, "negentiende"} + { + 0, "nulste" + }, + { + 1, "eerste" + }, + { + 3, "derde" + }, + { + 7, "sewende" + }, + { + 8, "agste" + }, + { + 9, "negende" + }, + { + 10, "tiende" + }, + { + 14, "veertiende" + }, + { + 17, "sewentiende" + }, + { + 19, "negentiende" + } }; public override string Convert(long number) { - if (number is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - return Convert((int)number, false); + if (number is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); } + return Convert((int) number, false); + } + public override string ConvertToOrdinal(int number) => Convert(number, true); string Convert(int number, bool isOrdinal) { - if (number == 0) - { - return GetUnitValue(0, isOrdinal); - } + if (number == 0) + { + return GetUnitValue(0, isOrdinal); + } - if (number < 0) - { - return $"minus {Convert(-number)}"; - } + if (number < 0) + { + return $"minus {Convert(-number)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000)} miljard"); - number %= 1000000000; - } + if (number / 1000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000)} miljard"); + number %= 1000000000; + } - if (number / 1000000 > 0) - { - parts.Add($"{Convert(number / 1000000)} miljoen"); - number %= 1000000; - } + if (number / 1000000 > 0) + { + parts.Add($"{Convert(number / 1000000)} miljoen"); + number %= 1000000; + } - if (number / 1000 > 0) - { - parts.Add($"{Convert(number / 1000)} duisend"); - number %= 1000; - } + if (number / 1000 > 0) + { + parts.Add($"{Convert(number / 1000)} duisend"); + number %= 1000; + } - if (number / 100 > 0) - { - parts.Add($"{Convert(number / 100)} honderd"); - number %= 100; - } + if (number / 100 > 0) + { + parts.Add($"{Convert(number / 100)} honderd"); + number %= 100; + } - if (number > 0) - { - //if (parts.Count != 0) - // parts.Add("en"); + if (number > 0) + { + //if (parts.Count != 0) + // parts.Add("en"); - if (number < 20) + if (number < 20) + { + if (parts.Count > 0) { - if (parts.Count > 0) - { - parts.Add("en"); - } + parts.Add("en"); + } - parts.Add(GetUnitValue(number, isOrdinal)); + parts.Add(GetUnitValue(number, isOrdinal)); + } + else + { + var lastPartValue = number / 10 * 10; + var lastPart = TensMap[number / 10]; + if (number % 10 > 0) + { + lastPart = $"{GetUnitValue(number % 10, false)} en {(isOrdinal ? GetUnitValue(lastPartValue, true) : lastPart)}"; } - else + else if (number % 10 == 0) { - var lastPartValue = number / 10 * 10; - var lastPart = TensMap[number / 10]; - if (number % 10 > 0) - { - lastPart = $"{GetUnitValue(number % 10, false)} en {(isOrdinal ? GetUnitValue(lastPartValue, true) : lastPart)}"; - } - else if (number % 10 == 0) - { - lastPart = $"{(parts.Count > 0 ? "en " : "")}{lastPart}{(isOrdinal ? "ste" : "")}"; - } - else if (isOrdinal) - { - lastPart = lastPart.TrimEnd('~') + "ste"; - } - - parts.Add(lastPart); + lastPart = $"{(parts.Count > 0 ? "en " : "")}{lastPart}{(isOrdinal ? "ste" : "")}"; + } + else if (isOrdinal) + { + lastPart = lastPart.TrimEnd('~') + "ste"; } - } - else if (isOrdinal) - { - parts[^1] += "ste"; - } - - var toWords = string.Join(" ", parts); - if (isOrdinal) - { - toWords = RemoveOnePrefix(toWords); + parts.Add(lastPart); } + } + else if (isOrdinal) + { + parts[^1] += "ste"; + } + + var toWords = string.Join(" ", parts); - return toWords; + if (isOrdinal) + { + toWords = RemoveOnePrefix(toWords); } + return toWords; + } + static string GetUnitValue(int number, bool isOrdinal) { - if (isOrdinal) + if (isOrdinal) + { + if (ExceptionNumbersToWords(number, out var exceptionString)) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } + return exceptionString; + } - if (number > 19) - { - return TensMap[number / 10] + "ste"; - } - return UnitsMap[number] + "de"; + if (number > 19) + { + return TensMap[number / 10] + "ste"; } - return UnitsMap[number]; + return UnitsMap[number] + "de"; } + return UnitsMap[number]; + } + static string RemoveOnePrefix(string toWords) { - // one hundred => hundredth - if (toWords.StartsWith("een", StringComparison.Ordinal)) + // one hundred => hundredth + if (toWords.StartsWith("een", StringComparison.Ordinal)) + { + if (toWords.IndexOf("een en", StringComparison.Ordinal) != 0) { - if (toWords.IndexOf("een en", StringComparison.Ordinal) != 0) - { - toWords = toWords.Remove(0, 4); - } + toWords = toWords.Remove(0, 4); } - - return toWords; } + return toWords; + } + static bool ExceptionNumbersToWords(int number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/ArabicNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/ArabicNumberToWordsConverter.cs index fffd79ba1..250c7fb35 100644 --- a/src/Humanizer/Localisation/NumberToWords/ArabicNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/ArabicNumberToWordsConverter.cs @@ -16,246 +16,294 @@ class ArabicNumberToWordsConverter : public override string Convert(long number, GrammaticalGender gender, bool addAnd = true) { - if (number == 0) - { - return "صفر"; - } + if (number == 0) + { + return "صفر"; + } - if (number < 0) - { - return $"ناقص {Convert(-number, gender)}"; - } + if (number < 0) + { + return $"ناقص {Convert(-number, gender)}"; + } - var result = string.Empty; - var groupLevel = 0; + var result = string.Empty; + var groupLevel = 0; - while (number >= 1) - { - var groupNumber = number % 1000; - number /= 1000; + while (number >= 1) + { + var groupNumber = number % 1000; + number /= 1000; - var tens = groupNumber % 100; - var hundreds = groupNumber / 100; - var process = string.Empty; + var tens = groupNumber % 100; + var hundreds = groupNumber / 100; + var process = string.Empty; - if (hundreds > 0) + if (hundreds > 0) + { + if (tens == 0 && hundreds == 2) { - if (tens == 0 && hundreds == 2) - { - process = AppendedTwos[0]; - } - else - { - process = HundredsGroup[hundreds]; - } + process = AppendedTwos[0]; + } + else + { + process = HundredsGroup[hundreds]; } + } - if (tens > 0) + if (tens > 0) + { + if (tens < 20) { - if (tens < 20) + if (tens == 2 && hundreds == 0 && groupLevel > 0) { - if (tens == 2 && hundreds == 0 && groupLevel > 0) + if (number is 2000 or 2000000 or 2000000000) { - if (number is 2000 or 2000000 or 2000000000) - { - process = AppendedTwos[groupLevel]; - } - else - { - process = Twos[groupLevel]; - } + process = AppendedTwos[groupLevel]; } else { - if (process != string.Empty) - { - process += " و "; - } - - if (tens == 1 && groupLevel > 0 && hundreds == 0) - { - process += " "; - } - else - { - process += gender == GrammaticalGender.Feminine && groupLevel == 0 ? FeminineOnesGroup[tens] : OnesGroup[tens]; - } + process = Twos[groupLevel]; } } else { - var ones = tens % 10; - tens /= 10; - - if (ones > 0) + if (process != string.Empty) { - if (process != string.Empty) - { - process += " و "; - } + process += " و "; + } - process += gender == GrammaticalGender.Feminine ? FeminineOnesGroup[ones] : OnesGroup[ones]; + if (tens == 1 && groupLevel > 0 && hundreds == 0) + { + process += " "; + } + else + { + process += gender == GrammaticalGender.Feminine && groupLevel == 0 ? FeminineOnesGroup[tens] : OnesGroup[tens]; } + } + } + else + { + var ones = tens % 10; + tens /= 10; + if (ones > 0) + { if (process != string.Empty) { process += " و "; } - process += TensGroup[tens]; + process += gender == GrammaticalGender.Feminine ? FeminineOnesGroup[ones] : OnesGroup[ones]; + } + + if (process != string.Empty) + { + process += " و "; } + + process += TensGroup[tens]; } + } - if (process != string.Empty) + if (process != string.Empty) + { + if (groupLevel > 0) { - if (groupLevel > 0) + if (result != string.Empty) { - if (result != string.Empty) - { - result = $"و {result}"; - } + result = $"و {result}"; + } - if (groupNumber != 2) + if (groupNumber != 2) + { + if (groupNumber % 100 != 1) { - if (groupNumber % 100 != 1) + if (groupNumber is >= 3 and <= 10) { - if (groupNumber is >= 3 and <= 10) - { - result = $"{PluralGroups[groupLevel]} {result}"; - } - else - { - result = $"{(result != string.Empty ? AppendedGroups[groupLevel] : Groups[groupLevel])} {result}"; - } + result = $"{PluralGroups[groupLevel]} {result}"; } else { - result = $"{Groups[groupLevel]} {result}"; + result = $"{(result != string.Empty ? AppendedGroups[groupLevel] : Groups[groupLevel])} {result}"; } } + else + { + result = $"{Groups[groupLevel]} {result}"; + } } - - result = $"{process} {result}"; } - groupLevel++; + result = $"{process} {result}"; } - return result.Trim(); + groupLevel++; } + return result.Trim(); + } + static readonly Dictionary OrdinalExceptions = new() { - {"واحد", "الحادي"}, - {"أحد", "الحادي"}, - {"اثنان", "الثاني"}, - {"اثنا", "الثاني"}, - {"ثلاثة", "الثالث"}, - {"أربعة", "الرابع"}, - {"خمسة", "الخامس"}, - {"ستة", "السادس"}, - {"سبعة", "السابع"}, - {"ثمانية", "الثامن"}, - {"تسعة", "التاسع"}, - {"عشرة", "العاشر"}, + { + "واحد", "الحادي" + }, + { + "أحد", "الحادي" + }, + { + "اثنان", "الثاني" + }, + { + "اثنا", "الثاني" + }, + { + "ثلاثة", "الثالث" + }, + { + "أربعة", "الرابع" + }, + { + "خمسة", "الخامس" + }, + { + "ستة", "السادس" + }, + { + "سبعة", "السابع" + }, + { + "ثمانية", "الثامن" + }, + { + "تسعة", "التاسع" + }, + { + "عشرة", "العاشر" + }, }; static readonly Dictionary FeminineOrdinalExceptions = new() { - {"واحدة", "الحادية"}, - {"إحدى", "الحادية"}, - {"اثنتان", "الثانية"}, - {"اثنتا", "الثانية"}, - {"ثلاث", "الثالثة"}, - {"أربع", "الرابعة"}, - {"خمس", "الخامسة"}, - {"ست", "السادسة"}, - {"سبع", "السابعة"}, - {"ثمان", "الثامنة"}, - {"تسع", "التاسعة"}, - {"عشر", "العاشرة"}, + { + "واحدة", "الحادية" + }, + { + "إحدى", "الحادية" + }, + { + "اثنتان", "الثانية" + }, + { + "اثنتا", "الثانية" + }, + { + "ثلاث", "الثالثة" + }, + { + "أربع", "الرابعة" + }, + { + "خمس", "الخامسة" + }, + { + "ست", "السادسة" + }, + { + "سبع", "السابعة" + }, + { + "ثمان", "الثامنة" + }, + { + "تسع", "التاسعة" + }, + { + "عشر", "العاشرة" + }, }; public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - if (number == 0) - { - return "الصفر"; - } - - var beforeOneHundredNumber = number % 100; - var overTensPart = number / 100 * 100; - var beforeOneHundredWord = string.Empty; - var overTensWord = string.Empty; + if (number == 0) + { + return "الصفر"; + } - if (beforeOneHundredNumber > 0) - { - beforeOneHundredWord = Convert(beforeOneHundredNumber, gender); - beforeOneHundredWord = ParseNumber(beforeOneHundredWord, beforeOneHundredNumber, gender); - } + var beforeOneHundredNumber = number % 100; + var overTensPart = number / 100 * 100; + var beforeOneHundredWord = string.Empty; + var overTensWord = string.Empty; - if (overTensPart > 0) - { - overTensWord = Convert(overTensPart); - overTensWord = ParseNumber(overTensWord, overTensPart, gender); - } + if (beforeOneHundredNumber > 0) + { + beforeOneHundredWord = Convert(beforeOneHundredNumber, gender); + beforeOneHundredWord = ParseNumber(beforeOneHundredWord, beforeOneHundredNumber, gender); + } - var word = beforeOneHundredWord + - (overTensPart > 0 - ? (string.IsNullOrWhiteSpace(beforeOneHundredWord) ? string.Empty : " بعد ") + overTensWord - : string.Empty); - return word.Trim(); + if (overTensPart > 0) + { + overTensWord = Convert(overTensPart); + overTensWord = ParseNumber(overTensWord, overTensPart, gender); } + var word = beforeOneHundredWord + + (overTensPart > 0 + ? (string.IsNullOrWhiteSpace(beforeOneHundredWord) ? string.Empty : " بعد ") + overTensWord + : string.Empty); + return word.Trim(); + } + static string ParseNumber(string word, int number, GrammaticalGender gender) { - if (number == 1) + if (number == 1) + { + return gender == GrammaticalGender.Feminine ? "الأولى" : "الأول"; + } + + if (number <= 10) + { + var ordinals = gender == GrammaticalGender.Feminine ? FeminineOrdinalExceptions : OrdinalExceptions; + foreach (var kv in ordinals.Where(kv => word.EndsWith(kv.Key))) { - return gender == GrammaticalGender.Feminine ? "الأولى" : "الأول"; + // replace word with exception + return word.Substring(0, word.Length - kv.Key.Length) + kv.Value; } + } + else if (number is > 10 and < 100) + { + var parts = word.Split(' '); + var newParts = new string[parts.Length]; + var count = 0; - if (number <= 10) + foreach (var part in parts) { + var newPart = part; + var oldPart = part; + var ordinals = gender == GrammaticalGender.Feminine ? FeminineOrdinalExceptions : OrdinalExceptions; - foreach (var kv in ordinals.Where(kv => word.EndsWith(kv.Key))) + foreach (var kv in ordinals.Where(kv => oldPart.EndsWith(kv.Key))) { // replace word with exception - return word.Substring(0, word.Length - kv.Key.Length) + kv.Value; + newPart = oldPart.Substring(0, oldPart.Length - kv.Key.Length) + kv.Value; } - } - else if (number is > 10 and < 100) - { - var parts = word.Split(' '); - var newParts = new string[parts.Length]; - var count = 0; - foreach (var part in parts) + if (number > 19 && newPart == oldPart && oldPart.Length > 1) { - var newPart = part; - var oldPart = part; - - var ordinals = gender == GrammaticalGender.Feminine ? FeminineOrdinalExceptions : OrdinalExceptions; - foreach (var kv in ordinals.Where(kv => oldPart.EndsWith(kv.Key))) - { - // replace word with exception - newPart = oldPart.Substring(0, oldPart.Length - kv.Key.Length) + kv.Value; - } - - if (number > 19 && newPart == oldPart && oldPart.Length > 1) - { - newPart = "ال" + oldPart; - } - - newParts[count++] = newPart; + newPart = "ال" + oldPart; } - word = string.Join(" ", newParts); - } - else - { - word = "ال" + word; + newParts[count++] = newPart; } - return word; + word = string.Join(" ", newParts); } + else + { + word = "ال" + word; + } + + return word; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/ArmenianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/ArmenianNumberToWordsConverter.cs index fcb5c6f5b..ba0d92726 100644 --- a/src/Humanizer/Localisation/NumberToWords/ArmenianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/ArmenianNumberToWordsConverter.cs @@ -8,11 +8,21 @@ class ArmenianNumberToWordsConverter : static readonly Dictionary OrdinalExceptions = new() { - {0, "զրոյական"}, - {1, "առաջին"}, - {2, "երկրորդ"}, - {3, "երրորդ"}, - {4, "չորրորդ"} + { + 0, "զրոյական" + }, + { + 1, "առաջին" + }, + { + 2, "երկրորդ" + }, + { + 3, "երրորդ" + }, + { + 4, "չորրորդ" + } }; public override string Convert(long number) => @@ -20,155 +30,155 @@ public override string Convert(long number) => public override string ConvertToOrdinal(int number) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } - - return ConvertImpl(number, true); + if (ExceptionNumbersToWords(number, out var exceptionString)) + { + return exceptionString; } + return ConvertImpl(number, true); + } + string ConvertImpl(long number, bool isOrdinal) { - if (number == 0) - { - return GetUnitValue(0, isOrdinal); - } + if (number == 0) + { + return GetUnitValue(0, isOrdinal); + } - if (number == long.MinValue) - { - return "մինուս ինը քվինտիլիոն " + - "երկու հարյուր քսաներեք կվադրիլիոն " + - "երեք հարյուր յոթանասուներկու տրիլիոն " + - "երեսունվեց միլիարդ " + - "ութ հարյուր հիսունչորս միլիոն " + - "յոթ հարյուր յոթանասունհինգ հազար " + - "ութ հարյուր ութ"; - } + if (number == long.MinValue) + { + return "մինուս ինը քվինտիլիոն " + + "երկու հարյուր քսաներեք կվադրիլիոն " + + "երեք հարյուր յոթանասուներկու տրիլիոն " + + "երեսունվեց միլիարդ " + + "ութ հարյուր հիսունչորս միլիոն " + + "յոթ հարյուր յոթանասունհինգ հազար " + + "ութ հարյուր ութ"; + } - if (number < 0) - { - return $"մինուս {ConvertImpl(-number, isOrdinal)}"; - } + if (number < 0) + { + return $"մինուս {ConvertImpl(-number, isOrdinal)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000000)} քվինտիլիոն"); - number %= 1000000000000000000; - } + if (number / 1000000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000000)} քվինտիլիոն"); + number %= 1000000000000000000; + } - if (number / 1000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000)} կվադրիլիոն"); - number %= 1000000000000000; - } + if (number / 1000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000)} կվադրիլիոն"); + number %= 1000000000000000; + } + + if (number / 1000000000000 > 0) + + { + parts.Add($"{Convert(number / 1000000000000)} տրիլիոն"); + number %= 1000000000000; + } + + if (number / 1000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000)} միլիարդ"); + number %= 1000000000; + } - if (number / 1000000000000 > 0) + if (number / 1000000 > 0) + { + parts.Add($"{Convert(number / 1000000)} միլիոն"); + number %= 1000000; + } + if (number / 1000 > 0) + { + if (number / 1000 == 1) { - parts.Add($"{Convert(number / 1000000000000)} տրիլիոն"); - number %= 1000000000000; + parts.Add("հազար"); } - - if (number / 1000000000 > 0) + else { - parts.Add($"{Convert(number / 1000000000)} միլիարդ"); - number %= 1000000000; + parts.Add($"{Convert(number / 1000)} հազար"); } - if (number / 1000000 > 0) + number %= 1000; + } + + if (number / 100 > 0) + { + if (number / 100 == 1) { - parts.Add($"{Convert(number / 1000000)} միլիոն"); - number %= 1000000; + parts.Add("հարյուր"); } - - if (number / 1000 > 0) + else { - if (number / 1000 == 1) - { - parts.Add("հազար"); - } - else - { - parts.Add($"{Convert(number / 1000)} հազար"); - } - - number %= 1000; + parts.Add($"{Convert(number / 100)} հարյուր"); } - if (number / 100 > 0) - { - if (number / 100 == 1) - { - parts.Add("հարյուր"); - } - else - { - parts.Add($"{Convert(number / 100)} հարյուր"); - } + number %= 100; + } - number %= 100; + if (number > 0) + { + if (number < 20) + { + parts.Add(GetUnitValue(number, isOrdinal)); } - - if (number > 0) + else { - if (number < 20) + var lastPart = TensMap[number / 10]; + if (number % 10 > 0) { - parts.Add(GetUnitValue(number, isOrdinal)); + lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; } - else + else if (isOrdinal) { - var lastPart = TensMap[number / 10]; - if (number % 10 > 0) - { - lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; - } - else if (isOrdinal) - { - lastPart += "երորդ"; - } - - parts.Add(lastPart); + lastPart += "երորդ"; } + + parts.Add(lastPart); } - else if (isOrdinal) - { - parts[^1] += "երորդ"; - } + } + else if (isOrdinal) + { + parts[^1] += "երորդ"; + } - var toWords = string.Join(" ", parts); + var toWords = string.Join(" ", parts); - //if (isOrdinal) - //{ - // toWords = RemoveOnePrefix(toWords); - //} + //if (isOrdinal) + //{ + // toWords = RemoveOnePrefix(toWords); + //} - return toWords; - } + return toWords; + } static string GetUnitValue(long number, bool isOrdinal) { - if (isOrdinal) - { - return UnitsMap[number] + "երորդ"; - } - - return UnitsMap[number]; + if (isOrdinal) + { + return UnitsMap[number] + "երորդ"; } + return UnitsMap[number]; + } + static string RemoveOnePrefix(string toWords) { - // one hundred => hundredth - if (toWords.StartsWith("մեկ", StringComparison.Ordinal)) - { - toWords = toWords.Remove(0, 4); - } - - return toWords; + // one hundred => hundredth + if (toWords.StartsWith("մեկ", StringComparison.Ordinal)) + { + toWords = toWords.Remove(0, 4); } + return toWords; + } + static bool ExceptionNumbersToWords(long number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/AzerbaijaniNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/AzerbaijaniNumberToWordsConverter.cs index 7851f8a3d..17f98ac24 100644 --- a/src/Humanizer/Localisation/NumberToWords/AzerbaijaniNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/AzerbaijaniNumberToWordsConverter.cs @@ -8,103 +8,122 @@ class AzerbaijaniNumberToWordsConverter : static readonly Dictionary OrdinalSuffix = new() { - {'ı', "ıncı"}, - {'i', "inci"}, - {'u', "uncu"}, - {'ü', "üncü"}, - {'o', "uncu"}, - {'ö', "üncü"}, - {'e', "inci"}, - {'a', "ıncı"}, - {'ə', "inci"}, + { + 'ı', "ıncı" + }, + { + 'i', "inci" + }, + { + 'u', "uncu" + }, + { + 'ü', "üncü" + }, + { + 'o', "uncu" + }, + { + 'ö', "üncü" + }, + { + 'e', "inci" + }, + { + 'a', "ıncı" + }, + { + 'ə', "inci" + }, }; public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - if (number == 0) - { - return UnitsMap[0]; - } - - if (number < 0) - { - return $"mənfi {Convert(-number)}"; - } + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - var parts = new List(); + var number = (int) input; + if (number == 0) + { + return UnitsMap[0]; + } - if (number / 1000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000)} milyard"); - number %= 1000000000; - } + if (number < 0) + { + return $"mənfi {Convert(-number)}"; + } - if (number / 1000000 > 0) - { - parts.Add($"{Convert(number / 1000000)} milyon"); - number %= 1000000; - } + var parts = new List(); - var thousand = number / 1000; - if (thousand > 0) - { - parts.Add($"{(thousand > 1 ? Convert(thousand) : "")} min".Trim()); - number %= 1000; - } + if (number / 1000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000)} milyard"); + number %= 1000000000; + } - var hundred = number / 100; - if (hundred > 0) - { - parts.Add($"{(hundred > 1 ? Convert(hundred) : "")} yüz".Trim()); - number %= 100; - } + if (number / 1000000 > 0) + { + parts.Add($"{Convert(number / 1000000)} milyon"); + number %= 1000000; + } - if (number / 10 > 0) - { - parts.Add(TensMap[number / 10]); - number %= 10; - } + var thousand = number / 1000; + if (thousand > 0) + { + parts.Add($"{(thousand > 1 ? Convert(thousand) : "")} min".Trim()); + number %= 1000; + } - if (number > 0) - { - parts.Add(UnitsMap[number]); - } + var hundred = number / 100; + if (hundred > 0) + { + parts.Add($"{(hundred > 1 ? Convert(hundred) : "")} yüz".Trim()); + number %= 100; + } - var toWords = string.Join(" ", parts); + if (number / 10 > 0) + { + parts.Add(TensMap[number / 10]); + number %= 10; + } - return toWords; + if (number > 0) + { + parts.Add(UnitsMap[number]); } + var toWords = string.Join(" ", parts); + + return toWords; + } + public override string ConvertToOrdinal(int number) { - var word = Convert(number); - var wordSuffix = string.Empty; - var suffixFoundOnLastVowel = false; + var word = Convert(number); + var wordSuffix = string.Empty; + var suffixFoundOnLastVowel = false; - for (var i = word.Length - 1; i >= 0; i--) + for (var i = word.Length - 1; i >= 0; i--) + { + if (OrdinalSuffix.TryGetValue(word[i], out wordSuffix)) { - if (OrdinalSuffix.TryGetValue(word[i], out wordSuffix)) - { - suffixFoundOnLastVowel = i == word.Length - 1; - break; - } - } - - if (word[^1] == 't') - { - word = word.Substring(0, word.Length - 1) + 'd'; + suffixFoundOnLastVowel = i == word.Length - 1; + break; } + } - if (suffixFoundOnLastVowel) - { - word = word.Substring(0, word.Length - 1); - } + if (word[^1] == 't') + { + word = word.Substring(0, word.Length - 1) + 'd'; + } - return $"{word}{wordSuffix}"; + if (suffixFoundOnLastVowel) + { + word = word.Substring(0, word.Length - 1); } + + return $"{word}{wordSuffix}"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/BanglaNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/BanglaNumberToWordsConverter.cs index 73c222ff8..4c99d5d6b 100644 --- a/src/Humanizer/Localisation/NumberToWords/BanglaNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/BanglaNumberToWordsConverter.cs @@ -8,108 +8,153 @@ class BanglaNumberToWordsConverter : "শূন্য", "এক", "দুই", "তিন", "চার", "পাঁচ", "ছয়", "সাত", "আট", "নয়", "দশ", "এগারো", "বারো", "তেরো", "চোদ্দ", "পনেরো", "ষোল", "সতেরো", "আঠারো", "উনিশ", "বিশ", "একুশ", "বাইশ", "তেইশ", "চব্বিশ", "পঁচিশ", "ছাব্বিশ", "সাতাশ", "আঠাশ", "উনতিরিশ", "তিরিশ", - "একতিরিশ", "বত্রিশ", "তেত্রিশ", "চৌঁতিরিশ", "পঁয়তিরিশ", "ছত্রিশ", "সাঁইতিরিশ", "আটতিরিশ", "উনচল্লিশ","চল্লিশ", - "একচল্লিশ", "বিয়াল্লিশ", "তেতাল্লিশ", "চুয়াল্লিশ", "পঁয়তাল্লিশ", "ছেচাল্লিশ", "সাতচল্লিশ", "আটচল্লিশ","উনপঞ্চাশ", "পঞ্চাশ", - "একান্ন", "বাহান্ন", "তিপ্পান্ন", "চুয়ান্ন", "পঞ্চান্ন", "ছাপ্পান্ন", "সাতান্ন", "আটান্ন", "উনষাট","ষাট", - "একষট্টি", "বাষট্টি", "তেষট্টি", "চৌষট্টি", "পঁয়ষট্টি", "ছেষট্টি", "সাতষট্টি", "আটষট্টি", "উনসত্তর","সত্তর", + "একতিরিশ", "বত্রিশ", "তেত্রিশ", "চৌঁতিরিশ", "পঁয়তিরিশ", "ছত্রিশ", "সাঁইতিরিশ", "আটতিরিশ", "উনচল্লিশ", "চল্লিশ", + "একচল্লিশ", "বিয়াল্লিশ", "তেতাল্লিশ", "চুয়াল্লিশ", "পঁয়তাল্লিশ", "ছেচাল্লিশ", "সাতচল্লিশ", "আটচল্লিশ", "উনপঞ্চাশ", "পঞ্চাশ", + "একান্ন", "বাহান্ন", "তিপ্পান্ন", "চুয়ান্ন", "পঞ্চান্ন", "ছাপ্পান্ন", "সাতান্ন", "আটান্ন", "উনষাট", "ষাট", + "একষট্টি", "বাষট্টি", "তেষট্টি", "চৌষট্টি", "পঁয়ষট্টি", "ছেষট্টি", "সাতষট্টি", "আটষট্টি", "উনসত্তর", "সত্তর", "একাত্তর", "বাহাত্তর", "তিয়াত্তর", "চুয়াত্তর", "পঁচাত্তর", "ছিয়াত্তর", "সাতাত্তর", "আটাত্তর", "উনআশি", "আশি", "একাশি", "বিরাশি", "তিরাশি", "চুরাশি", "পঁচাশি", "ছিয়াশি", "সাতাশি", "আটাশি", "উননব্বই", "নব্বই", - "একানব্বই", "বিরানব্বই", "তিরানব্বিই", "চুরানব্বই", "পঁচানব্বই", "ছিয়ানব্বই", "সাতানব্বই", "আটানব্বই","নিরানব্বই" + "একানব্বই", "বিরানব্বই", "তিরানব্বিই", "চুরানব্বই", "পঁচানব্বই", "ছিয়ানব্বই", "সাতানব্বই", "আটানব্বই", "নিরানব্বই" ]; static readonly string[] HundredsMap = [ - "শূন্য", "একশ", "দুইশ", "তিনশ", "চারশ", "পাঁচশ", "ছয়শ", "সাতশ","আটশ", "নয়শ" + "শূন্য", "একশ", "দুইশ", "তিনশ", "চারশ", "পাঁচশ", "ছয়শ", "সাতশ", "আটশ", "নয়শ" ]; static readonly Dictionary OrdinalExceptions = new() { - {1, "প্রথম"}, - {2, "দ্বিতীয়"}, - {3, "তৃতীয়"}, - {4, "চতুর্থ"}, - {5, "পঞ্চম"}, - {6, "ষষ্ট"}, - {7, "সপ্তম"}, - {8, "অষ্টম"}, - {9, "নবম"}, - {10, "দশম"}, - {11, "একাদশ"}, - {12, "দ্বাদশ"}, - {13, "ত্রয়োদশ"}, - {14, "চতুর্দশ"}, - {15, "পঞ্চদশ"}, - {16, "ষোড়শ"}, - {17, "সপ্তদশ"}, - {18, "অষ্টাদশ"}, - {100, "শত তম"}, - {1000, "হাজার তম"}, - {100000, "লক্ষ তম"}, - {10000000, "কোটি তম"}, + { + 1, "প্রথম" + }, + { + 2, "দ্বিতীয়" + }, + { + 3, "তৃতীয়" + }, + { + 4, "চতুর্থ" + }, + { + 5, "পঞ্চম" + }, + { + 6, "ষষ্ট" + }, + { + 7, "সপ্তম" + }, + { + 8, "অষ্টম" + }, + { + 9, "নবম" + }, + { + 10, "দশম" + }, + { + 11, "একাদশ" + }, + { + 12, "দ্বাদশ" + }, + { + 13, "ত্রয়োদশ" + }, + { + 14, "চতুর্দশ" + }, + { + 15, "পঞ্চদশ" + }, + { + 16, "ষোড়শ" + }, + { + 17, "সপ্তদশ" + }, + { + 18, "অষ্টাদশ" + }, + { + 100, "শত তম" + }, + { + 1000, "হাজার তম" + }, + { + 100000, "লক্ষ তম" + }, + { + 10000000, "কোটি তম" + }, }; public override string ConvertToOrdinal(int number) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } - - return Convert(number) + " তম"; + if (ExceptionNumbersToWords(number, out var exceptionString)) + { + return exceptionString; } + return Convert(number) + " তম"; + } + public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - - if (number == 0) - { - return UnitsMap[0]; - } - - if (number < 0) - { - return $"ঋণাত্মক {Convert(-number)}"; - } - - var parts = new List(); - - if (number / 10000000 > 0) - { - parts.Add($"{Convert(number / 10000000)} কোটি"); - number %= 10000000; - } - - if (number / 100000 > 0) - { - parts.Add($"{Convert(number / 100000)} লক্ষ"); - number %= 100000; - } - - if (number / 1000 > 0) - { - parts.Add($"{Convert(number / 1000)} হাজার"); - number %= 1000; - } - - if (number / 100 > 0) - { - parts.Add($"{HundredsMap[number / 100]}"); - number %= 100; - } - - if (number > 0) - { - parts.Add(UnitsMap[number]); - } - - return string.Join(" ", parts); + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } + + var number = (int) input; + + if (number == 0) + { + return UnitsMap[0]; + } + + if (number < 0) + { + return $"ঋণাত্মক {Convert(-number)}"; + } + + var parts = new List(); + + if (number / 10000000 > 0) + { + parts.Add($"{Convert(number / 10000000)} কোটি"); + number %= 10000000; } + if (number / 100000 > 0) + { + parts.Add($"{Convert(number / 100000)} লক্ষ"); + number %= 100000; + } + + if (number / 1000 > 0) + { + parts.Add($"{Convert(number / 1000)} হাজার"); + number %= 1000; + } + + if (number / 100 > 0) + { + parts.Add($"{HundredsMap[number / 100]}"); + number %= 100; + } + + if (number > 0) + { + parts.Add(UnitsMap[number]); + } + + return string.Join(" ", parts); + } + static bool ExceptionNumbersToWords(int number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/BrazilianPortugueseNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/BrazilianPortugueseNumberToWordsConverter.cs index 673a59e54..399ed029d 100644 --- a/src/Humanizer/Localisation/NumberToWords/BrazilianPortugueseNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/BrazilianPortugueseNumberToWordsConverter.cs @@ -13,182 +13,182 @@ class BrazilianPortugueseNumberToWordsConverter : public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input is > 999999999999 or < -999999999999) - { - throw new NotImplementedException(); - } + if (input is > 999999999999 or < -999999999999) + { + throw new NotImplementedException(); + } - var number = input; + var number = input; - if (number == 0) - { - return "zero"; - } + if (number == 0) + { + return "zero"; + } - if (number < 0) - { - return $"menos {Convert(Math.Abs(number), gender)}"; - } + if (number < 0) + { + return $"menos {Convert(Math.Abs(number), gender)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000 > 0) - { - // gender is not applied for billions - parts.Add(number / 1000000000 >= 2 - ? $"{Convert(number / 1000000000, GrammaticalGender.Masculine)} bilhões" - : $"{Convert(number / 1000000000, GrammaticalGender.Masculine)} bilhão"); + if (number / 1000000000 > 0) + { + // gender is not applied for billions + parts.Add(number / 1000000000 >= 2 + ? $"{Convert(number / 1000000000, GrammaticalGender.Masculine)} bilhões" + : $"{Convert(number / 1000000000, GrammaticalGender.Masculine)} bilhão"); - number %= 1000000000; - } + number %= 1000000000; + } - if (number / 1000000 > 0) - { - // gender is not applied for millions - parts.Add(number / 1000000 >= 2 - ? $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhões" - : $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhão"); + if (number / 1000000 > 0) + { + // gender is not applied for millions + parts.Add(number / 1000000 >= 2 + ? $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhões" + : $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhão"); - number %= 1000000; - } + number %= 1000000; + } - if (number / 1000 > 0) + if (number / 1000 > 0) + { + // gender is not applied for thousands + parts.Add(number / 1000 == 1 ? "mil" : $"{Convert(number / 1000, GrammaticalGender.Masculine)} mil"); + number %= 1000; + } + + if (number / 100 > 0) + { + if (number == 100) { - // gender is not applied for thousands - parts.Add(number / 1000 == 1 ? "mil" : $"{Convert(number / 1000, GrammaticalGender.Masculine)} mil"); - number %= 1000; + parts.Add(parts.Count > 0 ? "e cem" : "cem"); } - - if (number / 100 > 0) + else { - if (number == 100) - { - parts.Add(parts.Count > 0 ? "e cem" : "cem"); - } - else - { - // Gender is applied to hundreds starting from 200 - parts.Add(ApplyGender(PortugueseHundredsMap[number / 100], gender)); - } - - number %= 100; + // Gender is applied to hundreds starting from 200 + parts.Add(ApplyGender(PortugueseHundredsMap[number / 100], gender)); } - if (number > 0) + number %= 100; + } + + if (number > 0) + { + if (parts.Count != 0) { - if (parts.Count != 0) - { - parts.Add("e"); - } + parts.Add("e"); + } - if (number < 20) + if (number < 20) + { + parts.Add(ApplyGender(PortugueseUnitsMap[number], gender)); + } + else + { + var lastPart = PortugueseTensMap[number / 10]; + if (number % 10 > 0) { - parts.Add(ApplyGender(PortugueseUnitsMap[number], gender)); + lastPart += $" e {ApplyGender(PortugueseUnitsMap[number % 10], gender)}"; } - else - { - var lastPart = PortugueseTensMap[number / 10]; - if (number % 10 > 0) - { - lastPart += $" e {ApplyGender(PortugueseUnitsMap[number % 10], gender)}"; - } - parts.Add(lastPart); - } + parts.Add(lastPart); } - - return string.Join(" ", parts); } + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - // N/A in Portuguese ordinal - if (number == 0) - { - return "zero"; - } + // N/A in Portuguese ordinal + if (number == 0) + { + return "zero"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000 > 0) - { - parts.Add(number / 1000000000 == 1 - ? ApplyOrdinalGender("bilionésimo", gender) - : string.Format("{0} " + ApplyOrdinalGender("bilionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); + if (number / 1000000000 > 0) + { + parts.Add(number / 1000000000 == 1 + ? ApplyOrdinalGender("bilionésimo", gender) + : string.Format("{0} " + ApplyOrdinalGender("bilionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); - number %= 1000000000; - } - - if (number / 1000000 > 0) - { - parts.Add(number / 1000000 == 1 - ? ApplyOrdinalGender("milionésimo", gender) - : string.Format("{0}" + ApplyOrdinalGender("milionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); + number %= 1000000000; + } - number %= 1000000; - } + if (number / 1000000 > 0) + { + parts.Add(number / 1000000 == 1 + ? ApplyOrdinalGender("milionésimo", gender) + : string.Format("{0}" + ApplyOrdinalGender("milionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); - if (number / 1000 > 0) - { - parts.Add(number / 1000 == 1 - ? ApplyOrdinalGender("milésimo", gender) - : string.Format("{0} " + ApplyOrdinalGender("milésimo", gender), ConvertToOrdinal(number / 1000, gender))); + number %= 1000000; + } - number %= 1000; - } + if (number / 1000 > 0) + { + parts.Add(number / 1000 == 1 + ? ApplyOrdinalGender("milésimo", gender) + : string.Format("{0} " + ApplyOrdinalGender("milésimo", gender), ConvertToOrdinal(number / 1000, gender))); - if (number / 100 > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalHundredsMap[number / 100], gender)); - number %= 100; - } + number %= 1000; + } - if (number / 10 > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalTensMap[number / 10], gender)); - number %= 10; - } + if (number / 100 > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalHundredsMap[number / 100], gender)); + number %= 100; + } - if (number > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalUnitsMap[number], gender)); - } + if (number / 10 > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalTensMap[number / 10], gender)); + number %= 10; + } - return string.Join(" ", parts); + if (number > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalUnitsMap[number], gender)); } + return string.Join(" ", parts); + } + static string ApplyGender(string toWords, GrammaticalGender gender) { - if (gender != GrammaticalGender.Feminine) - { - return toWords; - } - - if (toWords.EndsWith("os")) - { - return toWords.Substring(0, toWords.Length - 2) + "as"; - } + if (gender != GrammaticalGender.Feminine) + { + return toWords; + } - if (toWords.EndsWith("um")) - { - return toWords.Substring(0, toWords.Length - 2) + "uma"; - } + if (toWords.EndsWith("os")) + { + return toWords.Substring(0, toWords.Length - 2) + "as"; + } - if (toWords.EndsWith("dois")) - { - return toWords.Substring(0, toWords.Length - 4) + "duas"; - } + if (toWords.EndsWith("um")) + { + return toWords.Substring(0, toWords.Length - 2) + "uma"; + } - return toWords; + if (toWords.EndsWith("dois")) + { + return toWords.Substring(0, toWords.Length - 4) + "duas"; } + return toWords; + } + static string ApplyOrdinalGender(string toWords, GrammaticalGender gender) { - if (gender == GrammaticalGender.Feminine) - { - return toWords.TrimEnd('o') + 'a'; - } - - return toWords; + if (gender == GrammaticalGender.Feminine) + { + return toWords.TrimEnd('o') + 'a'; } + + return toWords; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/BulgarianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/BulgarianNumberToWordsConverter.cs index 841aa3693..30a9d5914 100644 --- a/src/Humanizer/Localisation/NumberToWords/BulgarianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/BulgarianNumberToWordsConverter.cs @@ -39,135 +39,135 @@ public override string Convert(long input, GrammaticalGender gender, bool addAnd static string InnerConvert(long input, GrammaticalGender gender, bool isOrdinal) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - if (input == 0) - { - return isOrdinal ? "нулев" + GetEndingForGender(gender, input) : "нула"; - } + if (input == 0) + { + return isOrdinal ? "нулев" + GetEndingForGender(gender, input) : "нула"; + } - var parts = new List(); + var parts = new List(); - if (input < 0) - { - parts.Add("минус"); - input = -input; - } + if (input < 0) + { + parts.Add("минус"); + input = -input; + } - var lastOrdinalSubstitution = ""; + var lastOrdinalSubstitution = ""; - if (input / 1000000000 > 0) - { - parts.Add(input < 2000000000 ? "един милиард" : InnerConvert(input / 1000000000, gender, false) + " милиарда"); + if (input / 1000000000 > 0) + { + parts.Add(input < 2000000000 ? "един милиард" : InnerConvert(input / 1000000000, gender, false) + " милиарда"); - if (isOrdinal) - lastOrdinalSubstitution = InnerConvert(input / 1000000000, gender, false) + " милиард" + - GetEndingForGender(gender, input); - input %= 1000000000; - } + if (isOrdinal) + lastOrdinalSubstitution = InnerConvert(input / 1000000000, gender, false) + " милиард" + + GetEndingForGender(gender, input); + input %= 1000000000; + } - if (input / 1000000 > 0) - { - parts.Add(input < 2000000 ? "един милион" : InnerConvert(input / 1000000, gender, false) + " милиона"); + if (input / 1000000 > 0) + { + parts.Add(input < 2000000 ? "един милион" : InnerConvert(input / 1000000, gender, false) + " милиона"); - if (isOrdinal) - lastOrdinalSubstitution = InnerConvert(input / 1000000, gender, false) + " милион" + - GetEndingForGender(gender, input); + if (isOrdinal) + lastOrdinalSubstitution = InnerConvert(input / 1000000, gender, false) + " милион" + + GetEndingForGender(gender, input); - input %= 1000000; - } + input %= 1000000; + } - if (input / 1000 > 0) + if (input / 1000 > 0) + { + if (input < 2000) + parts.Add("хиляда"); + else { - if (input < 2000) - parts.Add("хиляда"); - else - { - parts.Add(InnerConvert(input / 1000, gender, false) + " хиляди"); - } - - if (isOrdinal) - lastOrdinalSubstitution = InnerConvert(input / 1000, gender, false) + " хиляд" + - GetEndingForGender(gender, input); - - input %= 1000; + parts.Add(InnerConvert(input / 1000, gender, false) + " хиляди"); } - if (input / 100 > 0) - { - parts.Add(HundredsMap[(int)input / 100]); + if (isOrdinal) + lastOrdinalSubstitution = InnerConvert(input / 1000, gender, false) + " хиляд" + + GetEndingForGender(gender, input); - if (isOrdinal) - lastOrdinalSubstitution = HundredsOrdinalMap[(int)input / 100] + GetEndingForGender(gender, input); + input %= 1000; + } - input %= 100; - } + if (input / 100 > 0) + { + parts.Add(HundredsMap[(int) input / 100]); - if (input > 19) - { - parts.Add(TensMap[input / 10]); + if (isOrdinal) + lastOrdinalSubstitution = HundredsOrdinalMap[(int) input / 100] + GetEndingForGender(gender, input); - if (isOrdinal) - lastOrdinalSubstitution = TensMap[(int)input / 10] + GetEndingForGender(gender, input); + input %= 100; + } - input %= 10; - } + if (input > 19) + { + parts.Add(TensMap[input / 10]); - if (input > 0) - { - parts.Add(UnitsMap[input]); + if (isOrdinal) + lastOrdinalSubstitution = TensMap[(int) input / 10] + GetEndingForGender(gender, input); - if (isOrdinal) - lastOrdinalSubstitution = UnitsOrdinal[input] + GetEndingForGender(gender, input); - } + input %= 10; + } - if (parts.Count > 1) - { - parts.Insert(parts.Count - 1, "и"); - } + if (input > 0) + { + parts.Add(UnitsMap[input]); - if (isOrdinal && !string.IsNullOrWhiteSpace(lastOrdinalSubstitution)) - parts[^1] = lastOrdinalSubstitution; + if (isOrdinal) + lastOrdinalSubstitution = UnitsOrdinal[input] + GetEndingForGender(gender, input); + } - return string.Join(" ", parts); + if (parts.Count > 1) + { + parts.Insert(parts.Count - 1, "и"); } + if (isOrdinal && !string.IsNullOrWhiteSpace(lastOrdinalSubstitution)) + parts[^1] = lastOrdinalSubstitution; + + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int input, GrammaticalGender gender) => InnerConvert(input, gender, true); static string GetEndingForGender(GrammaticalGender gender, long input) { - if (input == 0) - { - return gender switch - { - GrammaticalGender.Masculine => "", - GrammaticalGender.Feminine => "а", - GrammaticalGender.Neuter => "о", - _ => throw new ArgumentOutOfRangeException(nameof(gender)) - }; - } - - if (input < 99) + if (input == 0) + { + return gender switch { - return gender switch - { - GrammaticalGender.Masculine => "и", - GrammaticalGender.Feminine => "а", - GrammaticalGender.Neuter => "о", - _ => throw new ArgumentOutOfRangeException(nameof(gender)) - }; - } + GrammaticalGender.Masculine => "", + GrammaticalGender.Feminine => "а", + GrammaticalGender.Neuter => "о", + _ => throw new ArgumentOutOfRangeException(nameof(gender)) + }; + } + if (input < 99) + { return gender switch { - GrammaticalGender.Masculine => "ен", - GrammaticalGender.Feminine => "на", - GrammaticalGender.Neuter => "но", + GrammaticalGender.Masculine => "и", + GrammaticalGender.Feminine => "а", + GrammaticalGender.Neuter => "о", _ => throw new ArgumentOutOfRangeException(nameof(gender)) }; } + + return gender switch + { + GrammaticalGender.Masculine => "ен", + GrammaticalGender.Feminine => "на", + GrammaticalGender.Neuter => "но", + _ => throw new ArgumentOutOfRangeException(nameof(gender)) + }; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/CentralKurdishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/CentralKurdishNumberToWordsConverter.cs index 0e87e6689..3c630ab11 100644 --- a/src/Humanizer/Localisation/NumberToWords/CentralKurdishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/CentralKurdishNumberToWordsConverter.cs @@ -8,64 +8,79 @@ class CentralKurdishNumberToWordsConverter : GenderlessNumberToWordsConverter public override string Convert(long number) { - var largestNumber = Math.Pow(10, 15) * 1000 - 1; - if (number > largestNumber || number < -largestNumber) - { - throw new NotImplementedException(); - } + var largestNumber = Math.Pow(10, 15) * 1000 - 1; + if (number > largestNumber || number < -largestNumber) + { + throw new NotImplementedException(); + } - if (number < 0) - { - return $"نێگەتیڤ {Convert(-number)}"; - } + if (number < 0) + { + return $"نێگەتیڤ {Convert(-number)}"; + } - if (number == 0) - { - return "سفر"; - } + if (number == 0) + { + return "سفر"; + } - var kurdishGroupsMap = new Dictionary> + var kurdishGroupsMap = new Dictionary> + { { - {(long)Math.Pow(10, 15), n => $"{Convert(n)} کوادریلیۆن"}, - {(long)Math.Pow(10, 12), n => $"{Convert(n)} تریلیۆن"}, - {(long)Math.Pow(10, 9), n => $"{Convert(n)} میلیارد"}, - {(long)Math.Pow(10, 6), n => $"{Convert(n)} میلیۆن"}, - {(long)Math.Pow(10, 3), n => $"{Convert(n)} هەزار"}, - {(long)Math.Pow(10, 2), n => KurdishHundredsMap[n]} - }; - - var parts = new List(); - foreach (var group in kurdishGroupsMap.Keys) + (long) Math.Pow(10, 15), n => $"{Convert(n)} کوادریلیۆن" + }, { - if (number / group > 0) - { - parts.Add(kurdishGroupsMap[group](number / group)); - number %= group; - } - } - - if (number >= 20) + (long) Math.Pow(10, 12), n => $"{Convert(n)} تریلیۆن" + }, + { + (long) Math.Pow(10, 9), n => $"{Convert(n)} میلیارد" + }, + { + (long) Math.Pow(10, 6), n => $"{Convert(n)} میلیۆن" + }, { - parts.Add(KurdishTensMap[number / 10]); - number %= 10; + (long) Math.Pow(10, 3), n => $"{Convert(n)} هەزار" + }, + { + (long) Math.Pow(10, 2), n => KurdishHundredsMap[n] } + }; - if (number > 0) + var parts = new List(); + foreach (var group in kurdishGroupsMap.Keys) + { + if (number / group > 0) { - parts.Add(KurdishUnitsMap[number]); + parts.Add(kurdishGroupsMap[group](number / group)); + number %= group; } + } - var sentence = string.Join(" و ", parts); - if (sentence.StartsWith("یەک هەزار")) - return sentence.Substring(" یەک".Length); - return sentence; + if (number >= 20) + { + parts.Add(KurdishTensMap[number / 10]); + number %= 10; } + if (number > 0) + { + parts.Add(KurdishUnitsMap[number]); + } + + var sentence = string.Join(" و ", parts); + if (sentence.StartsWith("یەک هەزار")) + { + return sentence.Substring(" یەک".Length); + } + + return sentence; + } + public override string ConvertToOrdinal(int number) { - var word = Convert(number); - return $"{word}{(IsVowel(word[^1]) ? "یەم" : "ەم")}"; - } + var word = Convert(number); + return $"{word}{(IsVowel(word[^1]) ? "یەم" : "ەم")}"; + } static bool IsVowel(char c) => c is 'ا' or 'ێ' or 'ۆ' or 'ە' or 'ی'; diff --git a/src/Humanizer/Localisation/NumberToWords/ChineseNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/ChineseNumberToWordsConverter.cs index 11b40575a..84cc9f81b 100644 --- a/src/Humanizer/Localisation/NumberToWords/ChineseNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/ChineseNumberToWordsConverter.cs @@ -14,108 +14,108 @@ public override string ConvertToOrdinal(int number) => static string Convert(long number, bool isOrdinal, bool isSpecial) { - if (number == 0) - { - return UnitsMap[0]; - } + if (number == 0) + { + return UnitsMap[0]; + } + + if (number < 0) + { + return $"负 {Convert(-number, false, false)}"; + } + + var parts = new List(); - if (number < 0) + if (number / 1000000000000 > 0) + { + var format = "{0}兆"; + if (number % 1000000000000 < 100000000000 && number % 1000000000000 > 0) { - return $"负 {Convert(-number, false, false)}"; + format = "{0}兆零"; } - var parts = new List(); + parts.Add(string.Format(format, Convert(number / 1000000000000, false, false))); + number %= 1000000000000; + } - if (number / 1000000000000 > 0) + if (number / 100000000 > 0) + { + var format = "{0}亿"; + if (number % 100000000 < 10000000 && number % 100000000 > 0) { - var format = "{0}兆"; - if (number % 1000000000000 < 100000000000 && number % 1000000000000 > 0) - { - format = "{0}兆零"; - } - - parts.Add(string.Format(format, Convert(number / 1000000000000, false, false))); - number %= 1000000000000; + format = "{0}亿零"; } - if (number / 100000000 > 0) - { - var format = "{0}亿"; - if (number % 100000000 < 10000000 && number % 100000000 > 0) - { - format = "{0}亿零"; - } + parts.Add(string.Format(format, Convert(number / 100000000, false, false))); + number %= 100000000; + } - parts.Add(string.Format(format, Convert(number / 100000000, false, false))); - number %= 100000000; + if (number / 10000 > 0) + { + var format = "{0}万"; + if (number % 10000 < 1000 && number % 10000 > 0) + { + format = "{0}万零"; } - if (number / 10000 > 0) - { - var format = "{0}万"; - if (number % 10000 < 1000 && number % 10000 > 0) - { - format = "{0}万零"; - } + parts.Add(string.Format(format, Convert(number / 10000, false, false))); + number %= 10000; + } - parts.Add(string.Format(format, Convert(number / 10000, false, false))); - number %= 10000; + if (number / 1000 > 0) + { + var format = "{0}千"; + if (number % 1000 < 100 && number % 1000 > 0) + { + format = "{0}千零"; } - if (number / 1000 > 0) - { - var format = "{0}千"; - if (number % 1000 < 100 && number % 1000 > 0) - { - format = "{0}千零"; - } + parts.Add(string.Format(format, Convert(number / 1000, false, false))); + number %= 1000; + } - parts.Add(string.Format(format, Convert(number / 1000, false, false))); - number %= 1000; + if (number / 100 > 0) + { + var format = "{0}百"; + if (number % 100 < 10 && number % 100 > 0) + { + format = "{0}百零"; } - if (number / 100 > 0) - { - var format = "{0}百"; - if (number % 100 < 10 && number % 100 > 0) - { - format = "{0}百零"; - } + parts.Add(string.Format(format, Convert(number / 100, false, false))); + number %= 100; + } - parts.Add(string.Format(format, Convert(number / 100, false, false))); - number %= 100; + if (number > 0) + { + if (number <= 10) + { + parts.Add(UnitsMap[number]); } - - if (number > 0) + else { - if (number <= 10) + var lastPart = $"{UnitsMap[number / 10]}十"; + if (number % 10 > 0) { - parts.Add(UnitsMap[number]); + lastPart += $"{UnitsMap[number % 10]}"; } - else - { - var lastPart = $"{UnitsMap[number / 10]}十"; - if (number % 10 > 0) - { - lastPart += $"{UnitsMap[number % 10]}"; - } - parts.Add(lastPart); - } + parts.Add(lastPart); } + } - var toWords = string.Concat(parts); - - if (isSpecial) - { - toWords = toWords.Substring(1); - } + var toWords = string.Concat(parts); - if (isOrdinal) - { - toWords = $"第 {toWords}"; - } + if (isSpecial) + { + toWords = toWords.Substring(1); + } - return toWords; + if (isOrdinal) + { + toWords = $"第 {toWords}"; } + + return toWords; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/CzechNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/CzechNumberToWordsConverter.cs index 8c6cb0aa7..d2e873a96 100644 --- a/src/Humanizer/Localisation/NumberToWords/CzechNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/CzechNumberToWordsConverter.cs @@ -17,93 +17,93 @@ class CzechNumberToWordsConverter(CultureInfo? culture) : public override string Convert(long number, GrammaticalGender gender, bool addAnd = true) { - if (number == 0) - { - return UnitByGender(number, gender); - } + if (number == 0) + { + return UnitByGender(number, gender); + } - var parts = new List(); - if (number < 0) - { - parts.Add("mínus"); - number = -number; - } + var parts = new List(); + if (number < 0) + { + parts.Add("mínus"); + number = -number; + } - CollectThousandAndAbove(parts, ref number, 1_000_000_000, GrammaticalGender.Feminine, BillionsMap); - CollectThousandAndAbove(parts, ref number, 1_000_000, GrammaticalGender.Masculine, MillionsMap); - CollectThousandAndAbove(parts, ref number, 1_000, GrammaticalGender.Masculine, ThousandsMap); + CollectThousandAndAbove(parts, ref number, 1_000_000_000, GrammaticalGender.Feminine, BillionsMap); + CollectThousandAndAbove(parts, ref number, 1_000_000, GrammaticalGender.Masculine, MillionsMap); + CollectThousandAndAbove(parts, ref number, 1_000, GrammaticalGender.Masculine, ThousandsMap); - CollectLessThanThousand(parts, number, gender); + CollectLessThanThousand(parts, number, gender); - return string.Join(" ", parts); - } + return string.Join(" ", parts); + } public override string ConvertToOrdinal(int number, GrammaticalGender gender) => number.ToString(culture); static string UnitByGender(long number, GrammaticalGender? gender) { - if (number != 1 && number != 2) - { - return UnitsMap[number]; - } - - return gender switch - { - GrammaticalGender.Masculine => UnitsMasculineOverrideMap[number - 1], - GrammaticalGender.Feminine => UnitsFeminineOverrideMap[number - 1], - GrammaticalGender.Neuter => UnitsNeuterOverride[number - 1], - null => UnitsIntraOverride[number - 1], - _ => throw new ArgumentOutOfRangeException(nameof(gender)), - }; + if (number != 1 && number != 2) + { + return UnitsMap[number]; } + return gender switch + { + GrammaticalGender.Masculine => UnitsMasculineOverrideMap[number - 1], + GrammaticalGender.Feminine => UnitsFeminineOverrideMap[number - 1], + GrammaticalGender.Neuter => UnitsNeuterOverride[number - 1], + null => UnitsIntraOverride[number - 1], + _ => throw new ArgumentOutOfRangeException(nameof(gender)), + }; + } + static void CollectLessThanThousand(List parts, long number, GrammaticalGender? gender) { - if (number >= 100) - { - parts.Add(HundredsMap[number / 100]); - number %= 100; - } - - if (number >= 20) - { - parts.Add(TensMap[number / 10]); - number %= 10; - } - - if (number > 0) - { - parts.Add(UnitByGender(number, gender)); - } + if (number >= 100) + { + parts.Add(HundredsMap[number / 100]); + number %= 100; + } + + if (number >= 20) + { + parts.Add(TensMap[number / 10]); + number %= 10; + } + + if (number > 0) + { + parts.Add(UnitByGender(number, gender)); } + } static void CollectThousandAndAbove(List parts, ref long number, long divisor, GrammaticalGender gender, string[] map) { - var n = number / divisor; - - if (n <= 0) - { - return; - } - - CollectLessThanThousand(parts, n, n < 19 ? gender : null); - - var units = n % 1000; - - if (units == 1) - { - parts.Add(map[0]); - } - else if (units is > 1 and < 5) - { - parts.Add(map[1]); - } - else - { - parts.Add(map[2]); - } - - number %= divisor; + var n = number / divisor; + + if (n <= 0) + { + return; + } + + CollectLessThanThousand(parts, n, n < 19 ? gender : null); + + var units = n % 1000; + + if (units == 1) + { + parts.Add(map[0]); + } + else if (units is > 1 and < 5) + { + parts.Add(map[1]); } + else + { + parts.Add(map[2]); + } + + number %= divisor; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/DutchNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/DutchNumberToWordsConverter.cs index 36d3b61f0..30239fad8 100644 --- a/src/Humanizer/Localisation/NumberToWords/DutchNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/DutchNumberToWordsConverter.cs @@ -23,109 +23,164 @@ class Fact static readonly Fact[] Hunderds = [ - new() {Value = 1_000_000_000_000_000_000L, Name = "triljoen", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new() {Value = 1_000_000_000_000_000L, Name = "biljard", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new() {Value = 1_000_000_000_000L, Name = "biljoen", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new() {Value = 1000000000, Name = "miljard", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new() {Value = 1000000, Name = "miljoen", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new() {Value = 1000, Name = "duizend", Prefix = "", Postfix = " ", DisplayOneUnit = false}, - new() {Value = 100, Name = "honderd", Prefix = "", Postfix = "", DisplayOneUnit = false} + new() + { + Value = 1_000_000_000_000_000_000L, + Name = "triljoen", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 1_000_000_000_000_000L, + Name = "biljard", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 1_000_000_000_000L, + Name = "biljoen", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 1000000000, + Name = "miljard", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 1000000, + Name = "miljoen", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 1000, + Name = "duizend", + Prefix = "", + Postfix = " ", + DisplayOneUnit = false + }, + new() + { + Value = 100, + Name = "honderd", + Prefix = "", + Postfix = "", + DisplayOneUnit = false + } ]; public override string Convert(long input) { - var number = input; + var number = input; + + if (number == 0) + { + return UnitsMap[0]; + } + + if (number < 0) + { + return $"min {Convert(-number)}"; + } - if (number == 0) + var word = ""; + + foreach (var m in Hunderds) + { + var divided = number / m.Value; + + if (divided <= 0) { - return UnitsMap[0]; + continue; } - if (number < 0) + if (divided == 1 && !m.DisplayOneUnit) { - return $"min {Convert(-number)}"; + word += m.Name; } - - var word = ""; - - foreach (var m in Hunderds) + else { - var divided = number / m.Value; - - if (divided <= 0) - { - continue; - } - - if (divided == 1 && !m.DisplayOneUnit) - { - word += m.Name; - } - else - { - word += Convert(divided) + m.Prefix + m.Name; - } - - number %= m.Value; - if (number > 0) - { - word += m.Postfix; - } + word += Convert(divided) + m.Prefix + m.Name; } + number %= m.Value; if (number > 0) { - if (number < 20) + word += m.Postfix; + } + } + + if (number > 0) + { + if (number < 20) + { + word += UnitsMap[number]; + } + else + { + var tens = TensMap[number / 10]; + var unit = number % 10; + if (unit > 0) { - word += UnitsMap[number]; + var units = UnitsMap[unit]; + var trema = units.EndsWith("e"); + word += units + (trema ? "ën" : "en") + tens; } else { - var tens = TensMap[number / 10]; - var unit = number % 10; - if (unit > 0) - { - var units = UnitsMap[unit]; - var trema = units.EndsWith("e"); - word += units + (trema ? "ën" : "en") + tens; - } - else - { - word += tens; - } + word += tens; } } - - return word; } + return word; + } + static readonly Dictionary OrdinalExceptions = new() { - {"een", "eerste"}, - {"drie", "derde"}, - {"miljoen", "miljoenste"}, + { + "een", "eerste" + }, + { + "drie", "derde" + }, + { + "miljoen", "miljoenste" + }, }; static readonly char[] EndingCharForSte = ['t', 'g', 'd']; public override string ConvertToOrdinal(int number) { - var word = Convert(number); + var word = Convert(number); - foreach (var kv in OrdinalExceptions.Where(kv => word.EndsWith(kv.Key))) - { - // replace word with exception - return word.Substring(0, word.Length - kv.Key.Length) + kv.Value; - } - - // achtste - // twintigste, dertigste, veertigste, ... - // honderdste, duizendste, ... - if (word.LastIndexOfAny(EndingCharForSte) == word.Length - 1) - { - return word + "ste"; - } + foreach (var kv in OrdinalExceptions.Where(kv => word.EndsWith(kv.Key))) + { + // replace word with exception + return word.Substring(0, word.Length - kv.Key.Length) + kv.Value; + } - return word + "de"; + // achtste + // twintigste, dertigste, veertigste, ... + // honderdste, duizendste, ... + if (word.LastIndexOfAny(EndingCharForSte) == word.Length - 1) + { + return word + "ste"; } + + return word + "de"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/EnglishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/EnglishNumberToWordsConverter.cs index dfcb2843b..386026f74 100644 --- a/src/Humanizer/Localisation/NumberToWords/EnglishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/EnglishNumberToWordsConverter.cs @@ -7,14 +7,30 @@ class EnglishNumberToWordsConverter : GenderlessNumberToWordsConverter static readonly Dictionary OrdinalExceptions = new() { - {1, "first"}, - {2, "second"}, - {3, "third"}, - {4, "fourth"}, - {5, "fifth"}, - {8, "eighth"}, - {9, "ninth"}, - {12, "twelfth"}, + { + 1, "first" + }, + { + 2, "second" + }, + { + 3, "third" + }, + { + 4, "fourth" + }, + { + 5, "fifth" + }, + { + 8, "eighth" + }, + { + 9, "ninth" + }, + { + 12, "twelfth" + }, }; public override string Convert(long number) => @@ -28,160 +44,160 @@ public override string ConvertToOrdinal(int number) => string Convert(long number, bool isOrdinal, bool addAnd = true) { - if (number == 0) - { - return GetUnitValue(0, isOrdinal); - } + if (number == 0) + { + return GetUnitValue(0, isOrdinal); + } - if (number < 0) - { - return $"minus {Convert(-number)}"; - } + if (number < 0) + { + return $"minus {Convert(-number)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000000)} quintillion"); - number %= 1000000000000000000; - } + if (number / 1000000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000000)} quintillion"); + number %= 1000000000000000000; + } - if (number / 1000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000)} quadrillion"); - number %= 1000000000000000; - } + if (number / 1000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000)} quadrillion"); + number %= 1000000000000000; + } - if (number / 1000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000)} trillion"); - number %= 1000000000000; - } + if (number / 1000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000)} trillion"); + number %= 1000000000000; + } - if (number / 1000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000)} billion"); - number %= 1000000000; - } + if (number / 1000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000)} billion"); + number %= 1000000000; + } - if (number / 1000000 > 0) - { - parts.Add($"{Convert(number / 1000000)} million"); - number %= 1000000; - } + if (number / 1000000 > 0) + { + parts.Add($"{Convert(number / 1000000)} million"); + number %= 1000000; + } + + if (number / 1000 > 0) + { + parts.Add($"{Convert(number / 1000)} thousand"); + number %= 1000; + } + + if (number / 100 > 0) + { + parts.Add($"{Convert(number / 100)} hundred"); + number %= 100; + } - if (number / 1000 > 0) + if (number > 0) + { + if (parts.Count != 0 && addAnd) { - parts.Add($"{Convert(number / 1000)} thousand"); - number %= 1000; + parts.Add("and"); } - if (number / 100 > 0) + if (number < 20) { - parts.Add($"{Convert(number / 100)} hundred"); - number %= 100; + parts.Add(GetUnitValue(number, isOrdinal)); } - - if (number > 0) + else { - if (parts.Count != 0 && addAnd) - { - parts.Add("and"); - } - - if (number < 20) + var lastPart = TensMap[number / 10]; + if (number % 10 > 0) { - parts.Add(GetUnitValue(number, isOrdinal)); + lastPart += $"-{GetUnitValue(number % 10, isOrdinal)}"; } - else + else if (isOrdinal) { - var lastPart = TensMap[number / 10]; - if (number % 10 > 0) - { - lastPart += $"-{GetUnitValue(number % 10, isOrdinal)}"; - } - else if (isOrdinal) - { - lastPart = lastPart.TrimEnd('y') + "ieth"; - } - - parts.Add(lastPart); + lastPart = lastPart.TrimEnd('y') + "ieth"; } - } - else if (isOrdinal) - { - parts[^1] += "th"; - } - - var toWords = string.Join(" ", parts); - if (isOrdinal) - { - toWords = RemoveOnePrefix(toWords); + parts.Add(lastPart); } + } + else if (isOrdinal) + { + parts[^1] += "th"; + } - return toWords; + var toWords = string.Join(" ", parts); + + if (isOrdinal) + { + toWords = RemoveOnePrefix(toWords); } + return toWords; + } + static string GetUnitValue(long number, bool isOrdinal) { - if (isOrdinal) + if (isOrdinal) + { + if (ExceptionNumbersToWords(number, out var exceptionString)) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } - - return UnitsMap[number] + "th"; + return exceptionString; } - return UnitsMap[number]; + return UnitsMap[number] + "th"; } + return UnitsMap[number]; + } + static string RemoveOnePrefix(string toWords) { - // one hundred => hundredth - if (toWords.StartsWith("one", StringComparison.Ordinal)) - { - toWords = toWords.Remove(0, 4); - } - - return toWords; + // one hundred => hundredth + if (toWords.StartsWith("one", StringComparison.Ordinal)) + { + toWords = toWords.Remove(0, 4); } + return toWords; + } + static bool ExceptionNumbersToWords(long number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); public override string ConvertToTuple(int number) { - switch (number) - { - case 1: - return "single"; - case 2: - return "double"; - case 3: - return "triple"; - case 4: - return "quadruple"; - case 5: - return "quintuple"; - case 6: - return "sextuple"; - case 7: - return "septuple"; - case 8: - return "octuple"; - case 9: - return "nonuple"; - case 10: - return "decuple"; - case 100: - return "centuple"; - case 1000: - return "milluple"; - default: - return $"{number}-tuple"; - } + switch (number) + { + case 1: + return "single"; + case 2: + return "double"; + case 3: + return "triple"; + case 4: + return "quadruple"; + case 5: + return "quintuple"; + case 6: + return "sextuple"; + case 7: + return "septuple"; + case 8: + return "octuple"; + case 9: + return "nonuple"; + case 10: + return "decuple"; + case 100: + return "centuple"; + case 1000: + return "milluple"; + default: + return $"{number}-tuple"; } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/FarsiNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/FarsiNumberToWordsConverter.cs index 54af41c61..e696d7947 100644 --- a/src/Humanizer/Localisation/NumberToWords/FarsiNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/FarsiNumberToWordsConverter.cs @@ -8,69 +8,83 @@ class FarsiNumberToWordsConverter : GenderlessNumberToWordsConverter public override string Convert(long number) { - if (number < 0) - { - return $"منفی {Convert(-number)}"; - } + if (number < 0) + { + return $"منفی {Convert(-number)}"; + } - if (number == 0) - { - return "صفر"; - } + if (number == 0) + { + return "صفر"; + } - var farsiGroupsMap = new Dictionary> + var farsiGroupsMap = new Dictionary> + { { - {(long)Math.Pow(10, 18), n => $"{Convert(n)} تریلیون"}, - {(long)Math.Pow(10, 15), n => $"{Convert(n)} بیلیارد"}, - {(long)Math.Pow(10, 12), n => $"{Convert(n)} بیلیون"}, - {(long)Math.Pow(10, 9), n => $"{Convert(n)} میلیارد"}, - {(long)Math.Pow(10, 6), n => $"{Convert(n)} میلیون"}, - {(long)Math.Pow(10, 3), n => $"{Convert(n)} هزار"}, - {(long)Math.Pow(10, 2), n => FarsiHundredsMap[n]} - }; - - var parts = new List(); - foreach (var group in farsiGroupsMap.Keys) + (long) Math.Pow(10, 18), n => $"{Convert(n)} تریلیون" + }, { - if (number / group > 0) - { - parts.Add(farsiGroupsMap[group](number / group)); - number %= group; - } - } - - if (number >= 20) + (long) Math.Pow(10, 15), n => $"{Convert(n)} بیلیارد" + }, + { + (long) Math.Pow(10, 12), n => $"{Convert(n)} بیلیون" + }, + { + (long) Math.Pow(10, 9), n => $"{Convert(n)} میلیارد" + }, { - parts.Add(FarsiTensMap[number / 10]); - number %= 10; + (long) Math.Pow(10, 6), n => $"{Convert(n)} میلیون" + }, + { + (long) Math.Pow(10, 3), n => $"{Convert(n)} هزار" + }, + { + (long) Math.Pow(10, 2), n => FarsiHundredsMap[n] } + }; - if (number > 0) + var parts = new List(); + foreach (var group in farsiGroupsMap.Keys) + { + if (number / group > 0) { - parts.Add(FarsiUnitsMap[number]); + parts.Add(farsiGroupsMap[group](number / group)); + number %= group; } + } - return string.Join(" و ", parts); + if (number >= 20) + { + parts.Add(FarsiTensMap[number / 10]); + number %= 10; } + if (number > 0) + { + parts.Add(FarsiUnitsMap[number]); + } + + return string.Join(" و ", parts); + } + public override string ConvertToOrdinal(int number) { - if (number == 1) - { - return "اول"; - } - - if (number == 3) - { - return "سوم"; - } + if (number == 1) + { + return "اول"; + } - if (number % 10 == 3 && number != 13) - { - return Convert(number / 10 * 10) + " و سوم"; - } + if (number == 3) + { + return "سوم"; + } - var word = Convert(number); - return $"{word}{(word.EndsWith("ی") ? " ام" : "م")}"; + if (number % 10 == 3 && number != 13) + { + return Convert(number / 10 * 10) + " و سوم"; } + + var word = Convert(number); + return $"{word}{(word.EndsWith("ی") ? " ام" : "م")}"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/FrenchBelgianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/FrenchBelgianNumberToWordsConverter.cs index 6e7950693..6e4e46a2c 100644 --- a/src/Humanizer/Localisation/NumberToWords/FrenchBelgianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/FrenchBelgianNumberToWordsConverter.cs @@ -4,27 +4,27 @@ class FrenchBelgianNumberToWordsConverter : FrenchNumberToWordsConverterBase { protected override void CollectPartsUnderAHundred(ICollection parts, ref long number, GrammaticalGender gender, bool pluralize) { - if (number == 80) - { - parts.Add(pluralize ? "quatre-vingts" : "quatre-vingt"); - } - else if (number == 81) - { - parts.Add(gender == GrammaticalGender.Feminine ? "quatre-vingt-une" : "quatre-vingt-un"); - } - else - { - base.CollectPartsUnderAHundred(parts, ref number, gender, pluralize); - } + if (number == 80) + { + parts.Add(pluralize ? "quatre-vingts" : "quatre-vingt"); } + else if (number == 81) + { + parts.Add(gender == GrammaticalGender.Feminine ? "quatre-vingt-une" : "quatre-vingt-un"); + } + else + { + base.CollectPartsUnderAHundred(parts, ref number, gender, pluralize); + } + } protected override string GetTens(long tens) { - if (tens == 8) - { - return "quatre-vingt"; - } - - return base.GetTens(tens); + if (tens == 8) + { + return "quatre-vingt"; } + + return base.GetTens(tens); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/GreekNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/GreekNumberToWordsConverter.cs index 2ce5f9fbc..fb59fa4c3 100644 --- a/src/Humanizer/Localisation/NumberToWords/GreekNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/GreekNumberToWordsConverter.cs @@ -16,35 +16,93 @@ class GreekNumberToWordsConverter : GenderlessNumberToWordsConverter static readonly Dictionary ΟrdinalMap = new() { - { 0, string.Empty }, - { 1, "πρώτος" }, - { 2, "δεύτερος" }, - { 3, "τρίτος" }, - { 4, "τέταρτος" }, - { 5, "πέμπτος" }, - { 6, "έκτος" }, - { 7, "έβδομος" }, - { 8, "όγδοος" }, - { 9, "ένατος" }, - { 10, "δέκατος" }, - { 20, "εικοστός" }, - { 30, "τριακοστός" }, - { 40, "τεσσαρακοστός" }, - { 50, "πεντηκοστός" }, - { 60, "εξηκοστός" }, - { 70, "εβδομηκοστός" }, - { 80, "ογδοηκοστός" }, - { 90, "ενενηκοστός" }, - { 100, "εκατοστός" }, - { 200, "διακοσιοστός" }, - { 300, "τριακοσιοστός" }, - { 400, "τετρακοσιστός" }, - { 500, "πεντακοσιοστός" }, - { 600, "εξακοσιοστός" }, - { 700, "εφτακοσιοστός" }, - { 800, "οχτακοσιοστός" }, - { 900, "εννιακοσιοστός" }, - { 1000, "χιλιοστός" } + { + 0, string.Empty + }, + { + 1, "πρώτος" + }, + { + 2, "δεύτερος" + }, + { + 3, "τρίτος" + }, + { + 4, "τέταρτος" + }, + { + 5, "πέμπτος" + }, + { + 6, "έκτος" + }, + { + 7, "έβδομος" + }, + { + 8, "όγδοος" + }, + { + 9, "ένατος" + }, + { + 10, "δέκατος" + }, + { + 20, "εικοστός" + }, + { + 30, "τριακοστός" + }, + { + 40, "τεσσαρακοστός" + }, + { + 50, "πεντηκοστός" + }, + { + 60, "εξηκοστός" + }, + { + 70, "εβδομηκοστός" + }, + { + 80, "ογδοηκοστός" + }, + { + 90, "ενενηκοστός" + }, + { + 100, "εκατοστός" + }, + { + 200, "διακοσιοστός" + }, + { + 300, "τριακοσιοστός" + }, + { + 400, "τετρακοσιστός" + }, + { + 500, "πεντακοσιοστός" + }, + { + 600, "εξακοσιοστός" + }, + { + 700, "εφτακοσιοστός" + }, + { + 800, "οχτακοσιοστός" + }, + { + 900, "εννιακοσιοστός" + }, + { + 1000, "χιλιοστός" + } }; public override string Convert(long number) => @@ -52,240 +110,245 @@ public override string Convert(long number) => public override string ConvertToOrdinal(int number) { - if (number / 10 == 0) - { - return GetOneDigitOrdinal(number); - } + if (number / 10 == 0) + { + return GetOneDigitOrdinal(number); + } - if (number / 10 > 0 && number / 10 < 10) - { - return GetTwoDigitOrdinal(number); + if (number / 10 > 0 && number / 10 < 10) + { + return GetTwoDigitOrdinal(number); - } - - if (number / 100 > 0 && number / 100 < 10) - { - return GetThreeDigitOrdinal(number); - } + } - if (number / 1000 > 0 && number / 1000 < 10) - { - return GetFourDigitOrdinal(number); - } + if (number / 100 > 0 && number / 100 < 10) + { + return GetThreeDigitOrdinal(number); + } - return string.Empty; + if (number / 1000 > 0 && number / 1000 < 10) + { + return GetFourDigitOrdinal(number); } + return string.Empty; + } + static string GetOneDigitOrdinal(int number) { - if (ΟrdinalMap.TryGetValue(number, out var output)) - { - return output; - } - - return string.Empty; + if (ΟrdinalMap.TryGetValue(number, out var output)) + { + return output; } + return string.Empty; + } + static string GetTwoDigitOrdinal(int number) { - if (number == 11) return "ενδέκατος"; - if (number == 12) return "δωδέκατος"; + if (number == 11) return "ενδέκατος"; + if (number == 12) return "δωδέκατος"; - var decades = number / 10; + var decades = number / 10; - if (!ΟrdinalMap.TryGetValue(decades*10, out var decadesString)) return string.Empty; + if (!ΟrdinalMap.TryGetValue(decades * 10, out var decadesString)) return string.Empty; - if(number -decades*10 > 0) - { - return decadesString + " " + GetOneDigitOrdinal(number - decades * 10); - } - - return decadesString; + if (number - decades * 10 > 0) + { + return decadesString + " " + GetOneDigitOrdinal(number - decades * 10); } + return decadesString; + } + static string GetThreeDigitOrdinal(int number) { - var hundreds = number / 100; + var hundreds = number / 100; - if (!ΟrdinalMap.TryGetValue(hundreds*100, out var hundredsString)) return string.Empty; + if (!ΟrdinalMap.TryGetValue(hundreds * 100, out var hundredsString)) return string.Empty; - if (number - hundreds*100> 10) - { - return hundredsString + " " + GetTwoDigitOrdinal(number - hundreds*100); - } - - if(number - hundreds * 100 > 0) - { - return hundredsString + " " + GetOneDigitOrdinal(number - hundreds*100); - } + if (number - hundreds * 100 > 10) + { + return hundredsString + " " + GetTwoDigitOrdinal(number - hundreds * 100); + } - return hundredsString; + if (number - hundreds * 100 > 0) + { + return hundredsString + " " + GetOneDigitOrdinal(number - hundreds * 100); } + return hundredsString; + } + static string GetFourDigitOrdinal(int number) { - var thousands = number / 1000; + var thousands = number / 1000; - if (!ΟrdinalMap.TryGetValue(thousands*1000, out var thousandsString)) return string.Empty; + if (!ΟrdinalMap.TryGetValue(thousands * 1000, out var thousandsString)) return string.Empty; - if (number - thousands * 1000 > 100) - { - return thousandsString + " " + GetThreeDigitOrdinal(number - thousands*1000); - } - - if (number - thousands * 1000 > 10) - { - return thousandsString + " " + GetTwoDigitOrdinal(number - thousands * 1000); - } + if (number - thousands * 1000 > 100) + { + return thousandsString + " " + GetThreeDigitOrdinal(number - thousands * 1000); + } - if (number - thousands * 1000 > 0) - { - return thousandsString + " " + GetOneDigitOrdinal(number - thousands * 1000); - } + if (number - thousands * 1000 > 10) + { + return thousandsString + " " + GetTwoDigitOrdinal(number - thousands * 1000); + } - return thousandsString; + if (number - thousands * 1000 > 0) + { + return thousandsString + " " + GetOneDigitOrdinal(number - thousands * 1000); } + return thousandsString; + } + string ConvertImpl(long number, bool returnPluralized) { - if (number < 13) - { - return ConvertIntB13(number, returnPluralized); - } + if (number < 13) + { + return ConvertIntB13(number, returnPluralized); + } - if (number < 100) - { - return ConvertIntBH(number, returnPluralized); - } - if (number < 1000) - { - return ConvertIntBT(number, returnPluralized); - } - if (number < 1000000) - { - return ConvertIntBM(number); - } - if (number < 1000000000) - { - return ConvertIntBB(number); - } - if (number < 1000000000000) - { - return ConvertIntBTR(number); - } + if (number < 100) + { + return ConvertIntBH(number, returnPluralized); + } - return ""; + if (number < 1000) + { + return ConvertIntBT(number, returnPluralized); } + if (number < 1000000) + { + return ConvertIntBM(number); + } + + if (number < 1000000000) + { + return ConvertIntBB(number); + } + + if (number < 1000000000000) + { + return ConvertIntBTR(number); + } + + return ""; + } + string ConvertIntB13(long number, bool returnPluralized) => returnPluralized ? UnitsMap[number] : UnitMap[number]; string ConvertIntBH(long number, bool returnPluralized) { - var result = number / 10 == 1 ? TensNoDiacriticsMap[number / 10] : TensMap[number / 10]; + var result = number / 10 == 1 ? TensNoDiacriticsMap[number / 10] : TensMap[number / 10]; - if (number % 10 != 0) + if (number % 10 != 0) + { + if (number / 10 != 1) { - if (number / 10 != 1) - { - result += " "; - } - - result += ConvertImpl(number % 10, returnPluralized).ToLower(); + result += " "; } - return result; + result += ConvertImpl(number % 10, returnPluralized) + .ToLower(); } + return result; + } + string ConvertIntBT(long number, bool returnPluralized) { - string result; - - if (number / 100 == 1) - { - if (number % 100 == 0) - { - return HundredMap[number / 100]; - } + string result; - result = HundredsMap[number / 100]; - } - else + if (number / 100 == 1) + { + if (number % 100 == 0) { - result = returnPluralized ? HundredsMap[number / 100] : HundredMap[number / 100]; + return HundredMap[number / 100]; } - if (number % 100 != 0) - { - result += $" {ConvertImpl(number % 100, returnPluralized).ToLower()}"; - } + result = HundredsMap[number / 100]; + } + else + { + result = returnPluralized ? HundredsMap[number / 100] : HundredMap[number / 100]; + } - return result; + if (number % 100 != 0) + { + result += $" {ConvertImpl(number % 100, returnPluralized).ToLower()}"; } + return result; + } + string ConvertIntBM(long number) { - if (number / 1000 == 1) + if (number / 1000 == 1) + { + if (number % 1000 == 0) { - if (number % 1000 == 0) - { - return "χίλια"; - } - - return $"χίλια {ConvertImpl(number % 1000, false).ToLower()}"; + return "χίλια"; } - var result = $"{ConvertImpl(number / 1000, true)} χιλιάδες"; + return $"χίλια {ConvertImpl(number % 1000, false).ToLower()}"; + } - if (number % 1000 != 0) - { - result += $" {ConvertImpl(number % 1000, false).ToLower()}"; - } + var result = $"{ConvertImpl(number / 1000, true)} χιλιάδες"; - return result; + if (number % 1000 != 0) + { + result += $" {ConvertImpl(number % 1000, false).ToLower()}"; } + return result; + } + string ConvertIntBB(long number) { - if (number / 1000000 == 1) + if (number / 1000000 == 1) + { + if (number % 1000000 == 0) { - if (number % 1000000 == 0) - { - return "ένα εκατομμύριο"; - } - - return $"ένα εκατομμύριο {ConvertImpl(number % 1000000, true).ToLower()}"; + return "ένα εκατομμύριο"; } - var result = $"{ConvertImpl(number / 1000000, false)} εκατομμύρια"; + return $"ένα εκατομμύριο {ConvertImpl(number % 1000000, true).ToLower()}"; + } - if (number % 1000000 != 0) - { - result += $" {ConvertImpl(number % 1000000, false).ToLower()}"; - } + var result = $"{ConvertImpl(number / 1000000, false)} εκατομμύρια"; - return result; + if (number % 1000000 != 0) + { + result += $" {ConvertImpl(number % 1000000, false).ToLower()}"; } + return result; + } + string ConvertIntBTR(long number) { - if (number / 1000000000 == 1) + if (number / 1000000000 == 1) + { + if (number % 1000000000 == 0) { - if (number % 1000000000 == 0) - { - return "ένα δισεκατομμύριο"; - } - - return $"ένα δισεκατομμύριο {ConvertImpl(number % 1000000000, true).ToLower()}"; + return "ένα δισεκατομμύριο"; } - var result = $"{ConvertImpl(number / 1000000000, false)} δισεκατομμύρια"; + return $"ένα δισεκατομμύριο {ConvertImpl(number % 1000000000, true).ToLower()}"; + } - if (number % 1000000000 != 0) - { - result += $" {ConvertImpl(number % 1000000000, false).ToLower()}"; - } + var result = $"{ConvertImpl(number / 1000000000, false)} δισεκατομμύρια"; - return result; + if (number % 1000000000 != 0) + { + result += $" {ConvertImpl(number % 1000000000, false).ToLower()}"; } + + return result; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/HebrewNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/HebrewNumberToWordsConverter.cs index 789bde7d8..e913b8d48 100644 --- a/src/Humanizer/Localisation/NumberToWords/HebrewNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/HebrewNumberToWordsConverter.cs @@ -17,164 +17,167 @@ enum Group { Hundreds = 100, Thousands = 1000, + [Description("מיליון")] Millions = 1000000, + [Description("מיליארד")] Billions = 1000000000 } public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - if (number < 0) - { - return $"מינוס {Convert(-number, gender)}"; - } + var number = (int) input; - if (number == 0) - { - return UnitsFeminine[0]; - } + if (number < 0) + { + return $"מינוס {Convert(-number, gender)}"; + } - var parts = new List(); - if (number >= (int)Group.Billions) - { - ToBigNumber(number, Group.Billions, parts); - number %= (int)Group.Billions; - } + if (number == 0) + { + return UnitsFeminine[0]; + } - if (number >= (int)Group.Millions) - { - ToBigNumber(number, Group.Millions, parts); - number %= (int)Group.Millions; - } + var parts = new List(); + if (number >= (int) Group.Billions) + { + ToBigNumber(number, Group.Billions, parts); + number %= (int) Group.Billions; + } - if (number >= (int)Group.Thousands) - { - ToThousands(number, parts); - number %= (int)Group.Thousands; - } + if (number >= (int) Group.Millions) + { + ToBigNumber(number, Group.Millions, parts); + number %= (int) Group.Millions; + } - if (number >= (int)Group.Hundreds) - { - ToHundreds(number, parts); - number %= (int)Group.Hundreds; - } + if (number >= (int) Group.Thousands) + { + ToThousands(number, parts); + number %= (int) Group.Thousands; + } - if (number > 0) - { - var appendAnd = parts.Count != 0; + if (number >= (int) Group.Hundreds) + { + ToHundreds(number, parts); + number %= (int) Group.Hundreds; + } - if (number <= 10) + if (number > 0) + { + var appendAnd = parts.Count != 0; + + if (number <= 10) + { + var unit = gender == GrammaticalGender.Masculine ? UnitsMasculine[number] : UnitsFeminine[number]; + if (appendAnd) { - var unit = gender == GrammaticalGender.Masculine ? UnitsMasculine[number] : UnitsFeminine[number]; - if (appendAnd) - { - unit = "ו" + unit; - } + unit = "ו" + unit; + } - parts.Add(unit); + parts.Add(unit); + } + else if (number < 20) + { + var unit = Convert(number % 10, gender); + unit = unit.Replace("יי", "י"); + unit = $"{unit} {(gender == GrammaticalGender.Masculine ? "עשר" : "עשרה")}"; + if (appendAnd) + { + unit = "ו" + unit; } - else if (number < 20) + + parts.Add(unit); + } + else + { + var tenUnit = TensUnit[number / 10 - 1]; + if (number % 10 == 0) { - var unit = Convert(number % 10, gender); - unit = unit.Replace("יי", "י"); - unit = $"{unit} {(gender == GrammaticalGender.Masculine ? "עשר" : "עשרה")}"; - if (appendAnd) - { - unit = "ו" + unit; - } - - parts.Add(unit); + parts.Add(tenUnit); } else { - var tenUnit = TensUnit[number / 10 - 1]; - if (number % 10 == 0) - { - parts.Add(tenUnit); - } - else - { - var unit = Convert(number % 10, gender); - parts.Add($"{tenUnit} ו{unit}"); - } + var unit = Convert(number % 10, gender); + parts.Add($"{tenUnit} ו{unit}"); } } - - return string.Join(" ", parts); } + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) => number.ToString(culture); void ToBigNumber(int number, Group group, List parts) { - // Big numbers (million and above) always use the masculine form - // See https://www.safa-ivrit.org/dikduk/numbers.php + // Big numbers (million and above) always use the masculine form + // See https://www.safa-ivrit.org/dikduk/numbers.php - var digits = number / (int)group; - if (digits == 2) - { - parts.Add("שני"); - } - else if (digits > 2) - { - parts.Add(Convert(digits, GrammaticalGender.Masculine)); - } - - parts.Add(group.Humanize()); + var digits = number / (int) group; + if (digits == 2) + { + parts.Add("שני"); } + else if (digits > 2) + { + parts.Add(Convert(digits, GrammaticalGender.Masculine)); + } + + parts.Add(group.Humanize()); + } void ToThousands(int number, List parts) { - var thousands = number / (int)Group.Thousands; + var thousands = number / (int) Group.Thousands; - if (thousands == 1) - { - parts.Add("אלף"); - } - else if (thousands == 2) - { - parts.Add("אלפיים"); - } - else if (thousands == 8) - { - parts.Add("שמונת אלפים"); - } - else if (thousands <= 10) - { - parts.Add(UnitsFeminine[thousands] + "ת" + " אלפים"); - } - else - { - parts.Add(Convert(thousands) + " אלף"); - } + if (thousands == 1) + { + parts.Add("אלף"); + } + else if (thousands == 2) + { + parts.Add("אלפיים"); + } + else if (thousands == 8) + { + parts.Add("שמונת אלפים"); } + else if (thousands <= 10) + { + parts.Add(UnitsFeminine[thousands] + "ת" + " אלפים"); + } + else + { + parts.Add(Convert(thousands) + " אלף"); + } + } static void ToHundreds(int number, List parts) { - // For hundreds, Hebrew is using the feminine form - // See https://www.safa-ivrit.org/dikduk/numbers.php + // For hundreds, Hebrew is using the feminine form + // See https://www.safa-ivrit.org/dikduk/numbers.php - var hundreds = number / (int)Group.Hundreds; + var hundreds = number / (int) Group.Hundreds; - if (hundreds == 1) - { - parts.Add("מאה"); - } - else if (hundreds == 2) - { - parts.Add("מאתיים"); - } - else - { - parts.Add(UnitsFeminine[hundreds] + " מאות"); - } + if (hundreds == 1) + { + parts.Add("מאה"); + } + else if (hundreds == 2) + { + parts.Add("מאתיים"); } + else + { + parts.Add(UnitsFeminine[hundreds] + " מאות"); + } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/IcelandicNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/IcelandicNumberToWordsConverter.cs index eb719842f..df081ffed 100644 --- a/src/Humanizer/Localisation/NumberToWords/IcelandicNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/IcelandicNumberToWordsConverter.cs @@ -10,6 +10,7 @@ class IcelandicNumberToWordsConverter : GenderedNumberToWordsConverter static readonly string[] UnitsOrdinalPrefixes = ["núllt", "fyrst", string.Empty, "þriðj", "fjórð", "fimmt", "sjött", "sjöund", "áttund", "níund", "tíund", "elleft", "tólft", "þrettánd", "fjórtánd", "fimmtánd", "sextánd", "sautjánd", "átjánd", "nítjánd"]; static readonly string[] TensOrdinalPrefixes = [string.Empty, "tíund", "tuttugast", "þrítugast", "fertugast", "fimmtugast", "sextugast", "sjötugast", "áttugast", "nítugast"]; const string AndSplit = "og"; + class Fact { public long Power { get; set; } @@ -18,16 +19,89 @@ class Fact public required string Single { get; set; } public required string OrdinalPrefix { get; set; } } + static readonly Dictionary PowerOfTenMap = new() { - {0, new(){Power = 0 , Single = string.Empty, Plural = string.Empty, OrdinalPrefix = string.Empty, Gender = GrammaticalGender.Neuter }}, - {2, new(){Power = 2 , Single = "hundrað", Plural = "hundruð", OrdinalPrefix = "hundruðast", Gender = GrammaticalGender.Neuter }}, - {3, new(){Power = 1000 , Single = "eitt þúsund", Plural = "þúsund", OrdinalPrefix = "þúsundast", Gender = GrammaticalGender.Neuter }}, - {6, new(){Power = 1000000 , Single = "ein milljón", Plural = "milljónir", OrdinalPrefix = "milljónast", Gender = GrammaticalGender.Feminine }}, - {9, new(){Power = 1000000000 , Single = "einn milljarður", Plural = "milljarðar", OrdinalPrefix = "milljarðast", Gender = GrammaticalGender.Masculine }}, - {12, new(){Power = 1000000000000 , Single = "ein billjón", Plural = "billjónir", OrdinalPrefix = "billjónast", Gender = GrammaticalGender.Feminine }}, - {15, new(){Power = 1000000000000000 , Single = "einn billjarður", Plural = "billjarðar", OrdinalPrefix = "billjarðast", Gender = GrammaticalGender.Masculine }}, - {18, new(){Power = 1000000000000000000 , Single = "ein trilljón", Plural = "trilljónir", OrdinalPrefix = "trilljónast", Gender = GrammaticalGender.Feminine }} + { + 0, new() + { + Power = 0, + Single = string.Empty, + Plural = string.Empty, + OrdinalPrefix = string.Empty, + Gender = GrammaticalGender.Neuter + } + }, + { + 2, new() + { + Power = 2, + Single = "hundrað", + Plural = "hundruð", + OrdinalPrefix = "hundruðast", + Gender = GrammaticalGender.Neuter + } + }, + { + 3, new() + { + Power = 1000, + Single = "eitt þúsund", + Plural = "þúsund", + OrdinalPrefix = "þúsundast", + Gender = GrammaticalGender.Neuter + } + }, + { + 6, new() + { + Power = 1000000, + Single = "ein milljón", + Plural = "milljónir", + OrdinalPrefix = "milljónast", + Gender = GrammaticalGender.Feminine + } + }, + { + 9, new() + { + Power = 1000000000, + Single = "einn milljarður", + Plural = "milljarðar", + OrdinalPrefix = "milljarðast", + Gender = GrammaticalGender.Masculine + } + }, + { + 12, new() + { + Power = 1000000000000, + Single = "ein billjón", + Plural = "billjónir", + OrdinalPrefix = "billjónast", + Gender = GrammaticalGender.Feminine + } + }, + { + 15, new() + { + Power = 1000000000000000, + Single = "einn billjarður", + Plural = "billjarðar", + OrdinalPrefix = "billjarðast", + Gender = GrammaticalGender.Masculine + } + }, + { + 18, new() + { + Power = 1000000000000000000, + Single = "ein trilljón", + Plural = "trilljónir", + OrdinalPrefix = "trilljónast", + Gender = GrammaticalGender.Feminine + } + } }; static bool IsAndSplitNeeded(int number) => @@ -38,276 +112,295 @@ static string GetOrdinalEnding(GrammaticalGender gender) => static void GetUnits(ICollection builder, long number, GrammaticalGender gender) { - if (number is > 0 and < 5) + if (number is > 0 and < 5) + { + var genderedForm = gender switch { - var genderedForm = gender switch + GrammaticalGender.Masculine => MasculineUnitsMap[number], + GrammaticalGender.Neuter => NeuterUnitsMap[number], + GrammaticalGender.Feminine => FeminineUnitsMap[number], + _ => throw new ArgumentOutOfRangeException(nameof(gender)) + }; + builder.Add(genderedForm); + } + else + { + builder.Add(UnitsMap[number]); + } + } + + static void CollectOrdinalParts(ICollection builder, int threeDigitPart, Fact conversionRule, GrammaticalGender partGender, GrammaticalGender ordinalGender) + { + var hundreds = threeDigitPart / 100; + var hundredRemainder = threeDigitPart % 100; + var units = hundredRemainder % 10; + var decade = hundredRemainder / 10 * 10; + var hasThousand = conversionRule.Power > 100; + + if (hundreds != 0) + { + GetUnits(builder, hundreds, GrammaticalGender.Neuter); + var hundredPrefix = hundreds == 1 ? PowerOfTenMap[2].Single : PowerOfTenMap[2].Plural; + if (hundredRemainder < 20 && false == hasThousand) + { + var genderedFormWithPostfix = partGender switch { - GrammaticalGender.Masculine => MasculineUnitsMap[number], - GrammaticalGender.Neuter => NeuterUnitsMap[number], - GrammaticalGender.Feminine => FeminineUnitsMap[number], - _ => throw new ArgumentOutOfRangeException(nameof(gender)) + GrammaticalGender.Masculine => hundredPrefix + "asti", + GrammaticalGender.Neuter => hundredPrefix + "asta", + GrammaticalGender.Feminine => hundredPrefix + "asta", + _ => throw new ArgumentOutOfRangeException(nameof(partGender)) }; - builder.Add(genderedForm); + builder.Add(genderedFormWithPostfix); } else { - builder.Add(UnitsMap[number]); + builder.Add(hundredPrefix); } } - static void CollectOrdinalParts(ICollection builder, int threeDigitPart, Fact conversionRule, GrammaticalGender partGender, GrammaticalGender ordinalGender) - { - var hundreds = threeDigitPart / 100; - var hundredRemainder = threeDigitPart % 100; - var units = hundredRemainder % 10; - var decade = hundredRemainder / 10 * 10; - var hasThousand = conversionRule.Power > 100; - - if (hundreds != 0) + if (decade >= 20) + { + if (units != 0) { - GetUnits(builder, hundreds, GrammaticalGender.Neuter); - var hundredPrefix = hundreds == 1 ? PowerOfTenMap[2].Single : PowerOfTenMap[2].Plural; - if (hundredRemainder < 20 && false == hasThousand) - { - var genderedFormWithPostfix = partGender switch - { - GrammaticalGender.Masculine => hundredPrefix + "asti", - GrammaticalGender.Neuter => hundredPrefix + "asta", - GrammaticalGender.Feminine => hundredPrefix + "asta", - _ => throw new ArgumentOutOfRangeException(nameof(partGender)) - }; - builder.Add(genderedFormWithPostfix); - } - else - { - builder.Add(hundredPrefix); - } + builder.Add(CollectOrdinalPartsUnderAHundred(decade, partGender)); + builder.Add(AndSplit); + builder.Add(CollectOrdinalPartsUnderAHundred(units, partGender)); } - if (decade >= 20) + else { - if (units != 0) + if (hundreds != 0) { - builder.Add(CollectOrdinalPartsUnderAHundred(decade, partGender)); builder.Add(AndSplit); - builder.Add(CollectOrdinalPartsUnderAHundred(units, partGender)); - } - else - { - if (hundreds != 0) - { - builder.Add(AndSplit); - } - builder.Add(CollectOrdinalPartsUnderAHundred(decade, partGender)); } + + builder.Add(CollectOrdinalPartsUnderAHundred(decade, partGender)); } - else if (hundredRemainder != 0) + } + else if (hundredRemainder != 0) + { + if (hundreds != 0) { - if (hundreds != 0) - { - builder.Add(AndSplit); - } - if (hasThousand) - { - GetUnits(builder, hundredRemainder, conversionRule.Gender); - } - else - { - builder.Add(CollectOrdinalPartsUnderAHundred(hundredRemainder, partGender)); - } + builder.Add(AndSplit); } + if (hasThousand) { - builder.Add(conversionRule.OrdinalPrefix + GetOrdinalEnding(ordinalGender)); + GetUnits(builder, hundredRemainder, conversionRule.Gender); + } + else + { + builder.Add(CollectOrdinalPartsUnderAHundred(hundredRemainder, partGender)); } } + if (hasThousand) + { + builder.Add(conversionRule.OrdinalPrefix + GetOrdinalEnding(ordinalGender)); + } + } + static string? CollectOrdinalPartsUnderAHundred(int number, GrammaticalGender gender) { - if (number is >= 0 and < 20) + if (number is >= 0 and < 20) + { + if (number == 2) { - if (number == 2) - { - return gender switch - { - GrammaticalGender.Masculine => "annar", - GrammaticalGender.Feminine => "önnur", - GrammaticalGender.Neuter => "annað", - _ => throw new ArgumentOutOfRangeException(nameof(gender)) - }; - } - else + return gender switch { - return UnitsOrdinalPrefixes[number] + GetOrdinalEnding(gender); - } + GrammaticalGender.Masculine => "annar", + GrammaticalGender.Feminine => "önnur", + GrammaticalGender.Neuter => "annað", + _ => throw new ArgumentOutOfRangeException(nameof(gender)) + }; } - - if (number < 100 && number % 10 == 0) + else { - return TensOrdinalPrefixes[number / 10] + GetOrdinalEnding(gender); + return UnitsOrdinalPrefixes[number] + GetOrdinalEnding(gender); } + } - return null; + if (number < 100 && number % 10 == 0) + { + return TensOrdinalPrefixes[number / 10] + GetOrdinalEnding(gender); } + return null; + } + static void CollectParts(IList parts, ref long number, ref bool needsAnd, Fact rule) { - var remainder = number / rule.Power; - if (remainder > 0) + var remainder = number / rule.Power; + if (remainder > 0) + { + number %= rule.Power; + var prevLen = parts.Count; + CollectPart(parts, remainder, rule); + if (number == 0 && needsAnd && false == parts + .Skip(prevLen) + .Contains(AndSplit)) { - number %= rule.Power; - var prevLen = parts.Count; - CollectPart(parts, remainder, rule); - if (number == 0 && needsAnd && false == parts.Skip(prevLen).Contains(AndSplit)) - { - parts.Insert(prevLen, AndSplit); - } - needsAnd = true; + parts.Insert(prevLen, AndSplit); } + + needsAnd = true; } + } static void CollectPart(ICollection parts, long number, Fact rule) { - if (number == 1) - { - parts.Add(rule.Single); - } - else - { - CollectPartUnderOneThousand(parts, number, rule.Gender); - parts.Add(rule.Plural); - } + if (number == 1) + { + parts.Add(rule.Single); + } + else + { + CollectPartUnderOneThousand(parts, number, rule.Gender); + parts.Add(rule.Plural); } + } static void CollectPartUnderOneThousand(ICollection builder, long number, GrammaticalGender gender) { - var hundreds = number / 100; - var hundredRemainder = number % 100; - var units = hundredRemainder % 10; - var tens = hundredRemainder / 10; + var hundreds = number / 100; + var hundredRemainder = number % 100; + var units = hundredRemainder % 10; + var tens = hundredRemainder / 10; - if (hundreds != 0) + if (hundreds != 0) + { + GetUnits(builder, hundreds, GrammaticalGender.Neuter); + builder.Add(hundreds == 1 ? PowerOfTenMap[2].Single : PowerOfTenMap[2].Plural); + } + + if (tens >= 2) + { + if (units != 0) { - GetUnits(builder, hundreds, GrammaticalGender.Neuter); - builder.Add(hundreds == 1 ? PowerOfTenMap[2].Single : PowerOfTenMap[2].Plural); + builder.Add(TensMap[tens]); + builder.Add(AndSplit); + GetUnits(builder, units, gender); } - - if (tens >= 2) + else { - if (units != 0) + if (hundreds != 0) { - builder.Add(TensMap[tens]); builder.Add(AndSplit); - GetUnits(builder, units, gender); } - else - { - if (hundreds != 0) - { - builder.Add(AndSplit); - } - builder.Add(TensMap[tens]); - } + builder.Add(TensMap[tens]); + } - else if (hundredRemainder != 0) + } + else if (hundredRemainder != 0) + { + if (hundreds != 0) { - if (hundreds != 0) - { - builder.Add(AndSplit); - } - GetUnits(builder, hundredRemainder, gender); + builder.Add(AndSplit); } + + GetUnits(builder, hundredRemainder, gender); } + } static void CollectOrdinal(IList parts, ref int number, ref bool needsAnd, Fact rule, GrammaticalGender gender) { - var remainder = number / rule.Power; - if (remainder > 0) - { - number %= (int)rule.Power; + var remainder = number / rule.Power; + if (remainder > 0) + { + number %= (int) rule.Power; - // https://malfar.arnastofnun.is/grein/65658 - if (number > 0 && (number > 19 || (number % 100 > 10 && number % 100 % 10 == 0))) + // https://malfar.arnastofnun.is/grein/65658 + if (number > 0 && (number > 19 || (number % 100 > 10 && number % 100 % 10 == 0))) + { + if (remainder == 1) { - if (remainder == 1) - { - parts.Add(rule.Single); - } - else - { - CollectPartUnderOneThousand(parts, remainder, rule.Gender); - if (rule.Power > 0) - { - parts.Add(rule.Plural); - } - } + parts.Add(rule.Single); } else { - var prevLen = parts.Count; - CollectOrdinalParts(parts, (int)remainder, rule, rule.Gender, gender); - if (number == 0 && needsAnd && false == parts.Skip(prevLen).Contains(AndSplit)) + CollectPartUnderOneThousand(parts, remainder, rule.Gender); + if (rule.Power > 0) { - parts.Insert(prevLen, AndSplit); + parts.Add(rule.Plural); } } - needsAnd = true; } + else + { + var prevLen = parts.Count; + CollectOrdinalParts(parts, (int) remainder, rule, rule.Gender, gender); + if (number == 0 && needsAnd && false == parts + .Skip(prevLen) + .Contains(AndSplit)) + { + parts.Insert(prevLen, AndSplit); + } + } + + needsAnd = true; } + } + public override string Convert(long number, GrammaticalGender gender, bool addAnd = true) { - if (number == 0) - { - return UnitsMap[number]; - } + if (number == 0) + { + return UnitsMap[number]; + } - var parts = new List(); - if (number < 0) - { - parts.Add("mínus"); - number = -number; - } + var parts = new List(); + if (number < 0) + { + parts.Add("mínus"); + number = -number; + } - var needsAnd = false; - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[18]); - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[15]); - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[12]); - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[9]); - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[6]); - CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[3]); + var needsAnd = false; + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[18]); + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[15]); + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[12]); + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[9]); + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[6]); + CollectParts(parts, ref number, ref needsAnd, PowerOfTenMap[3]); - if (number > 0) + if (number > 0) + { + if (needsAnd && IsAndSplitNeeded((int) number)) { - if (needsAnd && IsAndSplitNeeded((int)number)) - { - parts.Add(AndSplit); - } - CollectPartUnderOneThousand(parts, number, gender); + parts.Add(AndSplit); } - return string.Join(" ", parts); + + CollectPartUnderOneThousand(parts, number, gender); } + + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - if (number == 0) - { - return UnitsOrdinalPrefixes[number] + GetOrdinalEnding(gender); - } - var parts = new List(); - var needsAnd = false; + if (number == 0) + { + return UnitsOrdinalPrefixes[number] + GetOrdinalEnding(gender); + } - CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[12], gender); - CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[9], gender); - CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[6], gender); - CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[3], gender); + var parts = new List(); + var needsAnd = false; - if (number > 0) + CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[12], gender); + CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[9], gender); + CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[6], gender); + CollectOrdinal(parts, ref number, ref needsAnd, PowerOfTenMap[3], gender); + + if (number > 0) + { + if (needsAnd && IsAndSplitNeeded(number)) { - if (needsAnd && IsAndSplitNeeded(number)) - { - parts.Add(AndSplit); - } - CollectOrdinalParts(parts, number, PowerOfTenMap[0], gender, gender); + parts.Add(AndSplit); } - return string.Join(" ", parts); + + CollectOrdinalParts(parts, number, PowerOfTenMap[0], gender, gender); } + + return string.Join(" ", parts); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/IndianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/IndianNumberToWordsConverter.cs index 9a4ebf0ec..b1db0e154 100644 --- a/src/Humanizer/Localisation/NumberToWords/IndianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/IndianNumberToWordsConverter.cs @@ -4,15 +4,32 @@ class IndianNumberToWordsConverter : GenderlessNumberToWordsConverter { static readonly Dictionary OrdinalExceptions = new() { - {1, "first"}, - {2, "second"}, - {3, "third"}, - {4, "fourth"}, - {5, "fifth"}, - {8, "eighth"}, - {9, "ninth"}, - {12, "twelfth"}, + { + 1, "first" + }, + { + 2, "second" + }, + { + 3, "third" + }, + { + 4, "fourth" + }, + { + 5, "fifth" + }, + { + 8, "eighth" + }, + { + 9, "ninth" + }, + { + 12, "twelfth" + }, }; + static readonly string[] Tillnineteen = [ "one", "two", "three", "four", "five", "six", "seven", "eight", @@ -27,40 +44,43 @@ class IndianNumberToWordsConverter : GenderlessNumberToWordsConverter ]; public override string Convert(long number) => - NumberToText(number).Trim(); + NumberToText(number) + .Trim(); public override string ConvertToOrdinal(int number) { - var result = NumberToText(number).Trim(); - return result; - } + var result = NumberToText(number) + .Trim(); + return result; + } - public static string NumberToText( long number) + public static string NumberToText(long number) { - if (number < 0) - return "(Negative) " + NumberToText(-number); - if (number == 0) - return ""; - if (number <= 19) - return Tillnineteen[number - 1] + " "; - if (number <= 99) - return Tens[number / 10 - 2] + " " + NumberToText(number % 10); - if (number <= 199) - return ("one hundred " + (number % 100 > 0 ? "and " : "") + NumberToText(number % 100)).Trim(); - if (number <= 999) - return NumberToText(number / 100) + "hundred " + (number % 100 > 0 ? "and " : "") + NumberToText(number % 100); - if (number <= 1999) - return "one thousand " + NumberToText(number % 1000); - if (number <= 99999) - return NumberToText(number / 1000) + "thousand " + NumberToText(number % 1000); - if (number <= 199999) - return ("one lakh " + NumberToText(number % 100000)).Trim(); - if (number <= 9999999) - return NumberToText(number / 100000) + "lakh " + NumberToText(number % 100000); - if (number <= 19999999) - return "one crore " + NumberToText(number % 10000000); - return NumberToText(number / 10000000).Trim() + " crore " + NumberToText(number % 10000000); - } + if (number < 0) + return "(Negative) " + NumberToText(-number); + if (number == 0) + return ""; + if (number <= 19) + return Tillnineteen[number - 1] + " "; + if (number <= 99) + return Tens[number / 10 - 2] + " " + NumberToText(number % 10); + if (number <= 199) + return ("one hundred " + (number % 100 > 0 ? "and " : "") + NumberToText(number % 100)).Trim(); + if (number <= 999) + return NumberToText(number / 100) + "hundred " + (number % 100 > 0 ? "and " : "") + NumberToText(number % 100); + if (number <= 1999) + return "one thousand " + NumberToText(number % 1000); + if (number <= 99999) + return NumberToText(number / 1000) + "thousand " + NumberToText(number % 1000); + if (number <= 199999) + return ("one lakh " + NumberToText(number % 100000)).Trim(); + if (number <= 9999999) + return NumberToText(number / 100000) + "lakh " + NumberToText(number % 100000); + if (number <= 19999999) + return "one crore " + NumberToText(number % 10000000); + return NumberToText(number / 10000000) + .Trim() + " crore " + NumberToText(number % 10000000); + } static bool ExceptionNumbersToWords(long number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); diff --git a/src/Humanizer/Localisation/NumberToWords/Italian/ItalianCardinalNumberCruncher.cs b/src/Humanizer/Localisation/NumberToWords/Italian/ItalianCardinalNumberCruncher.cs index dee73c59c..790496d81 100644 --- a/src/Humanizer/Localisation/NumberToWords/Italian/ItalianCardinalNumberCruncher.cs +++ b/src/Humanizer/Localisation/NumberToWords/Italian/ItalianCardinalNumberCruncher.cs @@ -4,28 +4,28 @@ class ItalianCardinalNumberCruncher(int number, GrammaticalGender gender) { public string Convert() { - // it's easier to treat zero as a completely distinct case - if (_fullNumber == 0) - { - return "zero"; - } + // it's easier to treat zero as a completely distinct case + if (_fullNumber == 0) + { + return "zero"; + } - var words = string.Empty; + var words = string.Empty; - foreach (var part in _threeDigitParts) - { - var partToString = GetNextPartConverter(); + foreach (var part in _threeDigitParts) + { + var partToString = GetNextPartConverter(); - if (partToString != null) - { - words = partToString(part) + words; - } + if (partToString != null) + { + words = partToString(part) + words; } - - // remove trailing spaces if there are only millions or billions - return words.TrimEnd(); } + // remove trailing spaces if there are only millions or billions + return words.TrimEnd(); + } + protected readonly int _fullNumber = number; protected readonly List _threeDigitParts = SplitEveryThreeDigits(number); protected readonly GrammaticalGender _gender = gender; @@ -40,21 +40,21 @@ public string Convert() /// The sequence of three-digit numbers. protected static List SplitEveryThreeDigits(int number) { - var parts = new List(); - var rest = number; + var parts = new List(); + var rest = number; - while (rest > 0) - { - var threeDigit = rest % 1000; - - parts.Add(threeDigit); + while (rest > 0) + { + var threeDigit = rest % 1000; - rest /= 1000; - } + parts.Add(threeDigit); - return parts; + rest /= 1000; } + return parts; + } + /// /// During number conversion to text, finds out the converter to use /// for the next three-digit set. @@ -62,41 +62,41 @@ protected static List SplitEveryThreeDigits(int number) /// The next conversion function to use. public Func? GetNextPartConverter() { - Func? converter; - - switch (_nextSet) - { - case ThreeDigitSets.Units: - converter = UnitsConverter; - _nextSet = ThreeDigitSets.Thousands; - break; - - case ThreeDigitSets.Thousands: - converter = ThousandsConverter; - _nextSet = ThreeDigitSets.Millions; - break; - - case ThreeDigitSets.Millions: - converter = MillionsConverter; - _nextSet = ThreeDigitSets.Billions; - break; - - case ThreeDigitSets.Billions: - converter = BillionsConverter; - _nextSet = ThreeDigitSets.More; - break; - - case ThreeDigitSets.More: - converter = null; - break; - - default: - throw new ArgumentOutOfRangeException("Unknow ThreeDigitSet: " + _nextSet); - } - - return converter; + Func? converter; + + switch (_nextSet) + { + case ThreeDigitSets.Units: + converter = UnitsConverter; + _nextSet = ThreeDigitSets.Thousands; + break; + + case ThreeDigitSets.Thousands: + converter = ThousandsConverter; + _nextSet = ThreeDigitSets.Millions; + break; + + case ThreeDigitSets.Millions: + converter = MillionsConverter; + _nextSet = ThreeDigitSets.Billions; + break; + + case ThreeDigitSets.Billions: + converter = BillionsConverter; + _nextSet = ThreeDigitSets.More; + break; + + case ThreeDigitSets.More: + converter = null; + break; + + default: + throw new ArgumentOutOfRangeException("Unknow ThreeDigitSet: " + _nextSet); } + return converter; + } + /// /// Converts a three-digit set to text. /// @@ -105,57 +105,57 @@ protected static List SplitEveryThreeDigits(int number) /// The same three-digit set expressed as text. static string ThreeDigitSetConverter(int number, bool thisIsLastSet = false) { - if (number == 0) - { - return string.Empty; - } + if (number == 0) + { + return string.Empty; + } - // grab lowest two digits - var tensAndUnits = number % 100; - // grab third digit - var hundreds = number / 100; + // grab lowest two digits + var tensAndUnits = number % 100; + // grab third digit + var hundreds = number / 100; - // grab also first and second digits separately - var units = tensAndUnits % 10; - var tens = tensAndUnits / 10; + // grab also first and second digits separately + var units = tensAndUnits % 10; + var tens = tensAndUnits / 10; - var words = string.Empty; + var words = string.Empty; - // append text for hundreds - words += _hundredNumberToText[hundreds]; + // append text for hundreds + words += _hundredNumberToText[hundreds]; - // append text for tens, only those from twenty upward - words += _tensOver20NumberToText[tens]; + // append text for tens, only those from twenty upward + words += _tensOver20NumberToText[tens]; - if (tensAndUnits <= 9) - { - // simple case for units, under 10 - words += _unitsNumberToText[tensAndUnits]; - } - else if (tensAndUnits <= 19) + if (tensAndUnits <= 9) + { + // simple case for units, under 10 + words += _unitsNumberToText[tensAndUnits]; + } + else if (tensAndUnits <= 19) + { + // special case for 'teens', from 10 to 19 + words += _teensUnder20NumberToText[tensAndUnits - 10]; + } + else + { + // just append units text, with some corner cases + + // truncate tens last vowel before 'uno' (1) and 'otto' (8) + if (units is 1 or 8) { - // special case for 'teens', from 10 to 19 - words += _teensUnder20NumberToText[tensAndUnits - 10]; + words = words.Remove(words.Length - 1); } - else - { - // just append units text, with some corner cases - - // truncate tens last vowel before 'uno' (1) and 'otto' (8) - if (units is 1 or 8) - { - words = words.Remove(words.Length - 1); - } - // if this is the last set, an accent could be due - var unitsText = thisIsLastSet && units == 3 ? "tré" : _unitsNumberToText[units]; + // if this is the last set, an accent could be due + var unitsText = thisIsLastSet && units == 3 ? "tré" : _unitsNumberToText[units]; - words += unitsText; - } - - return words; + words += unitsText; } + return words; + } + /// /// Converts a three-digit number, as units, to text. /// @@ -163,15 +163,15 @@ static string ThreeDigitSetConverter(int number, bool thisIsLastSet = false) /// The same three-digit number, as units, expressed as text. protected string UnitsConverter(int number) { - // being a unique case, it's easier to treat unity feminine gender as a completely distinct case - if (_gender == GrammaticalGender.Feminine && _fullNumber == 1) - { - return "una"; - } - - return ThreeDigitSetConverter(number, true); + // being a unique case, it's easier to treat unity feminine gender as a completely distinct case + if (_gender == GrammaticalGender.Feminine && _fullNumber == 1) + { + return "una"; } + return ThreeDigitSetConverter(number, true); + } + /// /// Converts a thousands three-digit number to text. /// @@ -179,19 +179,19 @@ protected string UnitsConverter(int number) /// The same three-digit number of thousands expressed as text. protected static string ThousandsConverter(int number) { - if (number == 0) - { - return string.Empty; - } - - if (number == 1) - { - return "mille"; - } + if (number == 0) + { + return string.Empty; + } - return ThreeDigitSetConverter(number) + "mila"; + if (number == 1) + { + return "mille"; } + return ThreeDigitSetConverter(number) + "mila"; + } + /// /// Converts a millions three-digit number to text. /// @@ -199,19 +199,19 @@ protected static string ThousandsConverter(int number) /// The same three-digit number of millions expressed as text. protected static string MillionsConverter(int number) { - if (number == 0) - { - return string.Empty; - } - - if (number == 1) - { - return "un milione "; - } + if (number == 0) + { + return string.Empty; + } - return ThreeDigitSetConverter(number, true) + " milioni "; + if (number == 1) + { + return "un milione "; } + return ThreeDigitSetConverter(number, true) + " milioni "; + } + /// /// Converts a billions three-digit number to text. /// @@ -219,14 +219,14 @@ protected static string MillionsConverter(int number) /// The same three-digit number of billions expressed as text. protected static string BillionsConverter(int number) { - if (number == 1) - { - return "un miliardo "; - } - - return ThreeDigitSetConverter(number) + " miliardi "; + if (number == 1) + { + return "un miliardo "; } + return ThreeDigitSetConverter(number) + " miliardi "; + } + /// /// Lookup table converting units number to text. Index 1 for 1, index 2 for 2, up to index 9. /// diff --git a/src/Humanizer/Localisation/NumberToWords/Italian/ItalianOrdinalNumberCruncher.cs b/src/Humanizer/Localisation/NumberToWords/Italian/ItalianOrdinalNumberCruncher.cs index 701e9b1be..b02a288c1 100644 --- a/src/Humanizer/Localisation/NumberToWords/Italian/ItalianOrdinalNumberCruncher.cs +++ b/src/Humanizer/Localisation/NumberToWords/Italian/ItalianOrdinalNumberCruncher.cs @@ -4,85 +4,85 @@ class ItalianOrdinalNumberCruncher(int number, GrammaticalGender gender) { public string Convert() { - // it's easier to treat zero as a completely distinct case - if (_fullNumber == 0) - { - return "zero"; - } + // it's easier to treat zero as a completely distinct case + if (_fullNumber == 0) + { + return "zero"; + } - if (_fullNumber <= 9) - { - // units ordinals, 1 to 9, are totally different than the rest: treat them as a distinct case - return _unitsUnder10NumberToText[_fullNumber] + _genderSuffix; - } + if (_fullNumber <= 9) + { + // units ordinals, 1 to 9, are totally different than the rest: treat them as a distinct case + return _unitsUnder10NumberToText[_fullNumber] + _genderSuffix; + } - var cardinalCruncher = new ItalianCardinalNumberCruncher(_fullNumber, _gender); + var cardinalCruncher = new ItalianCardinalNumberCruncher(_fullNumber, _gender); - var words = cardinalCruncher.Convert(); + var words = cardinalCruncher.Convert(); - var tensAndUnits = _fullNumber % 100; + var tensAndUnits = _fullNumber % 100; - if (tensAndUnits == 10) + if (tensAndUnits == 10) + { + // for numbers ending in 10, cardinal and ordinal endings are different, suffix doesn't work + words = words.Remove(words.Length - _lengthOf10AsCardinal) + "decim" + _genderSuffix; + } + else + { + // truncate last vowel + words = words.Remove(words.Length - 1); + + var units = _fullNumber % 10; + + // reintroduce *unaccented* last vowel in some corner cases + if (units == 3) { - // for numbers ending in 10, cardinal and ordinal endings are different, suffix doesn't work - words = words.Remove(words.Length - _lengthOf10AsCardinal) + "decim" + _genderSuffix; + words += 'e'; } - else + else if (units == 6) { - // truncate last vowel - words = words.Remove(words.Length - 1); + words += 'i'; + } - var units = _fullNumber % 10; + var lowestThreeDigits = _fullNumber % 1000; + var lowestSixDigits = _fullNumber % 1000000; + var lowestNineDigits = _fullNumber % 1000000000; - // reintroduce *unaccented* last vowel in some corner cases - if (units == 3) - { - words += 'e'; - } - else if (units == 6) - { - words += 'i'; - } - - var lowestThreeDigits = _fullNumber % 1000; - var lowestSixDigits = _fullNumber % 1000000; - var lowestNineDigits = _fullNumber % 1000000000; + if (lowestNineDigits == 0) + { + // if exact billions, cardinal number words are joined + words = words.Replace(" miliard", "miliard"); - if (lowestNineDigits == 0) + // if 1 billion, numeral prefix is removed completely + if (_fullNumber == 1000000000) { - // if exact billions, cardinal number words are joined - words = words.Replace(" miliard", "miliard"); - - // if 1 billion, numeral prefix is removed completely - if (_fullNumber == 1000000000) - { - words = words.Replace("un", string.Empty); - } + words = words.Replace("un", string.Empty); } - else if (lowestSixDigits == 0) - { - // if exact millions, cardinal number words are joined - words = words.Replace(" milion", "milion"); - - // if 1 million, numeral prefix is removed completely - if (_fullNumber == 1000000) - { - words = words.Replace("un", string.Empty); - } - } - else if (lowestThreeDigits == 0 && _fullNumber > 1000) + } + else if (lowestSixDigits == 0) + { + // if exact millions, cardinal number words are joined + words = words.Replace(" milion", "milion"); + + // if 1 million, numeral prefix is removed completely + if (_fullNumber == 1000000) { - // if exact thousands, double the final 'l', apart from 1000 already having that - words += 'l'; + words = words.Replace("un", string.Empty); } - - // append common ordinal suffix - words += "esim" + _genderSuffix; + } + else if (lowestThreeDigits == 0 && _fullNumber > 1000) + { + // if exact thousands, double the final 'l', apart from 1000 already having that + words += 'l'; } - return words; + // append common ordinal suffix + words += "esim" + _genderSuffix; } + return words; + } + protected readonly int _fullNumber = number; protected readonly GrammaticalGender _gender = gender; readonly string _genderSuffix = gender == GrammaticalGender.Feminine ? "a" : "o"; diff --git a/src/Humanizer/Localisation/NumberToWords/ItalianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/ItalianNumberToWordsConverter.cs index 683f10446..aa610337c 100644 --- a/src/Humanizer/Localisation/NumberToWords/ItalianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/ItalianNumberToWordsConverter.cs @@ -4,26 +4,27 @@ class ItalianNumberToWordsConverter : GenderedNumberToWordsConverter { public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - - if (number < 0) - { - return "meno " + Convert(Math.Abs(number), gender); - } + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - var cruncher = new ItalianCardinalNumberCruncher(number, gender); + var number = (int) input; - return cruncher.Convert(); + if (number < 0) + { + return "meno " + Convert(Math.Abs(number), gender); } + var cruncher = new ItalianCardinalNumberCruncher(number, gender); + + return cruncher.Convert(); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - var cruncher = new ItalianOrdinalNumberCruncher(number, gender); + var cruncher = new ItalianOrdinalNumberCruncher(number, gender); - return cruncher.Convert(); - } + return cruncher.Convert(); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/JapaneseNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/JapaneseNumberToWordsConverter.cs index 74df6e1c5..ebca33ecb 100644 --- a/src/Humanizer/Localisation/NumberToWords/JapaneseNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/JapaneseNumberToWordsConverter.cs @@ -4,6 +4,7 @@ class JapaneseNumberToWordsConverter : GenderlessNumberToWordsConverter { static readonly string[] UnitsMap1 = ["", "", "二", "三", "四", "五", "六", "七", "八", "九"]; static readonly string[] UnitsMap2 = ["", "十", "百", "千"]; + static readonly string[] UnitsMap3 = [ "", "万", "億", "兆", "京", "垓", "𥝱", "穣", "溝", "澗", "正", "載", "極", @@ -18,47 +19,47 @@ public override string ConvertToOrdinal(int number) => static string ConvertImpl(long number, bool isOrdinal) { - if (number == 0) - { - return isOrdinal ? "〇番目" : "〇"; - } - - if (number < 0) - { - return $"マイナス {ConvertImpl(-number, false)}"; - } + if (number == 0) + { + return isOrdinal ? "〇番目" : "〇"; + } - var parts = new List(); - var groupLevel = 0; - while (number > 0) - { - var groupNumber = number % 10000; - number /= 10000; + if (number < 0) + { + return $"マイナス {ConvertImpl(-number, false)}"; + } - var n0 = groupNumber % 10; - var n1 = (groupNumber % 100 - groupNumber % 10) / 10; - var n2 = (groupNumber % 1000 - groupNumber % 100) / 100; - var n3 = (groupNumber - groupNumber % 1000) / 1000; + var parts = new List(); + var groupLevel = 0; + while (number > 0) + { + var groupNumber = number % 10000; + number /= 10000; - parts.Add( - UnitsMap1[n3] + (n3 == 0 ? "" : UnitsMap2[3]) - + UnitsMap1[n2] + (n2 == 0 ? "" : UnitsMap2[2]) - + UnitsMap1[n1] + (n1 == 0 ? "" : UnitsMap2[1]) - + (n0 == 1 ? "一" : UnitsMap1[n0]) - + (groupNumber == 0 ? "" : UnitsMap3[groupLevel]) - ); + var n0 = groupNumber % 10; + var n1 = (groupNumber % 100 - groupNumber % 10) / 10; + var n2 = (groupNumber % 1000 - groupNumber % 100) / 100; + var n3 = (groupNumber - groupNumber % 1000) / 1000; - groupLevel++; - } + parts.Add( + UnitsMap1[n3] + (n3 == 0 ? "" : UnitsMap2[3]) + + UnitsMap1[n2] + (n2 == 0 ? "" : UnitsMap2[2]) + + UnitsMap1[n1] + (n1 == 0 ? "" : UnitsMap2[1]) + + (n0 == 1 ? "一" : UnitsMap1[n0]) + + (groupNumber == 0 ? "" : UnitsMap3[groupLevel]) + ); - parts.Reverse(); - var toWords = string.Concat(parts); + groupLevel++; + } - if (isOrdinal) - { - toWords = $"{toWords}番目"; - } + parts.Reverse(); + var toWords = string.Concat(parts); - return toWords; + if (isOrdinal) + { + toWords = $"{toWords}番目"; } + + return toWords; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/KoreanNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/KoreanNumberToWordsConverter.cs index 93439f28d..ae80f39a6 100644 --- a/src/Humanizer/Localisation/NumberToWords/KoreanNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/KoreanNumberToWordsConverter.cs @@ -8,26 +8,66 @@ class KoreanNumberToWordsConverter : GenderlessNumberToWordsConverter static readonly Dictionary OrdinalExceptions = new() { - {0, "영번째"}, - {1, "첫번째"}, - {2, "두번째"}, - {3, "세번째"}, - {4, "네번째"}, - {5, "다섯번째"}, - {6, "여섯번째"}, - {7, "일곱번째"}, - {8, "여덟번째"}, - {9, "아홉번째"}, - {10, "열번째"}, - {11, "열한번째"}, - {12, "열두번째"}, - {13, "열세번째"}, - {14, "열네번째"}, - {15, "열다섯번째"}, - {16, "열여섯번째"}, - {17, "열일곱번째"}, - {18, "열여덟번째"}, - {19, "열아홉째"}, + { + 0, "영번째" + }, + { + 1, "첫번째" + }, + { + 2, "두번째" + }, + { + 3, "세번째" + }, + { + 4, "네번째" + }, + { + 5, "다섯번째" + }, + { + 6, "여섯번째" + }, + { + 7, "일곱번째" + }, + { + 8, "여덟번째" + }, + { + 9, "아홉번째" + }, + { + 10, "열번째" + }, + { + 11, "열한번째" + }, + { + 12, "열두번째" + }, + { + 13, "열세번째" + }, + { + 14, "열네번째" + }, + { + 15, "열다섯번째" + }, + { + 16, "열여섯번째" + }, + { + 17, "열일곱번째" + }, + { + 18, "열여덟번째" + }, + { + 19, "열아홉째" + }, }; public override string Convert(long number) => @@ -38,53 +78,53 @@ public override string ConvertToOrdinal(int number) => static string ConvertImpl(long number, bool isOrdinal) { - if (isOrdinal && number < 20) - { - if (OrdinalExceptions.TryGetValue(number, out var words)) - return words; - } - - if (number == 0) - { - return "영"; - } + if (isOrdinal && number < 20) + { + if (OrdinalExceptions.TryGetValue(number, out var words)) + return words; + } - if (number < 0) - { - return $"마이너스 {ConvertImpl(-number, false)}"; - } + if (number == 0) + { + return "영"; + } - var parts = new List(); - var groupLevel = 0; - while (number > 0) - { - var groupNumber = number % 10000; - number /= 10000; + if (number < 0) + { + return $"마이너스 {ConvertImpl(-number, false)}"; + } - var n0 = groupNumber % 10; - var n1 = (groupNumber % 100 - groupNumber % 10) / 10; - var n2 = (groupNumber % 1000 - groupNumber % 100) / 100; - var n3 = (groupNumber - groupNumber % 1000) / 1000; + var parts = new List(); + var groupLevel = 0; + while (number > 0) + { + var groupNumber = number % 10000; + number /= 10000; - parts.Add( - UnitsMap1[n3] + (n3 == 0 ? "" : UnitsMap2[3]) - + UnitsMap1[n2] + (n2 == 0 ? "" : UnitsMap2[2]) - + UnitsMap1[n1] + (n1 == 0 ? "" : UnitsMap2[1]) - + (n0 == 1 ? "일" : UnitsMap1[n0]) - + (groupNumber == 0 ? "" : UnitsMap3[groupLevel]) - ); + var n0 = groupNumber % 10; + var n1 = (groupNumber % 100 - groupNumber % 10) / 10; + var n2 = (groupNumber % 1000 - groupNumber % 100) / 100; + var n3 = (groupNumber - groupNumber % 1000) / 1000; - groupLevel++; - } + parts.Add( + UnitsMap1[n3] + (n3 == 0 ? "" : UnitsMap2[3]) + + UnitsMap1[n2] + (n2 == 0 ? "" : UnitsMap2[2]) + + UnitsMap1[n1] + (n1 == 0 ? "" : UnitsMap2[1]) + + (n0 == 1 ? "일" : UnitsMap1[n0]) + + (groupNumber == 0 ? "" : UnitsMap3[groupLevel]) + ); - parts.Reverse(); - var toWords = string.Concat(parts); + groupLevel++; + } - if (isOrdinal) - { - toWords = $"{toWords}번째"; - } + parts.Reverse(); + var toWords = string.Concat(parts); - return toWords; + if (isOrdinal) + { + toWords = $"{toWords}번째"; } + + return toWords; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/LithuanianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/LithuanianNumberToWordsConverter.cs index 9096740ba..d8eb45ad0 100644 --- a/src/Humanizer/Localisation/NumberToWords/LithuanianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/LithuanianNumberToWordsConverter.cs @@ -12,148 +12,148 @@ class LithuanianNumberToWordsConverter : GenderedNumberToWordsConverter public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (gender == GrammaticalGender.Neuter) - { - throw new NotSupportedException(); - } + if (gender == GrammaticalGender.Neuter) + { + throw new NotSupportedException(); + } - var parts = new List(); - var number = input; + var parts = new List(); + var number = input; - HandleNegative(parts, ref number); - CollectParts(parts, ref number, 1000000000000000000, GrammaticalGender.Masculine, "kvintilijonas", "kvintilijonai", "kvintilijonų"); - CollectParts(parts, ref number, 1000000000000000, GrammaticalGender.Masculine, "kvadrilijonas", "kvadrilijonai", "kvadrilijonų"); - CollectParts(parts, ref number, 1000000000000, GrammaticalGender.Masculine, "trilijonas", "trilijonai", "trilijonų"); - CollectParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "milijardas", "milijardai", "milijardų"); - CollectParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "milijonas", "milijonai", "milijonų"); - CollectParts(parts, ref number, 1000, GrammaticalGender.Masculine, "tūkstantis", "tūkstančiai", "tūkstančių"); - CollectPartsUnderOneThousand(parts, number, gender); + HandleNegative(parts, ref number); + CollectParts(parts, ref number, 1000000000000000000, GrammaticalGender.Masculine, "kvintilijonas", "kvintilijonai", "kvintilijonų"); + CollectParts(parts, ref number, 1000000000000000, GrammaticalGender.Masculine, "kvadrilijonas", "kvadrilijonai", "kvadrilijonų"); + CollectParts(parts, ref number, 1000000000000, GrammaticalGender.Masculine, "trilijonas", "trilijonai", "trilijonų"); + CollectParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "milijardas", "milijardai", "milijardų"); + CollectParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "milijonas", "milijonai", "milijonų"); + CollectParts(parts, ref number, 1000, GrammaticalGender.Masculine, "tūkstantis", "tūkstančiai", "tūkstančių"); + CollectPartsUnderOneThousand(parts, number, gender); - return string.Join(" ", parts); - } + return string.Join(" ", parts); + } public override string ConvertToOrdinal(int input, GrammaticalGender gender) { - if (gender == GrammaticalGender.Neuter) - { - throw new NotSupportedException(); - } + if (gender == GrammaticalGender.Neuter) + { + throw new NotSupportedException(); + } - var parts = new List(); - var number = (long)input; + var parts = new List(); + var number = (long) input; - HandleNegative(parts, ref number); - CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "milijard" + GetOrdinalEndingForGender(gender), "milijardas", "milijardai", "milijardų"); - CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "milijon" + GetOrdinalEndingForGender(gender), "milijonas", "milijonai", "milijonų"); - CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Masculine, "tūkstant" + GetOrdinalEndingForGender(gender), "tūkstantis", "tūkstančiai", "tūkstančių"); - CollectOrdinalPartsUnderOneThousand(parts, number, gender, true); + HandleNegative(parts, ref number); + CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "milijard" + GetOrdinalEndingForGender(gender), "milijardas", "milijardai", "milijardų"); + CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "milijon" + GetOrdinalEndingForGender(gender), "milijonas", "milijonai", "milijonų"); + CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Masculine, "tūkstant" + GetOrdinalEndingForGender(gender), "tūkstantis", "tūkstančiai", "tūkstančių"); + CollectOrdinalPartsUnderOneThousand(parts, number, gender, true); - return string.Join(" ", parts); - } + return string.Join(" ", parts); + } static void HandleNegative(List parts, ref long number) { - if (number < 0) - { - parts.Add("minus"); - number = -number; - } + if (number < 0) + { + parts.Add("minus"); + number = -number; } + } static void CollectParts(ICollection parts, ref long number, long divisor, GrammaticalGender gender, params string[] forms) { - var result = number / divisor; - if (result == 0) - { - return; - } - - number %= divisor; + var result = number / divisor; + if (result == 0) + { + return; + } - if (result > 1) - { - CollectPartsUnderOneThousand(parts, result, gender); - } + number %= divisor; - parts.Add(ChooseForm(result, forms)); + if (result > 1) + { + CollectPartsUnderOneThousand(parts, result, gender); } + parts.Add(ChooseForm(result, forms)); + } + static void CollectOrdinalParts(ICollection parts, ref long number, long divisor, GrammaticalGender gender, string ordinalForm, params string[] forms) { - var result = number / divisor; - if (result == 0) - { - return; - } - - number %= divisor; + var result = number / divisor; + if (result == 0) + { + return; + } - if (result > 1) - { - CollectOrdinalPartsUnderOneThousand(parts, result, gender); - } + number %= divisor; - parts.Add(ChooseCardinalOrOrdinalForm(result, ordinalForm, forms, useOrdinalForm: number == 0)); + if (result > 1) + { + CollectOrdinalPartsUnderOneThousand(parts, result, gender); } + parts.Add(ChooseCardinalOrOrdinalForm(result, ordinalForm, forms, useOrdinalForm: number == 0)); + } + static void CollectPartsUnderOneThousand(ICollection parts, long number, GrammaticalGender gender) { - if (number >= 100) - { - var hundreds = number / 100; - number %= 100; - parts.Add(HundredsMap[hundreds]); - } + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + parts.Add(HundredsMap[hundreds]); + } - if (number >= 20) - { - var tens = number / 10; - parts.Add(TensMap[tens]); - number %= 10; - } + if (number >= 20) + { + var tens = number / 10; + parts.Add(TensMap[tens]); + number %= 10; + } - if (number > 0 || parts.Count == 0) - { - parts.Add(GetCardinalNumberForGender(UnitsMap[number], gender)); - } + if (number > 0 || parts.Count == 0) + { + parts.Add(GetCardinalNumberForGender(UnitsMap[number], gender)); } + } static void CollectOrdinalPartsUnderOneThousand(ICollection parts, long number, GrammaticalGender gender, bool lastNumber = false) { - if (number >= 100) - { - var hundreds = number / 100; - number %= 100; - - parts.Add(!lastNumber || number > 0 - ? HundredsMap[hundreds] - : OrdinalHundredsMap[hundreds] + GetOrdinalEndingForGender(gender)); - } + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + + parts.Add(!lastNumber || number > 0 + ? HundredsMap[hundreds] + : OrdinalHundredsMap[hundreds] + GetOrdinalEndingForGender(gender)); + } - if (number >= 20) - { - var tens = number / 10; - number %= 10; + if (number >= 20) + { + var tens = number / 10; + number %= 10; - parts.Add(!lastNumber || number > 0 - ? TensMap[tens] - : OrdinalTensMap[tens] + GetOrdinalEndingForGender(gender)); - } + parts.Add(!lastNumber || number > 0 + ? TensMap[tens] + : OrdinalTensMap[tens] + GetOrdinalEndingForGender(gender)); + } - if (number > 0) - { - parts.Add(!lastNumber - ? UnitsMap[number] - : OrdinalUnitsMap[number] + GetOrdinalEndingForGender(gender)); - } - else if (number == 0 && parts.Count == 0) - { - parts.Add(gender == GrammaticalGender.Masculine ? "nulinis" : "nulinė"); - } + if (number > 0) + { + parts.Add(!lastNumber + ? UnitsMap[number] + : OrdinalUnitsMap[number] + GetOrdinalEndingForGender(gender)); + } + else if (number == 0 && parts.Count == 0) + { + parts.Add(gender == GrammaticalGender.Masculine ? "nulinis" : "nulinė"); } + } static string ChooseForm(long number, string[] forms) => forms[GetFormIndex(number)]; @@ -161,81 +161,81 @@ static string ChooseForm(long number, string[] forms) => static string ChooseCardinalOrOrdinalForm(long number, string ordinalForm, string[] cardinalForms, bool useOrdinalForm = false) { - if (useOrdinalForm) - { - return ordinalForm; - } - - return ChooseForm(number, cardinalForms); + if (useOrdinalForm) + { + return ordinalForm; } + return ChooseForm(number, cardinalForms); + } + static int GetFormIndex(long number) { - var form = LithuanianNumberFormDetector.Detect(number); + var form = LithuanianNumberFormDetector.Detect(number); - switch (form) + switch (form) + { + case LithuanianNumberForm.Singular: + { + return 0; + } + case LithuanianNumberForm.Plural: + { + return 1; + } + case LithuanianNumberForm.GenitivePlural: { - case LithuanianNumberForm.Singular: - { - return 0; - } - case LithuanianNumberForm.Plural: - { - return 1; - } - case LithuanianNumberForm.GenitivePlural: - { - return 2; - } - default: - throw new ArgumentOutOfRangeException(nameof(form)); + return 2; } + default: + throw new ArgumentOutOfRangeException(nameof(form)); } + } static string GetCardinalNumberForGender(string number, GrammaticalGender gender) { - if (gender == GrammaticalGender.Masculine) + if (gender == GrammaticalGender.Masculine) + { + return number; + } + + if (gender == GrammaticalGender.Feminine) + { + if (number == "du") + { + return "dvi"; + } + + if (number.EndsWith("as")) { - return number; + return number.Substring(0, number.Length - 1); } - if (gender == GrammaticalGender.Feminine) + if (number.EndsWith("i")) { - if (number == "du") - { - return "dvi"; - } - - if (number.EndsWith("as")) - { - return number.Substring(0, number.Length - 1); - } - - if (number.EndsWith("i")) - { - return number + "os"; - } - - return number; + return number + "os"; } - throw new ArgumentOutOfRangeException(nameof(gender)); + return number; } + throw new ArgumentOutOfRangeException(nameof(gender)); + } + static string GetOrdinalEndingForGender(GrammaticalGender gender) { - switch (gender) + switch (gender) + { + case GrammaticalGender.Masculine: + { + return "as"; + } + case GrammaticalGender.Feminine: { - case GrammaticalGender.Masculine: - { - return "as"; - } - case GrammaticalGender.Feminine: - { - return "a"; - } - default: - throw new ArgumentOutOfRangeException(nameof(gender)); + return "a"; } + default: + throw new ArgumentOutOfRangeException(nameof(gender)); } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/NorwegianBokmalNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/NorwegianBokmalNumberToWordsConverter.cs index aca7f52c1..8bb124b29 100644 --- a/src/Humanizer/Localisation/NumberToWords/NorwegianBokmalNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/NorwegianBokmalNumberToWordsConverter.cs @@ -7,165 +7,186 @@ class NorwegianBokmalNumberToWordsConverter : GenderedNumberToWordsConverter static readonly Dictionary OrdinalExceptions = new() { - {0, "nullte"}, - {1, "første"}, - {2, "andre"}, - {3, "tredje"}, - {4, "fjerde"}, - {5, "femte"}, - {6, "sjette"}, - {11, "ellevte"}, - {12, "tolvte"} + { + 0, "nullte" + }, + { + 1, "første" + }, + { + 2, "andre" + }, + { + 3, "tredje" + }, + { + 4, "fjerde" + }, + { + 5, "femte" + }, + { + 6, "sjette" + }, + { + 11, "ellevte" + }, + { + 12, "tolvte" + } }; public override string Convert(long number, GrammaticalGender gender, bool addAnd = true) { - if (number is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - - return Convert((int)number, false, gender); + if (number is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); } + return Convert((int) number, false, gender); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) => Convert(number, true, gender); string Convert(int number, bool isOrdinal, GrammaticalGender gender) { - if (number == 0) - { - return GetUnitValue(0, isOrdinal); - } + if (number == 0) + { + return GetUnitValue(0, isOrdinal); + } - if (number < 0) - { - return $"minus {Convert(-number, isOrdinal, gender)}"; - } + if (number < 0) + { + return $"minus {Convert(-number, isOrdinal, gender)}"; + } - if (number == 1) + if (number == 1) + { + switch (gender) { - switch (gender) - { - case GrammaticalGender.Feminine: - return "ei"; - case GrammaticalGender.Neuter: - return "et"; - } + case GrammaticalGender.Feminine: + return "ei"; + case GrammaticalGender.Neuter: + return "et"; } + } - var parts = new List(); + var parts = new List(); - var millionOrMore = false; + var millionOrMore = false; - const int billion = 1000000000; - if (number / billion > 0) - { - millionOrMore = true; - var isExactOrdinal = isOrdinal && number % billion == 0; - parts.Add(Part("{0} milliard" + (isExactOrdinal ? "" : "er"), (isExactOrdinal ? "" : "en ") + "milliard", number / billion, !isExactOrdinal)); - number %= billion; - } + const int billion = 1000000000; + if (number / billion > 0) + { + millionOrMore = true; + var isExactOrdinal = isOrdinal && number % billion == 0; + parts.Add(Part("{0} milliard" + (isExactOrdinal ? "" : "er"), (isExactOrdinal ? "" : "en ") + "milliard", number / billion, !isExactOrdinal)); + number %= billion; + } - const int million = 1000000; - if (number / million > 0) - { - millionOrMore = true; - var isExactOrdinal = isOrdinal && number % million == 0; - parts.Add(Part("{0} million" + (isExactOrdinal ? "" : "er"), (isExactOrdinal ? "" : "en ") + "million", number / million, !isExactOrdinal)); - number %= million; - } + const int million = 1000000; + if (number / million > 0) + { + millionOrMore = true; + var isExactOrdinal = isOrdinal && number % million == 0; + parts.Add(Part("{0} million" + (isExactOrdinal ? "" : "er"), (isExactOrdinal ? "" : "en ") + "million", number / million, !isExactOrdinal)); + number %= million; + } - var thousand = false; - if (number / 1000 > 0) - { - thousand = true; - parts.Add(Part("{0}tusen", number % 1000 < 100 ? "tusen" : "ettusen", number / 1000)); - number %= 1000; - } + var thousand = false; + if (number / 1000 > 0) + { + thousand = true; + parts.Add(Part("{0}tusen", number % 1000 < 100 ? "tusen" : "ettusen", number / 1000)); + number %= 1000; + } - var hundred = false; - if (number / 100 > 0) - { - hundred = true; - parts.Add(Part("{0}hundre", thousand || millionOrMore ? "ethundre" : "hundre", number / 100)); - number %= 100; - } + var hundred = false; + if (number / 100 > 0) + { + hundred = true; + parts.Add(Part("{0}hundre", thousand || millionOrMore ? "ethundre" : "hundre", number / 100)); + number %= 100; + } - if (number > 0) + if (number > 0) + { + if (parts.Count != 0) { - if (parts.Count != 0) + if (millionOrMore && !hundred && !thousand) { - if (millionOrMore && !hundred && !thousand) - { - parts.Add("og "); - } - else - { - parts.Add("og"); - } - } - - if (number < 20) - { - parts.Add(GetUnitValue(number, isOrdinal)); + parts.Add("og "); } else { - var lastPart = TensMap[number / 10]; - if (number % 10 > 0) - { - lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; - } - else if (isOrdinal) - { - lastPart = lastPart.TrimEnd('e') + "ende"; - } - - parts.Add(lastPart); + parts.Add("og"); } } - else if (isOrdinal) + + if (number < 20) { - parts[^1] += (number == 0 ? "" : "en") + (millionOrMore ? "te" : "de"); + parts.Add(GetUnitValue(number, isOrdinal)); } + else + { + var lastPart = TensMap[number / 10]; + if (number % 10 > 0) + { + lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; + } + else if (isOrdinal) + { + lastPart = lastPart.TrimEnd('e') + "ende"; + } - var toWords = string.Concat(parts).Trim(); - - return toWords; + parts.Add(lastPart); + } + } + else if (isOrdinal) + { + parts[^1] += (number == 0 ? "" : "en") + (millionOrMore ? "te" : "de"); } + var toWords = string + .Concat(parts) + .Trim(); + + return toWords; + } + static string GetUnitValue(int number, bool isOrdinal) { - if (isOrdinal) + if (isOrdinal) + { + if (ExceptionNumbersToWords(number, out var exceptionString)) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } - - if (number < 13) - { - return UnitsMap[number].TrimEnd('e') + "ende"; - } + return exceptionString; + } - return UnitsMap[number] + "de"; + if (number < 13) + { + return UnitsMap[number] + .TrimEnd('e') + "ende"; } - return UnitsMap[number]; + return UnitsMap[number] + "de"; } + return UnitsMap[number]; + } + static bool ExceptionNumbersToWords(int number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); string Part(string pluralFormat, string singular, int number, bool postfixSpace = false) { - var postfix = postfixSpace ? " " : ""; - if (number == 1) - { - return singular + postfix; - } - - return string.Format(pluralFormat, Convert(number)) + postfix; + var postfix = postfixSpace ? " " : ""; + if (number == 1) + { + return singular + postfix; } + + return string.Format(pluralFormat, Convert(number)) + postfix; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/PolishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/PolishNumberToWordsConverter.cs index a5953d71a..c9474c4b9 100644 --- a/src/Humanizer/Localisation/NumberToWords/PolishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/PolishNumberToWordsConverter.cs @@ -35,120 +35,122 @@ class PolishNumberToWordsConverter(CultureInfo? culture) : public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input == 0) - { - return "zero"; - } + if (input == 0) + { + return "zero"; + } - var parts = new List(); - CollectParts(parts, input, gender); + var parts = new List(); + CollectParts(parts, input, gender); - return string.Join(" ", parts); - } + return string.Join(" ", parts); + } public override string ConvertToOrdinal(int number, GrammaticalGender gender) => number.ToString(culture); static void CollectParts(ICollection parts, long input, GrammaticalGender gender) { - var inputSign = 1; - if (input < 0) - { - parts.Add("minus"); - inputSign = -1; - } + var inputSign = 1; + if (input < 0) + { + parts.Add("minus"); + inputSign = -1; + } - var number = input; - var divisor = MaxPossibleDivisor; - var power = PowersOfThousandMap.Length - 1; - while (divisor > 0) + var number = input; + var divisor = MaxPossibleDivisor; + var power = PowersOfThousandMap.Length - 1; + while (divisor > 0) + { + var multiplier = (int) Math.Abs(number / divisor); + if (divisor > 1) { - var multiplier = (int) Math.Abs(number / divisor); - if (divisor > 1) + if (multiplier > 1) { - if (multiplier > 1) - { - CollectPartsUnderThousand(parts, multiplier, GrammaticalGender.Masculine); - } - - if (multiplier > 0) - { - parts.Add(GetPowerOfThousandNameForm(multiplier, power)); - } + CollectPartsUnderThousand(parts, multiplier, GrammaticalGender.Masculine); } - else if (multiplier > 0) + + if (multiplier > 0) { - if (multiplier == 1 && Math.Abs(input) != 1) - { - gender = GrammaticalGender.Masculine; - } - CollectPartsUnderThousand(parts, multiplier, gender); + parts.Add(GetPowerOfThousandNameForm(multiplier, power)); + } + } + else if (multiplier > 0) + { + if (multiplier == 1 && Math.Abs(input) != 1) + { + gender = GrammaticalGender.Masculine; } - number -= multiplier * divisor * inputSign; - divisor /= 1000; - power--; + CollectPartsUnderThousand(parts, multiplier, gender); } + + number -= multiplier * divisor * inputSign; + divisor /= 1000; + power--; } + } static void CollectPartsUnderThousand(ICollection parts, int number, GrammaticalGender gender) { - var hundredsDigit = number / 100; - var tensDigit = number % 100 / 10; - var unitsDigit = number % 10; + var hundredsDigit = number / 100; + var tensDigit = number % 100 / 10; + var unitsDigit = number % 10; - if (hundredsDigit >= 1) - { - parts.Add(HundredsMap[hundredsDigit]); - } + if (hundredsDigit >= 1) + { + parts.Add(HundredsMap[hundredsDigit]); + } - if (tensDigit >= 2) - { - parts.Add(TensMap[tensDigit]); - } + if (tensDigit >= 2) + { + parts.Add(TensMap[tensDigit]); + } - if (tensDigit != 1 && unitsDigit == 2) - { - var genderedForm = gender == GrammaticalGender.Feminine ? "dwie" : "dwa"; - parts.Add(genderedForm); - } - else if (number == 1) + if (tensDigit != 1 && unitsDigit == 2) + { + var genderedForm = gender == GrammaticalGender.Feminine ? "dwie" : "dwa"; + parts.Add(genderedForm); + } + else if (number == 1) + { + var genderedForm = gender switch { - var genderedForm = gender switch - { - GrammaticalGender.Masculine => "jeden", - GrammaticalGender.Feminine => "jedna", - GrammaticalGender.Neuter => "jedno", - _ => throw new ArgumentOutOfRangeException(nameof(gender)) - }; - parts.Add(genderedForm); - } - else + GrammaticalGender.Masculine => "jeden", + GrammaticalGender.Feminine => "jedna", + GrammaticalGender.Neuter => "jedno", + _ => throw new ArgumentOutOfRangeException(nameof(gender)) + }; + parts.Add(genderedForm); + } + else + { + var unit = unitsDigit + 10 * (tensDigit == 1 ? 1 : 0); + if (unit > 0) { - var unit = unitsDigit + 10 * (tensDigit == 1 ? 1 : 0); - if (unit > 0) - { - parts.Add(UnitsMap[unit]); - } + parts.Add(UnitsMap[unit]); } } + } static string GetPowerOfThousandNameForm(int multiplier, int power) { - const int singularIndex = 0; - const int pluralIndex = 1; - const int genitiveIndex = 2; - if (multiplier == 1) - { - return PowersOfThousandMap[power][singularIndex]; - } + const int singularIndex = 0; + const int pluralIndex = 1; + const int genitiveIndex = 2; + if (multiplier == 1) + { + return PowersOfThousandMap[power][singularIndex]; + } - var multiplierUnitsDigit = multiplier % 10; - var multiplierTensDigit = multiplier % 100 / 10; - if (multiplierTensDigit == 1 || multiplierUnitsDigit <= 1 || multiplierUnitsDigit >= 5) - { - return PowersOfThousandMap[power][genitiveIndex]; - } - return PowersOfThousandMap[power][pluralIndex]; + var multiplierUnitsDigit = multiplier % 10; + var multiplierTensDigit = multiplier % 100 / 10; + if (multiplierTensDigit == 1 || multiplierUnitsDigit <= 1 || multiplierUnitsDigit >= 5) + { + return PowersOfThousandMap[power][genitiveIndex]; } + + return PowersOfThousandMap[power][pluralIndex]; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/PortugueseNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/PortugueseNumberToWordsConverter.cs index ecc1a3f55..95972f73f 100644 --- a/src/Humanizer/Localisation/NumberToWords/PortugueseNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/PortugueseNumberToWordsConverter.cs @@ -12,182 +12,182 @@ class PortugueseNumberToWordsConverter : GenderedNumberToWordsConverter public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input is > 999999999999 or < -999999999999) - { - throw new NotImplementedException(); - } + if (input is > 999999999999 or < -999999999999) + { + throw new NotImplementedException(); + } - var number = input; + var number = input; - if (number == 0) - { - return "zero"; - } + if (number == 0) + { + return "zero"; + } - if (number < 0) - { - return $"menos {Convert(Math.Abs(number), gender)}"; - } + if (number < 0) + { + return $"menos {Convert(Math.Abs(number), gender)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000 > 0) - { - // gender is not applied for billions - parts.Add(number / 1000000000 == 1 - ? "mil milhões" - : $"{Convert(number / 1000000000)} mil milhões"); + if (number / 1000000000 > 0) + { + // gender is not applied for billions + parts.Add(number / 1000000000 == 1 + ? "mil milhões" + : $"{Convert(number / 1000000000)} mil milhões"); - number %= 1000000000; - } + number %= 1000000000; + } - if (number / 1000000 > 0) - { - // gender is not applied for millions - parts.Add(number / 1000000 >= 2 - ? $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhões" - : $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhão"); + if (number / 1000000 > 0) + { + // gender is not applied for millions + parts.Add(number / 1000000 >= 2 + ? $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhões" + : $"{Convert(number / 1000000, GrammaticalGender.Masculine)} milhão"); - number %= 1000000; - } + number %= 1000000; + } - if (number / 1000 > 0) + if (number / 1000 > 0) + { + // gender is not applied for thousands + parts.Add(number / 1000 == 1 ? "mil" : $"{Convert(number / 1000, GrammaticalGender.Masculine)} mil"); + number %= 1000; + } + + if (number / 100 > 0) + { + if (number == 100) { - // gender is not applied for thousands - parts.Add(number / 1000 == 1 ? "mil" : $"{Convert(number / 1000, GrammaticalGender.Masculine)} mil"); - number %= 1000; + parts.Add(parts.Count > 0 ? "e cem" : "cem"); } - - if (number / 100 > 0) + else { - if (number == 100) - { - parts.Add(parts.Count > 0 ? "e cem" : "cem"); - } - else - { - // Gender is applied to hundreds starting from 200 - parts.Add(ApplyGender(PortugueseHundredsMap[number / 100], gender)); - } - - number %= 100; + // Gender is applied to hundreds starting from 200 + parts.Add(ApplyGender(PortugueseHundredsMap[number / 100], gender)); } - if (number > 0) + number %= 100; + } + + if (number > 0) + { + if (parts.Count != 0) { - if (parts.Count != 0) - { - parts.Add("e"); - } + parts.Add("e"); + } - if (number < 20) + if (number < 20) + { + parts.Add(ApplyGender(PortugueseUnitsMap[number], gender)); + } + else + { + var lastPart = PortugueseTensMap[number / 10]; + if (number % 10 > 0) { - parts.Add(ApplyGender(PortugueseUnitsMap[number], gender)); + lastPart += $" e {ApplyGender(PortugueseUnitsMap[number % 10], gender)}"; } - else - { - var lastPart = PortugueseTensMap[number / 10]; - if (number % 10 > 0) - { - lastPart += $" e {ApplyGender(PortugueseUnitsMap[number % 10], gender)}"; - } - parts.Add(lastPart); - } + parts.Add(lastPart); } - - return string.Join(" ", parts); } + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - // N/A in Portuguese ordinal - if (number == 0) - { - return "zero"; - } + // N/A in Portuguese ordinal + if (number == 0) + { + return "zero"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000 > 0) - { - parts.Add(number / 1000000000 == 1 - ? $"{ApplyOrdinalGender("milésimo", gender)} {ApplyOrdinalGender("milionésimo", gender)}" - : $"{Convert(number / 1000000000)} {ApplyOrdinalGender("milésimo", gender)} {ApplyOrdinalGender("milionésimo", gender)}"); + if (number / 1000000000 > 0) + { + parts.Add(number / 1000000000 == 1 + ? $"{ApplyOrdinalGender("milésimo", gender)} {ApplyOrdinalGender("milionésimo", gender)}" + : $"{Convert(number / 1000000000)} {ApplyOrdinalGender("milésimo", gender)} {ApplyOrdinalGender("milionésimo", gender)}"); - number %= 1000000000; - } - - if (number / 1000000 > 0) - { - parts.Add(number / 1000000 == 1 - ? ApplyOrdinalGender("milionésimo", gender) - : string.Format("{0} " + ApplyOrdinalGender("milionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); + number %= 1000000000; + } - number %= 1000000; - } + if (number / 1000000 > 0) + { + parts.Add(number / 1000000 == 1 + ? ApplyOrdinalGender("milionésimo", gender) + : string.Format("{0} " + ApplyOrdinalGender("milionésimo", gender), ConvertToOrdinal(number / 1000000000, gender))); - if (number / 1000 > 0) - { - parts.Add(number / 1000 == 1 - ? ApplyOrdinalGender("milésimo", gender) - : string.Format("{0} " + ApplyOrdinalGender("milésimo", gender), ConvertToOrdinal(number / 1000, gender))); + number %= 1000000; + } - number %= 1000; - } + if (number / 1000 > 0) + { + parts.Add(number / 1000 == 1 + ? ApplyOrdinalGender("milésimo", gender) + : string.Format("{0} " + ApplyOrdinalGender("milésimo", gender), ConvertToOrdinal(number / 1000, gender))); - if (number / 100 > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalHundredsMap[number / 100], gender)); - number %= 100; - } + number %= 1000; + } - if (number / 10 > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalTensMap[number / 10], gender)); - number %= 10; - } + if (number / 100 > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalHundredsMap[number / 100], gender)); + number %= 100; + } - if (number > 0) - { - parts.Add(ApplyOrdinalGender(PortugueseOrdinalUnitsMap[number], gender)); - } + if (number / 10 > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalTensMap[number / 10], gender)); + number %= 10; + } - return string.Join(" ", parts); + if (number > 0) + { + parts.Add(ApplyOrdinalGender(PortugueseOrdinalUnitsMap[number], gender)); } + return string.Join(" ", parts); + } + static string ApplyGender(string toWords, GrammaticalGender gender) { - if (gender != GrammaticalGender.Feminine) - { - return toWords; - } - - if (toWords.EndsWith("os")) - { - return toWords.Substring(0, toWords.Length - 2) + "as"; - } + if (gender != GrammaticalGender.Feminine) + { + return toWords; + } - if (toWords.EndsWith("um")) - { - return toWords.Substring(0, toWords.Length - 2) + "uma"; - } + if (toWords.EndsWith("os")) + { + return toWords.Substring(0, toWords.Length - 2) + "as"; + } - if (toWords.EndsWith("dois")) - { - return toWords.Substring(0, toWords.Length - 4) + "duas"; - } + if (toWords.EndsWith("um")) + { + return toWords.Substring(0, toWords.Length - 2) + "uma"; + } - return toWords; + if (toWords.EndsWith("dois")) + { + return toWords.Substring(0, toWords.Length - 4) + "duas"; } + return toWords; + } + static string ApplyOrdinalGender(string toWords, GrammaticalGender gender) { - if (gender == GrammaticalGender.Feminine) - { - return toWords.TrimEnd('o') + 'a'; - } - - return toWords; + if (gender == GrammaticalGender.Feminine) + { + return toWords.TrimEnd('o') + 'a'; } + + return toWords; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianCardinalNumberConverter.cs b/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianCardinalNumberConverter.cs index 203c6eb92..2a27e4ffd 100644 --- a/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianCardinalNumberConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianCardinalNumberConverter.cs @@ -93,45 +93,47 @@ enum ThreeDigitSets public string Convert(int number, GrammaticalGender gender) { - if (number == 0) - { - return "zero"; - } + if (number == 0) + { + return "zero"; + } - var words = string.Empty; + var words = string.Empty; - var prefixMinusSign = false; + var prefixMinusSign = false; - if (number < 0) - { - prefixMinusSign = true; - number = -number; - } - - var _threeDigitParts = SplitEveryThreeDigits(number); + if (number < 0) + { + prefixMinusSign = true; + number = -number; + } - for (var i = 0; i < _threeDigitParts.Count; i++) - { - var currentSet = (ThreeDigitSets)Enum.ToObject(typeof(ThreeDigitSets), i); + var _threeDigitParts = SplitEveryThreeDigits(number); - var partToString = GetNextPartConverter(currentSet); + for (var i = 0; i < _threeDigitParts.Count; i++) + { + var currentSet = (ThreeDigitSets) Enum.ToObject(typeof(ThreeDigitSets), i); - if (partToString != null) - { - words = partToString(_threeDigitParts[i], gender) - .Trim() + " " + words.Trim(); - } - } + var partToString = GetNextPartConverter(currentSet); - if (prefixMinusSign) + if (partToString != null) { - words = _minusSign + " " + words; + words = partToString(_threeDigitParts[i], gender) + .Trim() + " " + words.Trim(); } + } - // remove extra spaces - return words.TrimEnd().Replace(" ", " "); + if (prefixMinusSign) + { + words = _minusSign + " " + words; } + // remove extra spaces + return words + .TrimEnd() + .Replace(" ", " "); + } + /// /// Splits a number into a sequence of three-digits numbers, /// starting from units, then thousands, millions, and so on. @@ -140,21 +142,21 @@ public string Convert(int number, GrammaticalGender gender) /// The sequence of three-digit numbers. static List SplitEveryThreeDigits(int number) { - var parts = new List(); - var rest = number; + var parts = new List(); + var rest = number; - while (rest > 0) - { - var threeDigit = rest % 1000; + while (rest > 0) + { + var threeDigit = rest % 1000; - parts.Add(threeDigit); + parts.Add(threeDigit); - rest /= 1000; - } - - return parts; + rest /= 1000; } + return parts; + } + /// /// During number conversion to text, finds out the converter /// to use for the next three-digit set. @@ -162,37 +164,37 @@ static List SplitEveryThreeDigits(int number) /// The next conversion function to use. Func? GetNextPartConverter(ThreeDigitSets currentSet) { - Func? converter; + Func? converter; - switch (currentSet) - { - case ThreeDigitSets.Units: - converter = UnitsConverter; - break; + switch (currentSet) + { + case ThreeDigitSets.Units: + converter = UnitsConverter; + break; - case ThreeDigitSets.Thousands: - converter = ThousandsConverter; - break; + case ThreeDigitSets.Thousands: + converter = ThousandsConverter; + break; - case ThreeDigitSets.Millions: - converter = MillionsConverter; - break; + case ThreeDigitSets.Millions: + converter = MillionsConverter; + break; - case ThreeDigitSets.Billions: - converter = BillionsConverter; - break; + case ThreeDigitSets.Billions: + converter = BillionsConverter; + break; - case ThreeDigitSets.More: - converter = null; - break; + case ThreeDigitSets.More: + converter = null; + break; - default: - throw new ArgumentOutOfRangeException("Unknow ThreeDigitSet: " + currentSet); - } - - return converter; + default: + throw new ArgumentOutOfRangeException("Unknow ThreeDigitSet: " + currentSet); } + return converter; + } + /// /// Converts a three-digit set to text. /// @@ -201,88 +203,88 @@ static List SplitEveryThreeDigits(int number) /// The same three-digit set expressed as text. string ThreeDigitSetConverter(int number, GrammaticalGender gender) { - if (number == 0) - { - return string.Empty; - } + if (number == 0) + { + return string.Empty; + } - // grab lowest two digits - var tensAndUnits = number % 100; - // grab third digit - var hundreds = number / 100; + // grab lowest two digits + var tensAndUnits = number % 100; + // grab third digit + var hundreds = number / 100; - // grab also first and second digits separately - var units = tensAndUnits % 10; - var tens = tensAndUnits / 10; + // grab also first and second digits separately + var units = tensAndUnits % 10; + var tens = tensAndUnits / 10; - var words = string.Empty; + var words = string.Empty; - // append text for hundreds - words += HundredsToText(hundreds); + // append text for hundreds + words += HundredsToText(hundreds); - // append text for tens, only those from twenty upward - words += (tens >= 2 ? " " : string.Empty) + _tensOver20NumberToText[tens]; + // append text for tens, only those from twenty upward + words += (tens >= 2 ? " " : string.Empty) + _tensOver20NumberToText[tens]; - if (tensAndUnits <= 9) - { - // simple case for units, under 10 - words += " " + GetPartByGender(_units[tensAndUnits], gender); - } - else if (tensAndUnits <= 19) - { - // special case for 'teens', from 10 to 19 - words += " " + GetPartByGender(_teensUnder20NumberToText[tensAndUnits - 10], gender); - } - else - { - // exception for zero - var unitsText = units == 0 ? string.Empty : " " + _joinGroups + " " + GetPartByGender(_units[units], gender); - - words += unitsText; - } + if (tensAndUnits <= 9) + { + // simple case for units, under 10 + words += " " + GetPartByGender(_units[tensAndUnits], gender); + } + else if (tensAndUnits <= 19) + { + // special case for 'teens', from 10 to 19 + words += " " + GetPartByGender(_teensUnder20NumberToText[tensAndUnits - 10], gender); + } + else + { + // exception for zero + var unitsText = units == 0 ? string.Empty : " " + _joinGroups + " " + GetPartByGender(_units[units], gender); - return words; + words += unitsText; } + return words; + } + static string GetPartByGender(string multiGenderPart, GrammaticalGender gender) { - if (multiGenderPart.Contains("|")) + if (multiGenderPart.Contains("|")) + { + var parts = multiGenderPart.Split('|'); + if (gender == GrammaticalGender.Feminine) { - var parts = multiGenderPart.Split('|'); - if (gender == GrammaticalGender.Feminine) - { - return parts[1]; - } - - if (gender == GrammaticalGender.Neuter) - { - return parts[2]; - } - - return parts[0]; + return parts[1]; } - return multiGenderPart; + if (gender == GrammaticalGender.Neuter) + { + return parts[2]; + } + + return parts[0]; } + return multiGenderPart; + } + static bool IsAbove20(int number) => number >= 20; string HundredsToText(int hundreds) { - if (hundreds == 0) - { - return string.Empty; - } - - if (hundreds == 1) - { - return _feminineSingular + " sută"; - } + if (hundreds == 0) + { + return string.Empty; + } - return GetPartByGender(_units[hundreds], GrammaticalGender.Feminine) + " sute"; + if (hundreds == 1) + { + return _feminineSingular + " sută"; } + return GetPartByGender(_units[hundreds], GrammaticalGender.Feminine) + " sute"; + } + /// /// Converts a three-digit number, as units, to text. /// @@ -300,19 +302,19 @@ string UnitsConverter(int number, GrammaticalGender gender) => /// The same three-digit number of thousands expressed as text. string ThousandsConverter(int number, GrammaticalGender gender) { - if (number == 0) - { - return string.Empty; - } - - if (number == 1) - { - return _feminineSingular + " mie"; - } + if (number == 0) + { + return string.Empty; + } - return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " mii"; + if (number == 1) + { + return _feminineSingular + " mie"; } + return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " mii"; + } + // Large numbers (above 10^6) use a combined form of the long and short scales. /* Singular Plural Order Scale @@ -333,19 +335,19 @@ trilion trilioane 10^12 short /// The same three-digit number of millions expressed as text. string MillionsConverter(int number, GrammaticalGender gender) { - if (number == 0) - { - return string.Empty; - } - - if (number == 1) - { - return _masculineSingular + " milion"; - } + if (number == 0) + { + return string.Empty; + } - return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " milioane"; + if (number == 1) + { + return _masculineSingular + " milion"; } + return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " milioane"; + } + /// /// Converts a billions three-digit number to text. /// @@ -354,11 +356,11 @@ string MillionsConverter(int number, GrammaticalGender gender) /// The same three-digit number of billions expressed as text. string BillionsConverter(int number, GrammaticalGender gender) { - if (number == 1) - { - return _masculineSingular + " miliard"; - } - - return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " miliarde"; + if (number == 1) + { + return _masculineSingular + " miliard"; } + + return ThreeDigitSetConverter(number, GrammaticalGender.Feminine) + (IsAbove20(number) ? " " + _joinAbove20 : string.Empty) + " miliarde"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianOrdinalNumberConverter.cs b/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianOrdinalNumberConverter.cs index 9fd119b24..476af2e3d 100644 --- a/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianOrdinalNumberConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/Romanian/RomanianOrdinalNumberConverter.cs @@ -7,15 +7,33 @@ class RomanianOrdinalNumberConverter /// readonly Dictionary _ordinalsUnder10 = new() { - {1, "primul|prima"}, - {2, "doilea|doua"}, - {3, "treilea|treia"}, - {4, "patrulea|patra"}, - {5, "cincilea|cincea"}, - {6, "șaselea|șasea"}, - {7, "șaptelea|șaptea"}, - {8, "optulea|opta"}, - {9, "nouălea|noua"}, + { + 1, "primul|prima" + }, + { + 2, "doilea|doua" + }, + { + 3, "treilea|treia" + }, + { + 4, "patrulea|patra" + }, + { + 5, "cincilea|cincea" + }, + { + 6, "șaselea|șasea" + }, + { + 7, "șaptelea|șaptea" + }, + { + 8, "optulea|opta" + }, + { + 9, "nouălea|noua" + }, }; readonly string _femininePrefix = "a"; @@ -25,105 +43,107 @@ class RomanianOrdinalNumberConverter public string Convert(int number, GrammaticalGender gender) { - // it's easier to treat zero as a completely distinct case - if (number == 0) - { - return "zero"; - } + // it's easier to treat zero as a completely distinct case + if (number == 0) + { + return "zero"; + } - if (number == 1) - { - // no prefixes for primul/prima - return GetPartByGender(_ordinalsUnder10[number], gender); - } + if (number == 1) + { + // no prefixes for primul/prima + return GetPartByGender(_ordinalsUnder10[number], gender); + } - if (number <= 9) - { - // units ordinals, 2 to 9, are totally different than the rest: treat them as a distinct case - return string.Format("{0} {1}", - gender == GrammaticalGender.Feminine ? _femininePrefix : _masculinePrefix, - GetPartByGender(_ordinalsUnder10[number], gender) - ); - } + if (number <= 9) + { + // units ordinals, 2 to 9, are totally different than the rest: treat them as a distinct case + return string.Format("{0} {1}", + gender == GrammaticalGender.Feminine ? _femininePrefix : _masculinePrefix, + GetPartByGender(_ordinalsUnder10[number], gender) + ); + } - var coverter = new RomanianCardinalNumberConverter(); - var words = coverter.Convert(number, gender); + var coverter = new RomanianCardinalNumberConverter(); + var words = coverter.Convert(number, gender); - // remove 'de' preposition - words = words.Replace(" de ", " "); + // remove 'de' preposition + words = words.Replace(" de ", " "); - if (gender == GrammaticalGender.Feminine && words.EndsWith("zeci")) - { - words = words.Substring(0, words.Length - 4) + "zece"; - } - else if (gender == GrammaticalGender.Feminine && words.Contains("zeci") && (words.Contains("milioane") || words.Contains("miliarde"))) - { - words = words.Replace("zeci", "zecea"); - } + if (gender == GrammaticalGender.Feminine && words.EndsWith("zeci")) + { + words = words.Substring(0, words.Length - 4) + "zece"; + } + else if (gender == GrammaticalGender.Feminine && words.Contains("zeci") && (words.Contains("milioane") || words.Contains("miliarde"))) + { + words = words.Replace("zeci", "zecea"); + } - if (gender == GrammaticalGender.Feminine && words.StartsWith("un ")) - { - words = words.Substring(2).TrimStart(); - } + if (gender == GrammaticalGender.Feminine && words.StartsWith("un ")) + { + words = words + .Substring(2) + .TrimStart(); + } - if (words.EndsWith("milioane")) + if (words.EndsWith("milioane")) + { + if (gender == GrammaticalGender.Feminine) { - if (gender == GrammaticalGender.Feminine) - { - words = words.Substring(0, words.Length - 8) + "milioana"; - } + words = words.Substring(0, words.Length - 8) + "milioana"; } + } - var customMasculineSuffix = _masculineSuffix; - if (words.EndsWith("milion")) + var customMasculineSuffix = _masculineSuffix; + if (words.EndsWith("milion")) + { + if (gender == GrammaticalGender.Feminine) { - if (gender == GrammaticalGender.Feminine) - { - words = words.Substring(0, words.Length - 6) + "milioana"; - } - else - { - customMasculineSuffix = "u" + _masculineSuffix; - } + words = words.Substring(0, words.Length - 6) + "milioana"; } - else if (words.EndsWith("miliard")) + else { - if (gender == GrammaticalGender.Masculine) - { - customMasculineSuffix = "u" + _masculineSuffix; - } + customMasculineSuffix = "u" + _masculineSuffix; } - - // trim last letter - if (gender == GrammaticalGender.Feminine && !words.EndsWith("zece") && - (words.EndsWith("a") || - words.EndsWith("ă") || - words.EndsWith("e") || - words.EndsWith("i"))) + } + else if (words.EndsWith("miliard")) + { + if (gender == GrammaticalGender.Masculine) { - words = words.Substring(0, words.Length - 1); + customMasculineSuffix = "u" + _masculineSuffix; } + } - return string.Format("{0} {1}{2}", - gender == GrammaticalGender.Feminine ? _femininePrefix : _masculinePrefix, - words, - gender == GrammaticalGender.Feminine ? _feminineSuffix : customMasculineSuffix - ); + // trim last letter + if (gender == GrammaticalGender.Feminine && !words.EndsWith("zece") && + (words.EndsWith("a") || + words.EndsWith("ă") || + words.EndsWith("e") || + words.EndsWith("i"))) + { + words = words.Substring(0, words.Length - 1); } + return string.Format("{0} {1}{2}", + gender == GrammaticalGender.Feminine ? _femininePrefix : _masculinePrefix, + words, + gender == GrammaticalGender.Feminine ? _feminineSuffix : customMasculineSuffix + ); + } + static string GetPartByGender(string multiGenderPart, GrammaticalGender gender) { - if (multiGenderPart.Contains("|")) + if (multiGenderPart.Contains("|")) + { + var parts = multiGenderPart.Split('|'); + if (gender == GrammaticalGender.Feminine) { - var parts = multiGenderPart.Split('|'); - if (gender == GrammaticalGender.Feminine) - { - return parts[1]; - } - - return parts[0]; + return parts[1]; } - return multiGenderPart; + return parts[0]; } + + return multiGenderPart; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/RomanianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/RomanianNumberToWordsConverter.cs index b36539005..9fdefff67 100644 --- a/src/Humanizer/Localisation/NumberToWords/RomanianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/RomanianNumberToWordsConverter.cs @@ -4,17 +4,18 @@ class RomanianNumberToWordsConverter : GenderedNumberToWordsConverter { public override string Convert(long number, GrammaticalGender gender, bool addAnd = true) { - if (number is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var converter = new RomanianCardinalNumberConverter(); - return converter.Convert((int)number, gender); + if (number is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); } + var converter = new RomanianCardinalNumberConverter(); + return converter.Convert((int) number, gender); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - var converter = new RomanianOrdinalNumberConverter(); - return converter.Convert(number, gender); - } + var converter = new RomanianOrdinalNumberConverter(); + return converter.Convert(number, gender); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/RussianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/RussianNumberToWordsConverter.cs index 11641c4b8..a2c995695 100644 --- a/src/Humanizer/Localisation/NumberToWords/RussianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/RussianNumberToWordsConverter.cs @@ -12,252 +12,252 @@ class RussianNumberToWordsConverter : GenderedNumberToWordsConverter public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input == 0) - { - return "ноль"; - } + if (input == 0) + { + return "ноль"; + } - var parts = new List(); + var parts = new List(); - if (input < 0) - { - parts.Add("минус"); - } + if (input < 0) + { + parts.Add("минус"); + } - CollectParts(parts, ref input, 1000000000000000000, GrammaticalGender.Masculine, "квинтиллион", "квинтиллиона", "квинтиллионов"); - CollectParts(parts, ref input, 1000000000000000, GrammaticalGender.Masculine, "квадриллион", "квадриллиона", "квадриллионов"); - CollectParts(parts, ref input, 1000000000000, GrammaticalGender.Masculine, "триллион", "триллиона", "триллионов"); - CollectParts(parts, ref input, 1000000000, GrammaticalGender.Masculine, "миллиард", "миллиарда", "миллиардов"); - CollectParts(parts, ref input, 1000000, GrammaticalGender.Masculine, "миллион", "миллиона", "миллионов"); - CollectParts(parts, ref input, 1000, GrammaticalGender.Feminine, "тысяча", "тысячи", "тысяч"); + CollectParts(parts, ref input, 1000000000000000000, GrammaticalGender.Masculine, "квинтиллион", "квинтиллиона", "квинтиллионов"); + CollectParts(parts, ref input, 1000000000000000, GrammaticalGender.Masculine, "квадриллион", "квадриллиона", "квадриллионов"); + CollectParts(parts, ref input, 1000000000000, GrammaticalGender.Masculine, "триллион", "триллиона", "триллионов"); + CollectParts(parts, ref input, 1000000000, GrammaticalGender.Masculine, "миллиард", "миллиарда", "миллиардов"); + CollectParts(parts, ref input, 1000000, GrammaticalGender.Masculine, "миллион", "миллиона", "миллионов"); + CollectParts(parts, ref input, 1000, GrammaticalGender.Feminine, "тысяча", "тысячи", "тысяч"); - if (input > 0) - { - CollectPartsUnderOneThousand(parts, input, gender); - } - - return string.Join(" ", parts); + if (input > 0) + { + CollectPartsUnderOneThousand(parts, input, gender); } + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int input, GrammaticalGender gender) { - if (input == 0) - { - return "нулев" + GetEndingForGender(gender, input); - } + if (input == 0) + { + return "нулев" + GetEndingForGender(gender, input); + } - var parts = new List(); + var parts = new List(); - if (input < 0) - { - parts.Add("минус"); - input = -input; - } + if (input < 0) + { + parts.Add("минус"); + input = -input; + } - var number = (long)input; - CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "миллиардн" + GetEndingForGender(gender, number), "миллиард", "миллиарда", "миллиардов"); - CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "миллионн" + GetEndingForGender(gender, number), "миллион", "миллиона", "миллионов"); - CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Feminine, "тысячн" + GetEndingForGender(gender, number), "тысяча", "тысячи", "тысяч"); + var number = (long) input; + CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "миллиардн" + GetEndingForGender(gender, number), "миллиард", "миллиарда", "миллиардов"); + CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "миллионн" + GetEndingForGender(gender, number), "миллион", "миллиона", "миллионов"); + CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Feminine, "тысячн" + GetEndingForGender(gender, number), "тысяча", "тысячи", "тысяч"); - if (number >= 100) + if (number >= 100) + { + var ending = GetEndingForGender(gender, number); + var hundreds = number / 100; + number %= 100; + if (number == 0) { - var ending = GetEndingForGender(gender, number); - var hundreds = number / 100; - number %= 100; - if (number == 0) - { - parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот" + ending); - } - else - { - parts.Add(HundredsMap[hundreds]); - } + parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот" + ending); } - - if (number >= 20) + else { - var ending = GetEndingForGender(gender, number); - var tens = number / 10; - number %= 10; - if (number == 0) - { - parts.Add(TensOrdinal[tens] + ending); - } - else - { - parts.Add(TensMap[tens]); - } + parts.Add(HundredsMap[hundreds]); } + } - if (number > 0) + if (number >= 20) + { + var ending = GetEndingForGender(gender, number); + var tens = number / 10; + number %= 10; + if (number == 0) { - parts.Add(UnitsOrdinal[number] + GetEndingForGender(gender, number)); + parts.Add(TensOrdinal[tens] + ending); } + else + { + parts.Add(TensMap[tens]); + } + } - return string.Join(" ", parts); + if (number > 0) + { + parts.Add(UnitsOrdinal[number] + GetEndingForGender(gender, number)); } + return string.Join(" ", parts); + } + static void CollectPartsUnderOneThousand(ICollection parts, long number, GrammaticalGender gender) { - if (number >= 100) + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + parts.Add(HundredsMap[hundreds]); + } + + if (number >= 20) + { + var tens = number / 10; + parts.Add(TensMap[tens]); + number %= 10; + } + + if (number > 0) + { + if (number == 1 && gender == GrammaticalGender.Feminine) { - var hundreds = number / 100; - number %= 100; - parts.Add(HundredsMap[hundreds]); + parts.Add("одна"); } - - if (number >= 20) + else if (number == 1 && gender == GrammaticalGender.Neuter) { - var tens = number / 10; - parts.Add(TensMap[tens]); - number %= 10; + parts.Add("одно"); } - - if (number > 0) + else if (number == 2 && gender == GrammaticalGender.Feminine) { - if (number == 1 && gender == GrammaticalGender.Feminine) - { - parts.Add("одна"); - } - else if (number == 1 && gender == GrammaticalGender.Neuter) - { - parts.Add("одно"); - } - else if (number == 2 && gender == GrammaticalGender.Feminine) - { - parts.Add("две"); - } - else if (number < 20) - { - parts.Add(UnitsMap[number]); - } + parts.Add("две"); + } + else if (number < 20) + { + parts.Add(UnitsMap[number]); } } + } static string GetPrefix(long number) { - var parts = new List(); + var parts = new List(); - if (number >= 100) + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + if (hundreds != 1) { - var hundreds = number / 100; - number %= 100; - if (hundreds != 1) - { - parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот"); - } - else - { - parts.Add("сто"); - } + parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот"); } - - if (number >= 20) + else { - var tens = number / 10; - number %= 10; - parts.Add(TensOrdinalPrefixes[tens]); + parts.Add("сто"); } + } - if (number > 0) - { - parts.Add(number == 1 ? "одно" : UnitsOrdinalPrefixes[number]); - } + if (number >= 20) + { + var tens = number / 10; + number %= 10; + parts.Add(TensOrdinalPrefixes[tens]); + } - return string.Concat(parts); + if (number > 0) + { + parts.Add(number == 1 ? "одно" : UnitsOrdinalPrefixes[number]); } + return string.Concat(parts); + } + static void CollectParts(ICollection parts, ref long number, long divisor, GrammaticalGender gender, params string[] forms) { - var result = Math.Abs(number / divisor); - if (result == 0) - { - return; - } + var result = Math.Abs(number / divisor); + if (result == 0) + { + return; + } - number = Math.Abs(number % divisor); + number = Math.Abs(number % divisor); - CollectPartsUnderOneThousand(parts, result, gender); - parts.Add(ChooseOneForGrammaticalNumber(result, forms)); - } + CollectPartsUnderOneThousand(parts, result, gender); + parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + } static void CollectOrdinalParts(ICollection parts, ref long number, int divisor, GrammaticalGender gender, string prefixedForm, params string[] forms) { - if (number < divisor) - { - return; - } + if (number < divisor) + { + return; + } - var result = number / divisor; - number %= divisor; - if (number == 0) + var result = number / divisor; + number %= divisor; + if (number == 0) + { + if (result == 1) { - if (result == 1) - { - parts.Add(prefixedForm); - } - else - { - parts.Add(GetPrefix(result) + prefixedForm); - } + parts.Add(prefixedForm); } else { - CollectPartsUnderOneThousand(parts, result, gender); - parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + parts.Add(GetPrefix(result) + prefixedForm); } } + else + { + CollectPartsUnderOneThousand(parts, result, gender); + parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + } + } static int GetIndex(RussianGrammaticalNumber number) { - if (number == RussianGrammaticalNumber.Singular) - { - return 0; - } - - if (number == RussianGrammaticalNumber.Paucal) - { - return 1; - } + if (number == RussianGrammaticalNumber.Singular) + { + return 0; + } - return 2; + if (number == RussianGrammaticalNumber.Paucal) + { + return 1; } + return 2; + } + static string ChooseOneForGrammaticalNumber(long number, string[] forms) => forms[GetIndex(RussianGrammaticalNumberDetector.Detect(number))]; static string GetEndingForGender(GrammaticalGender gender, long number) { - switch (gender) - { - case GrammaticalGender.Masculine: - if (number is 0 or 2 or 6 or 7 or 8 or 40) - { - return "ой"; - } - - if (number == 3) - { - return "ий"; - } - - return "ый"; - case GrammaticalGender.Feminine: - if (number == 3) - { - return "ья"; - } - - return "ая"; - case GrammaticalGender.Neuter: - if (number == 3) - { - return "ье"; - } - - return "ое"; - default: - throw new ArgumentOutOfRangeException(nameof(gender)); - } + switch (gender) + { + case GrammaticalGender.Masculine: + if (number is 0 or 2 or 6 or 7 or 8 or 40) + { + return "ой"; + } + + if (number == 3) + { + return "ий"; + } + + return "ый"; + case GrammaticalGender.Feminine: + if (number == 3) + { + return "ья"; + } + + return "ая"; + case GrammaticalGender.Neuter: + if (number == 3) + { + return "ье"; + } + + return "ое"; + default: + throw new ArgumentOutOfRangeException(nameof(gender)); } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/SerbianCyrlNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SerbianCyrlNumberToWordsConverter.cs index c9d324195..bf4be1661 100644 --- a/src/Humanizer/Localisation/NumberToWords/SerbianCyrlNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SerbianCyrlNumberToWordsConverter.cs @@ -8,114 +8,115 @@ class SerbianCyrlNumberToWordsConverter(CultureInfo? culture) : public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - if (number == 0) - { - return "нула"; - } + var number = (int) input; - if (number < 0) - { - return $"- {Convert(-number)}"; - } + if (number == 0) + { + return "нула"; + } - var parts = new List(); - var billions = number / 1000000000; + if (number < 0) + { + return $"- {Convert(-number)}"; + } - if (billions > 0) - { - parts.Add(Part("милијарда", "две милијарде", "{0} милијарде", "{0} милијарда", billions)); - number %= 1000000000; + var parts = new List(); + var billions = number / 1000000000; - if (number > 0) - { - parts.Add(" "); - } + if (billions > 0) + { + parts.Add(Part("милијарда", "две милијарде", "{0} милијарде", "{0} милијарда", billions)); + number %= 1000000000; + + if (number > 0) + { + parts.Add(" "); } + } - var millions = number / 1000000; + var millions = number / 1000000; - if (millions > 0) - { - parts.Add(Part("милион", "два милиона", "{0} милиона", "{0} милиона", millions)); - number %= 1000000; + if (millions > 0) + { + parts.Add(Part("милион", "два милиона", "{0} милиона", "{0} милиона", millions)); + number %= 1000000; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - var thousands = number / 1000; + var thousands = number / 1000; - if (thousands > 0) - { - parts.Add(Part("хиљаду", "две хиљаде", "{0} хиљаде", "{0} хиљада", thousands)); - number %= 1000; + if (thousands > 0) + { + parts.Add(Part("хиљаду", "две хиљаде", "{0} хиљаде", "{0} хиљада", thousands)); + number %= 1000; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - var hundreds = number / 100; + var hundreds = number / 100; - if (hundreds > 0) - { - parts.Add(Part("сто", "двесто", "{0}сто", "{0}сто", hundreds)); - number %= 100; + if (hundreds > 0) + { + parts.Add(Part("сто", "двесто", "{0}сто", "{0}сто", hundreds)); + number %= 100; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - if (number > 0) + if (number > 0) + { + if (number < 20) { - if (number < 20) - { - parts.Add(UnitsMap[number]); - } - else - { - parts.Add(TensMap[number / 10]); + parts.Add(UnitsMap[number]); + } + else + { + parts.Add(TensMap[number / 10]); - var units = number % 10; + var units = number % 10; - if (units > 0) - { - parts.Add($" {UnitsMap[units]}"); - } + if (units > 0) + { + parts.Add($" {UnitsMap[units]}"); } } - - return string.Concat(parts); } + return string.Concat(parts); + } + public override string ConvertToOrdinal(int number) => //TODO: In progress number.ToString(culture); string Part(string singular, string dual, string trialQuadral, string plural, int number) { - switch (number) - { - case 1: - return singular; - case 2: - return dual; - case 3: - case 4: - return string.Format(trialQuadral, Convert(number)); - default: - return string.Format(plural, Convert(number)); - } + switch (number) + { + case 1: + return singular; + case 2: + return dual; + case 3: + case 4: + return string.Format(trialQuadral, Convert(number)); + default: + return string.Format(plural, Convert(number)); } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/SerbianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SerbianNumberToWordsConverter.cs index f13f971e8..3ccafd1f1 100644 --- a/src/Humanizer/Localisation/NumberToWords/SerbianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SerbianNumberToWordsConverter.cs @@ -8,112 +8,113 @@ class SerbianNumberToWordsConverter(CultureInfo? culture) : public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - if (number == 0) - { - return "nula"; - } + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - if (number < 0) - { - return $"- {Convert(-number)}"; - } + var number = (int) input; + if (number == 0) + { + return "nula"; + } - var parts = new List(); - var billions = number / 1000000000; + if (number < 0) + { + return $"- {Convert(-number)}"; + } - if (billions > 0) - { - parts.Add(Part("milijarda", "dve milijarde", "{0} milijarde", "{0} milijarda", billions)); - number %= 1000000000; + var parts = new List(); + var billions = number / 1000000000; - if (number > 0) - { - parts.Add(" "); - } + if (billions > 0) + { + parts.Add(Part("milijarda", "dve milijarde", "{0} milijarde", "{0} milijarda", billions)); + number %= 1000000000; + + if (number > 0) + { + parts.Add(" "); } + } - var millions = number / 1000000; + var millions = number / 1000000; - if (millions > 0) - { - parts.Add(Part("milion", "dva miliona", "{0} miliona", "{0} miliona", millions)); - number %= 1000000; + if (millions > 0) + { + parts.Add(Part("milion", "dva miliona", "{0} miliona", "{0} miliona", millions)); + number %= 1000000; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - var thousands = number / 1000; + var thousands = number / 1000; - if (thousands > 0) - { - parts.Add(Part("hiljadu", "dve hiljade", "{0} hiljade", "{0} hiljada", thousands)); - number %= 1000; + if (thousands > 0) + { + parts.Add(Part("hiljadu", "dve hiljade", "{0} hiljade", "{0} hiljada", thousands)); + number %= 1000; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - var hundreds = number / 100; + var hundreds = number / 100; - if (hundreds > 0) - { - parts.Add(Part("sto", "dvesto", "{0}sto", "{0}sto", hundreds)); - number %= 100; + if (hundreds > 0) + { + parts.Add(Part("sto", "dvesto", "{0}sto", "{0}sto", hundreds)); + number %= 100; - if (number > 0) - { - parts.Add(" "); - } + if (number > 0) + { + parts.Add(" "); } + } - if (number > 0) + if (number > 0) + { + if (number < 20) { - if (number < 20) - { - parts.Add(UnitsMap[number]); - } - else - { - parts.Add(TensMap[number / 10]); - var units = number % 10; + parts.Add(UnitsMap[number]); + } + else + { + parts.Add(TensMap[number / 10]); + var units = number % 10; - if (units > 0) - { - parts.Add($" {UnitsMap[units]}"); - } + if (units > 0) + { + parts.Add($" {UnitsMap[units]}"); } } - - return string.Concat(parts); } + return string.Concat(parts); + } + public override string ConvertToOrdinal(int number) => //TODO: In progress number.ToString(culture); string Part(string singular, string dual, string trialQuadral, string plural, int number) { - switch (number) - { - case 1: - return singular; - case 2: - return dual; - case 3: - case 4: - return string.Format(trialQuadral, Convert(number)); - default: - return string.Format(plural, Convert(number)); - } + switch (number) + { + case 1: + return singular; + case 2: + return dual; + case 3: + case 4: + return string.Format(trialQuadral, Convert(number)); + default: + return string.Format(plural, Convert(number)); } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/SlovenianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SlovenianNumberToWordsConverter.cs index 493761473..59f07ab90 100644 --- a/src/Humanizer/Localisation/NumberToWords/SlovenianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SlovenianNumberToWordsConverter.cs @@ -8,115 +8,116 @@ class SlovenianNumberToWordsConverter(CultureInfo? culture) : public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - if (number == 0) - { - return "nič"; - } + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } - if (number < 0) - { - return $"minus {Convert(-number)}"; - } + var number = (int) input; + if (number == 0) + { + return "nič"; + } - var parts = new List(); + if (number < 0) + { + return $"minus {Convert(-number)}"; + } - var billions = number / 1000000000; - if (billions > 0) + var parts = new List(); + + var billions = number / 1000000000; + if (billions > 0) + { + parts.Add(Part("milijarda", "dve milijardi", "{0} milijarde", "{0} milijard", billions)); + number %= 1000000000; + if (number > 0) { - parts.Add(Part("milijarda", "dve milijardi", "{0} milijarde", "{0} milijard", billions)); - number %= 1000000000; - if (number > 0) - { - parts.Add(" "); - } + parts.Add(" "); } + } - var millions = number / 1000000; - if (millions > 0) + var millions = number / 1000000; + if (millions > 0) + { + parts.Add(Part("milijon", "dva milijona", "{0} milijone", "{0} milijonov", millions)); + number %= 1000000; + if (number > 0) { - parts.Add(Part("milijon", "dva milijona", "{0} milijone", "{0} milijonov", millions)); - number %= 1000000; - if (number > 0) - { - parts.Add(" "); - } + parts.Add(" "); } + } - var thousands = number / 1000; - if (thousands > 0) + var thousands = number / 1000; + if (thousands > 0) + { + parts.Add(Part("tisoč", "dva tisoč", "{0} tisoč", "{0} tisoč", thousands)); + number %= 1000; + if (number > 0) { - parts.Add(Part("tisoč", "dva tisoč", "{0} tisoč", "{0} tisoč", thousands)); - number %= 1000; - if (number > 0) - { - parts.Add(" "); - } + parts.Add(" "); } + } - var hundreds = number / 100; - if (hundreds > 0) + var hundreds = number / 100; + if (hundreds > 0) + { + parts.Add(Part("sto", "dvesto", "{0}sto", "{0}sto", hundreds)); + number %= 100; + if (number > 0) { - parts.Add(Part("sto", "dvesto", "{0}sto", "{0}sto", hundreds)); - number %= 100; - if (number > 0) - { - parts.Add(" "); - } + parts.Add(" "); } + } - if (number > 0) + if (number > 0) + { + if (number < 20) { - if (number < 20) + if (number > 1) { - if (number > 1) - { - parts.Add(UnitsMap[number]); - } - else - { - parts.Add("ena"); - } + parts.Add(UnitsMap[number]); } else { - var units = number % 10; - if (units > 0) - { - parts.Add($"{UnitsMap[units]}in"); - } - - parts.Add(TensMap[number / 10]); + parts.Add("ena"); } } + else + { + var units = number % 10; + if (units > 0) + { + parts.Add($"{UnitsMap[units]}in"); + } - return string.Concat(parts); + parts.Add(TensMap[number / 10]); + } } + return string.Concat(parts); + } + public override string ConvertToOrdinal(int number) => number.ToString(culture); string Part(string singular, string dual, string trialQuadral, string plural, int number) { - if (number == 1) - { - return singular; - } - - if (number == 2) - { - return dual; - } + if (number == 1) + { + return singular; + } - if (number is 3 or 4) - { - return string.Format(trialQuadral, Convert(number)); - } + if (number == 2) + { + return dual; + } - return string.Format(plural, Convert(number)); + if (number is 3 or 4) + { + return string.Format(trialQuadral, Convert(number)); } + + return string.Format(plural, Convert(number)); + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs index 003402c6c..0f2573a81 100644 --- a/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs @@ -16,7 +16,7 @@ class SpanishNumberToWordsConverter : GenderedNumberToWordsConverter static readonly string[] OrdinalsRootMap = [ - "" , "primer", "segund", "tercer", "cuart", "quint", "sext", + "", "primer", "segund", "tercer", "cuart", "quint", "sext", "séptim", "octav", "noven" ]; @@ -55,103 +55,102 @@ public override string Convert(long input, GrammaticalGender gender, bool addAnd public override string Convert(long number, WordForm wordForm, GrammaticalGender gender, bool addAnd = true) { - List wordBuilder = []; + List wordBuilder = []; - if (number == 0) - { - return "cero"; - } + if (number == 0) + { + return "cero"; + } - if (number == long.MinValue) - { - return - "menos nueve trillones doscientos veintitrés mil trescientos setenta y dos billones treinta y seis mil " + - "ochocientos cincuenta y cuatro millones setecientos setenta y cinco mil ochocientos ocho"; - } + if (number == long.MinValue) + { + return + "menos nueve trillones doscientos veintitrés mil trescientos setenta y dos billones treinta y seis mil " + + "ochocientos cincuenta y cuatro millones setecientos setenta y cinco mil ochocientos ocho"; + } - if (number < 0) - { - return $"menos {Convert(-number)}"; - } + if (number < 0) + { + return $"menos {Convert(-number)}"; + } - wordBuilder.Add(ConvertGreaterThanMillion(number, out var remainder)); - wordBuilder.Add(ConvertThousands(remainder, out remainder, gender)); - wordBuilder.Add(ConvertHundreds(remainder, out remainder, gender)); - wordBuilder.Add(ConvertUnits(remainder, gender, wordForm)); + wordBuilder.Add(ConvertGreaterThanMillion(number, out var remainder)); + wordBuilder.Add(ConvertThousands(remainder, out remainder, gender)); + wordBuilder.Add(ConvertHundreds(remainder, out remainder, gender)); + wordBuilder.Add(ConvertUnits(remainder, gender, wordForm)); - return BuildWord(wordBuilder); - } + return BuildWord(wordBuilder); + } public override string ConvertToOrdinal(int number, GrammaticalGender gender) => ConvertToOrdinal(number, gender, WordForm.Normal); public override string ConvertToOrdinal(int number, GrammaticalGender gender, WordForm wordForm) { - List wordBuilder = []; + List wordBuilder = []; - if (number is 0 or int.MinValue) - { - return "cero"; - } + if (number is 0 or int.MinValue) + { + return "cero"; + } - if (number < 0) - { - return ConvertToOrdinal(Math.Abs(number), gender); - } + if (number < 0) + { + return ConvertToOrdinal(Math.Abs(number), gender); + } - if (IsRoundBillion(number)) - { - return ConvertRoundBillionths(number, gender); - } + if (IsRoundBillion(number)) + { + return ConvertRoundBillionths(number, gender); + } - if (IsRoundMillion(number)) - { - return ConvertToOrdinal(number / 1000, gender).Replace("milésim", "millonésim"); - } + if (IsRoundMillion(number)) + { + return ConvertToOrdinal(number / 1000, gender) + .Replace("milésim", "millonésim"); + } - wordBuilder.Add(ConvertTensAndHunderdsOfThousandths(number, out var remainder, gender)); - wordBuilder.Add(ConvertThousandths(remainder, out remainder, gender)); - wordBuilder.Add(ConvertHundredths(remainder, out remainder, gender)); - wordBuilder.Add(ConvertTenths(remainder, out remainder, gender)); - wordBuilder.Add(ConvertOrdinalUnits(remainder, gender, wordForm)); + wordBuilder.Add(ConvertTensAndHunderdsOfThousandths(number, out var remainder, gender)); + wordBuilder.Add(ConvertThousandths(remainder, out remainder, gender)); + wordBuilder.Add(ConvertHundredths(remainder, out remainder, gender)); + wordBuilder.Add(ConvertTenths(remainder, out remainder, gender)); + wordBuilder.Add(ConvertOrdinalUnits(remainder, gender, wordForm)); - return BuildWord(wordBuilder); - } + return BuildWord(wordBuilder); + } public override string ConvertToTuple(int number) { - number = Math.Abs(number); + number = Math.Abs(number); - if (number < TupleMap.Length) - return TupleMap[number]; + if (number < TupleMap.Length) + return TupleMap[number]; - return Convert(number) + " veces"; - } + return Convert(number) + " veces"; + } static string BuildWord(IReadOnlyList wordParts) { - var parts = wordParts.ToList(); - parts.RemoveAll(string.IsNullOrEmpty); - return string.Join(" ", parts); - } + var parts = wordParts.ToList(); + parts.RemoveAll(string.IsNullOrEmpty); + return string.Join(" ", parts); + } static string ConvertHundreds(in long inputNumber, out long remainder, GrammaticalGender gender) { - var wordPart = string.Empty; - remainder = inputNumber; + var wordPart = string.Empty; + remainder = inputNumber; - if (inputNumber / 100 > 0) - { - wordPart = inputNumber == 100 ? - "cien" : - GetGenderedHundredsMap(gender)[(int)(inputNumber / 100)]; - - remainder = inputNumber % 100; - } + if (inputNumber / 100 > 0) + { + wordPart = inputNumber == 100 ? "cien" : GetGenderedHundredsMap(gender)[(int) (inputNumber / 100)]; - return wordPart; + remainder = inputNumber % 100; } + return wordPart; + } + static string ConvertHundredths(in int number, out int remainder, GrammaticalGender gender) => ConvertMappedOrdinalNumber(number, 100, HundredthsRootMap, out remainder, gender); @@ -162,42 +161,42 @@ static string ConvertMappedOrdinalNumber( out int remainder, GrammaticalGender gender) { - var wordPart = string.Empty; - remainder = number; - - if (number / divisor > 0) - { - var genderedEnding = gender == GrammaticalGender.Feminine ? "a" : "o"; - wordPart = map[number / divisor] + genderedEnding; - remainder = number % divisor; - } - - return wordPart; + var wordPart = string.Empty; + remainder = number; + + if (number / divisor > 0) + { + var genderedEnding = gender == GrammaticalGender.Feminine ? "a" : "o"; + wordPart = map[number / divisor] + genderedEnding; + remainder = number % divisor; } + return wordPart; + } + static string ConvertOrdinalUnits(in int number, GrammaticalGender gender, WordForm wordForm) { - if (number is <= 0 or >= 10) - { - return string.Empty; - } + if (number is <= 0 or >= 10) + { + return string.Empty; + } - switch (gender) - { - case GrammaticalGender.Masculine: - case GrammaticalGender.Neuter: - if (HasOrdinalAbbreviation(number, wordForm)) - { - return OrdinalsRootMap[number]; - } - - return OrdinalsRootMap[number] + 'o'; - case GrammaticalGender.Feminine: - return OrdinalsRootMap[number] + "a"; - default: - throw new ArgumentOutOfRangeException(nameof(gender), gender, null); - } + switch (gender) + { + case GrammaticalGender.Masculine: + case GrammaticalGender.Neuter: + if (HasOrdinalAbbreviation(number, wordForm)) + { + return OrdinalsRootMap[number]; + } + + return OrdinalsRootMap[number] + 'o'; + case GrammaticalGender.Feminine: + return OrdinalsRootMap[number] + "a"; + default: + throw new ArgumentOutOfRangeException(nameof(gender), gender, null); } + } static string ConvertTenths(in int number, out int remainder, GrammaticalGender gender) => ConvertMappedOrdinalNumber(number, 10, TenthsRootMap, out remainder, gender); @@ -207,69 +206,69 @@ static string ConvertThousandths(in int number, out int remainder, GrammaticalGe static string ConvertUnits(long inputNumber, GrammaticalGender gender, WordForm wordForm = WordForm.Normal) { - if (inputNumber <= 0) - { - return string.Empty; - } - - UnitsMap[1] = GetGenderedOne(gender, wordForm); - UnitsMap[21] = GetGenderedTwentyOne(gender, wordForm); + if (inputNumber <= 0) + { + return string.Empty; + } - if (inputNumber < 30) - { - return UnitsMap[inputNumber]; - } + UnitsMap[1] = GetGenderedOne(gender, wordForm); + UnitsMap[21] = GetGenderedTwentyOne(gender, wordForm); - var wordPart = TensMap[inputNumber / 10]; - if (inputNumber % 10 <= 0) - { - return wordPart; - } + if (inputNumber < 30) + { + return UnitsMap[inputNumber]; + } - return wordPart + $" y {UnitsMap[inputNumber % 10]}"; + var wordPart = TensMap[inputNumber / 10]; + if (inputNumber % 10 <= 0) + { + return wordPart; } + return wordPart + $" y {UnitsMap[inputNumber % 10]}"; + } + static IReadOnlyList GetGenderedHundredsMap(GrammaticalGender gender) { - var genderedEnding = gender == GrammaticalGender.Feminine ? "as" : "os"; - var map = new List(); - map.AddRange(HundredsRootMap.Take(2)); + var genderedEnding = gender == GrammaticalGender.Feminine ? "as" : "os"; + var map = new List(); + map.AddRange(HundredsRootMap.Take(2)); - for (var i = 2; i < HundredsRootMap.Length; i++) - { - map.Add(HundredsRootMap[i] + genderedEnding); - } - - return map; + for (var i = 2; i < HundredsRootMap.Length; i++) + { + map.Add(HundredsRootMap[i] + genderedEnding); } + return map; + } + static string GetGenderedOne(GrammaticalGender gender, WordForm wordForm = WordForm.Normal) { - switch (gender) - { - case GrammaticalGender.Masculine: - case GrammaticalGender.Neuter: - return wordForm == WordForm.Abbreviation ? "un" : "uno"; - case GrammaticalGender.Feminine: - return "una"; - default: - throw new ArgumentOutOfRangeException(nameof(gender), gender, null); - } + switch (gender) + { + case GrammaticalGender.Masculine: + case GrammaticalGender.Neuter: + return wordForm == WordForm.Abbreviation ? "un" : "uno"; + case GrammaticalGender.Feminine: + return "una"; + default: + throw new ArgumentOutOfRangeException(nameof(gender), gender, null); } + } static string GetGenderedTwentyOne(GrammaticalGender gender, WordForm wordForm = WordForm.Normal) { - switch (gender) - { - case GrammaticalGender.Masculine: - case GrammaticalGender.Neuter: - return wordForm == WordForm.Abbreviation ? "veintiún" : "veintiuno"; - case GrammaticalGender.Feminine: - return "veintiuna"; - default: - throw new ArgumentOutOfRangeException(nameof(gender), gender, null); - } + switch (gender) + { + case GrammaticalGender.Masculine: + case GrammaticalGender.Neuter: + return wordForm == WordForm.Abbreviation ? "veintiún" : "veintiuno"; + case GrammaticalGender.Feminine: + return "veintiuna"; + default: + throw new ArgumentOutOfRangeException(nameof(gender), gender, null); } + } static bool HasOrdinalAbbreviation(int number, WordForm wordForm) => number is 1 or 3 && wordForm == WordForm.Abbreviation; @@ -283,106 +282,108 @@ static bool IsRoundMillion(int number) => static string PluralizeGreaterThanMillion(string singularWord) => singularWord.TrimEnd('ó', 'n') + "ones"; - static Dictionary numbersAndWordsDict = new() + static Dictionary numbersAndWordsDict = new() { - { "trillón", 1_000_000_000_000_000_000 }, - { "billón", 1_000_000_000_000 }, - { "millón", 1_000_000 } + { + "trillón", 1_000_000_000_000_000_000 + }, + { + "billón", 1_000_000_000_000 + }, + { + "millón", 1_000_000 + } }; string ConvertGreaterThanMillion(in long inputNumber, out long remainder) { - List wordBuilder = []; + List wordBuilder = []; - remainder = inputNumber; - foreach (var numberAndWord in numbersAndWordsDict) + remainder = inputNumber; + foreach (var numberAndWord in numbersAndWordsDict) + { + if (remainder / numberAndWord.Value > 0) { - if (remainder / numberAndWord.Value > 0) + if (remainder / numberAndWord.Value == 1) { - if (remainder / numberAndWord.Value == 1) - { - wordBuilder.Add($"un {numberAndWord.Key}"); - } - else - { - wordBuilder.Add(remainder / numberAndWord.Value % 10 == 1 ? - $"{Convert(remainder / numberAndWord.Value, WordForm.Abbreviation, GrammaticalGender.Masculine)} {PluralizeGreaterThanMillion(numberAndWord.Key)}" : - $"{Convert(remainder / numberAndWord.Value)} {PluralizeGreaterThanMillion(numberAndWord.Key)}"); - } - - remainder %= numberAndWord.Value; + wordBuilder.Add($"un {numberAndWord.Key}"); + } + else + { + wordBuilder.Add(remainder / numberAndWord.Value % 10 == 1 ? $"{Convert(remainder / numberAndWord.Value, WordForm.Abbreviation, GrammaticalGender.Masculine)} {PluralizeGreaterThanMillion(numberAndWord.Key)}" : $"{Convert(remainder / numberAndWord.Value)} {PluralizeGreaterThanMillion(numberAndWord.Key)}"); } - } - return BuildWord(wordBuilder); + remainder %= numberAndWord.Value; + } } + return BuildWord(wordBuilder); + } + string ConvertRoundBillionths(int number, GrammaticalGender gender) { - var cardinalPart = Convert(number / 1_000_000, WordForm.Abbreviation, gender); - var sep = number == 1_000_000_000 ? "" : " "; - var ordinalPart = ConvertToOrdinal(1_000_000, gender); - return cardinalPart + sep + ordinalPart; - } + var cardinalPart = Convert(number / 1_000_000, WordForm.Abbreviation, gender); + var sep = number == 1_000_000_000 ? "" : " "; + var ordinalPart = ConvertToOrdinal(1_000_000, gender); + return cardinalPart + sep + ordinalPart; + } string ConvertTensAndHunderdsOfThousandths(in int number, out int remainder, GrammaticalGender gender) { - var wordPart = string.Empty; - remainder = number; + var wordPart = string.Empty; + remainder = number; - if (number / 10000 > 0) - { - wordPart = Convert(number / 1000 * 1000, gender); + if (number / 10000 > 0) + { + wordPart = Convert(number / 1000 * 1000, gender); - if (number < 30000 || IsRoundNumber(number)) + if (number < 30000 || IsRoundNumber(number)) + { + if (number == 21000) { - if (number == 21000) - { - wordPart = wordPart - .Replace("a", "") - .Replace("ú", "u"); - } - - wordPart = wordPart.Remove(wordPart.LastIndexOf(' '), 1); + wordPart = wordPart + .Replace("a", "") + .Replace("ú", "u"); } - wordPart += "ésim" + (gender == GrammaticalGender.Masculine ? "o" : "a"); - - remainder = number % 1000; + wordPart = wordPart.Remove(wordPart.LastIndexOf(' '), 1); } - return wordPart; + wordPart += "ésim" + (gender == GrammaticalGender.Masculine ? "o" : "a"); - static bool IsRoundNumber(int number) => - (number % 10000 == 0 && number < 100000) - || (number % 100000 == 0 && number < 1000000) - || (number % 1000000 == 0 && number < 10000000) - || (number % 10000000 == 0 && number < 100000000) - || (number % 100000000 == 0 && number < 1000000000) - || (number % 1000000000 == 0 && number < int.MaxValue); + remainder = number % 1000; } + return wordPart; + + static bool IsRoundNumber(int number) => + (number % 10000 == 0 && number < 100000) + || (number % 100000 == 0 && number < 1000000) + || (number % 1000000 == 0 && number < 10000000) + || (number % 10000000 == 0 && number < 100000000) + || (number % 100000000 == 0 && number < 1000000000) + || (number % 1000000000 == 0 && number < int.MaxValue); + } + string ConvertThousands(in long inputNumber, out long remainder, GrammaticalGender gender) { - var wordPart = string.Empty; - remainder = inputNumber; + var wordPart = string.Empty; + remainder = inputNumber; - if (inputNumber / 1000 > 0) + if (inputNumber / 1000 > 0) + { + if (inputNumber / 1000 == 1) { - if (inputNumber / 1000 == 1) - { - wordPart = "mil"; - } - else - { - wordPart = gender == GrammaticalGender.Feminine ? - $"{Convert(inputNumber / 1000, GrammaticalGender.Feminine)} mil" : - $"{Convert(inputNumber / 1000, WordForm.Abbreviation, gender)} mil"; - } - - remainder = inputNumber % 1000; + wordPart = "mil"; + } + else + { + wordPart = gender == GrammaticalGender.Feminine ? $"{Convert(inputNumber / 1000, GrammaticalGender.Feminine)} mil" : $"{Convert(inputNumber / 1000, WordForm.Abbreviation, gender)} mil"; } - return wordPart; + remainder = inputNumber % 1000; } + + return wordPart; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/SwedishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SwedishNumberToWordsConverter.cs index e92f71c52..0b337940c 100644 --- a/src/Humanizer/Localisation/NumberToWords/SwedishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SwedishNumberToWordsConverter.cs @@ -17,94 +17,126 @@ class Fact static readonly Fact[] Hunderds = [ - new(){Value = 1000000000, Name = "miljard", Prefix = " ", Postfix = " ", DisplayOneUnit = true, Gender = GrammaticalGender.Masculine}, - new(){Value = 1000000, Name = "miljon", Prefix = " ", Postfix = " ", DisplayOneUnit = true, Gender = GrammaticalGender.Masculine}, - new(){Value = 1000, Name = "tusen", Prefix = " ", Postfix = " ", DisplayOneUnit = true}, - new(){Value = 100, Name = "hundra", Prefix = "", Postfix = "", DisplayOneUnit = false} + new() + { + Value = 1000000000, + Name = "miljard", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true, + Gender = GrammaticalGender.Masculine + }, + new() + { + Value = 1000000, + Name = "miljon", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true, + Gender = GrammaticalGender.Masculine + }, + new() + { + Value = 1000, + Name = "tusen", + Prefix = " ", + Postfix = " ", + DisplayOneUnit = true + }, + new() + { + Value = 100, + Name = "hundra", + Prefix = "", + Postfix = "", + DisplayOneUnit = false + } ]; public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input is > int.MaxValue or < int.MinValue) + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); + } + + var number = (int) input; + + if (number == 0) + { + return UnitsMap[0]; + } + + if (number < 0) + { + return $"minus {Convert(-number, gender)}"; + } + + var word = ""; + + foreach (var m in Hunderds) + { + var divided = number / m.Value; + + if (divided <= 0) { - throw new NotImplementedException(); + continue; } - var number = (int)input; - if (number == 0) + if (divided == 1 && !m.DisplayOneUnit) { - return UnitsMap[0]; + word += m.Name; } - - if (number < 0) + else { - return $"minus {Convert(-number, gender)}"; + word += Convert(divided, m.Gender) + m.Prefix + m.Name; } - var word = ""; - - foreach (var m in Hunderds) + // pluralise 1M+ + if (divided > 1 && input >= 1_000_000) { - var divided = number / m.Value; + word += "er"; + } - if (divided <= 0) - { - continue; - } + number %= m.Value; + if (number > 0) + { + word += m.Postfix; + } + } - if (divided == 1 && !m.DisplayOneUnit) + if (number > 0) + { + if (number < 20) + { + if (number == 1 && gender == GrammaticalGender.Masculine) { - word += m.Name; + word += "en"; } else { - word += Convert(divided, m.Gender) + m.Prefix + m.Name; - } - - // pluralise 1M+ - if (divided > 1 && input >= 1_000_000) - { - word += "er"; - } - - number %= m.Value; - if (number > 0) - { - word += m.Postfix; + word += UnitsMap[number]; } } - - if (number > 0) + else { - if (number < 20) + var tens = TensMap[number / 10]; + var unit = number % 10; + if (unit > 0) { - if (number == 1 && gender == GrammaticalGender.Masculine) - { - word += "en"; - } - else - { - word += UnitsMap[number]; - } + var units = UnitsMap[unit]; + word += tens + units; } else { - var tens = TensMap[number / 10]; - var unit = number % 10; - if (unit > 0) - { - var units = UnitsMap[unit]; - word += tens + units; - } - else - { - word += tens; - } + word += tens; } } - - return word; } + + return word; + } + public override string Convert(long input) => Convert(input, GrammaticalGender.Neuter); @@ -135,79 +167,79 @@ public override string Convert(long input) => public override string ConvertToOrdinal(int number) { - var word = ""; + var word = ""; + + if (number < 0) + { + return $"minus {ConvertToOrdinal(-number)}"; + } + + if (number <= 20) + { + return ordinalNumbers[number]; + } - if (number < 0) + // 21+ + if (number <= 100) + { + var tens = TensMap[number / 10]; + var unit = number % 10; + if (unit > 0) { - return $"minus {ConvertToOrdinal(-number)}"; + word += tens + ConvertToOrdinal(unit); } - - if (number <= 20) + else if (number == 100) { - return ordinalNumbers[number]; + word += tens + "de"; } - - // 21+ - if (number <= 100) + else { - var tens = TensMap[number / 10]; - var unit = number % 10; - if (unit > 0) - { - word += tens + ConvertToOrdinal(unit); - } - else if (number == 100) - { - word += tens + "de"; - } - else - { - word += tens + "nde"; - } - - return word; + word += tens + "nde"; } - // 101+ - foreach (var m in Hunderds) - { - var divided = number / m.Value; + return word; + } - if (divided <= 0) - { - continue; - } + // 101+ + foreach (var m in Hunderds) + { + var divided = number / m.Value; - if (divided == 1 && !m.DisplayOneUnit) - { - word += m.Name; - } - else - { - word += Convert(divided, m.Gender) + m.Prefix + m.Name; - } + if (divided <= 0) + { + continue; + } - // suffix -de/-te - if (number % m.Value == 0) - { - switch (number) - { - case 1_000_000: - word += "te"; - break; - default: - word += "de"; - break; - } - } + if (divided == 1 && !m.DisplayOneUnit) + { + word += m.Name; + } + else + { + word += Convert(divided, m.Gender) + m.Prefix + m.Name; + } - number %= m.Value; - if (number > 0) + // suffix -de/-te + if (number % m.Value == 0) + { + switch (number) { - word += ConvertToOrdinal(number); + case 1_000_000: + word += "te"; + break; + default: + word += "de"; + break; } } - return word; + number %= m.Value; + if (number > 0) + { + word += ConvertToOrdinal(number); + } } + + return word; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/TamilNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/TamilNumberToWordsConverter.cs index e1fe65b02..6d1e735a8 100644 --- a/src/Humanizer/Localisation/NumberToWords/TamilNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/TamilNumberToWordsConverter.cs @@ -11,14 +11,30 @@ class TamilNumberToWordsConverter : GenderlessNumberToWordsConverter static readonly Dictionary OrdinalExceptions = new() { - {1, "முதலாவது"}, - {2, "இரண்டாவது"}, - {3, "மூன்றாவது"}, - {4, "நான்காவது"}, - {5, "ஐந்தாவது"}, - {8, "எட்டாவது"}, - {9, "ஒன்பதாவது"}, - {12, "பனிரெண்டாவது"}, + { + 1, "முதலாவது" + }, + { + 2, "இரண்டாவது" + }, + { + 3, "மூன்றாவது" + }, + { + 4, "நான்காவது" + }, + { + 5, "ஐந்தாவது" + }, + { + 8, "எட்டாவது" + }, + { + 9, "ஒன்பதாவது" + }, + { + 12, "பனிரெண்டாவது" + }, }; public override string Convert(long number) => @@ -29,242 +45,248 @@ public override string ConvertToOrdinal(int number) => string ConvertImpl(long number, bool isOrdinal) { - if (number == 0) - return GetUnitValue(0, isOrdinal); + if (number == 0) + return GetUnitValue(0, isOrdinal); - if (number < 0) - return $"கழித்தல் {Convert(-number)}"; + if (number < 0) + return $"கழித்தல் {Convert(-number)}"; - var parts = new List(); + var parts = new List(); - if (number / 1000000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000000)} quintillion"); - number %= 1000000000000000000; - } - - if (number / 1000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000)} quadrillion"); - number %= 1000000000000000; - } + if (number / 1000000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000000)} quintillion"); + number %= 1000000000000000000; + } - //if ((number / 1000000000000) > 0) - //{ - // parts.Add(string.Format("{0} trillion", Convert(number / 1000000000000))); - // number %= 1000000000000; - //} + if (number / 1000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000)} quadrillion"); + number %= 1000000000000000; + } - //if ((number / 1000000000) > 0) - //{ - // parts.Add(string.Format("{0} பில்லியன்", Convert(number / 1000000000))); - // number %= 1000000000; - //} + //if ((number / 1000000000000) > 0) + //{ + // parts.Add(string.Format("{0} trillion", Convert(number / 1000000000000))); + // number %= 1000000000000; + //} - //if ((number / 1000000) > 0) - //{ - // parts.Add(string.Format("{0} மில்லியன்", Convert(number / 1000000))); - // number %= 1000000; - //} + //if ((number / 1000000000) > 0) + //{ + // parts.Add(string.Format("{0} பில்லியன்", Convert(number / 1000000000))); + // number %= 1000000000; + //} - if (number / 10000000 > 0) parts.Add(GetCroresValue(ref number)); + //if ((number / 1000000) > 0) + //{ + // parts.Add(string.Format("{0} மில்லியன்", Convert(number / 1000000))); + // number %= 1000000; + //} - if (number / 100000 > 0) parts.Add(GetLakhsValue(ref number, isOrdinal)); + if (number / 10000000 > 0) parts.Add(GetCroresValue(ref number)); - if (number / 1000 > 0) parts.Add(GetThousandsValue(ref number)); + if (number / 100000 > 0) parts.Add(GetLakhsValue(ref number, isOrdinal)); - if (number / 100 > 0) parts.Add(GetHundredsValue(ref number)); + if (number / 1000 > 0) parts.Add(GetThousandsValue(ref number)); - if (number > 0) - parts.Add(GetTensValue(number, isOrdinal)); - else if (isOrdinal) - parts[^1] += "வது"; + if (number / 100 > 0) parts.Add(GetHundredsValue(ref number)); - var toWords = string.Join(" ", parts); + if (number > 0) + parts.Add(GetTensValue(number, isOrdinal)); + else if (isOrdinal) + parts[^1] += "வது"; - if (isOrdinal) - { - toWords = RemoveOnePrefix(toWords); - } + var toWords = string.Join(" ", parts); - return toWords; + if (isOrdinal) + { + toWords = RemoveOnePrefix(toWords); } + return toWords; + } + static string GetUnitValue(long number, bool isOrdinal) { - if (isOrdinal) + if (isOrdinal) + { + if (ExceptionNumbersToWords(number, out var exceptionString)) { - if (ExceptionNumbersToWords(number, out var exceptionString)) - { - return exceptionString; - } - return UnitsMap[number] + "வது"; + return exceptionString; } - return UnitsMap[number]; + return UnitsMap[number] + "வது"; } + return UnitsMap[number]; + } + static string GetTensValue(long number, bool isOrdinal, bool isThousand = false) { - var local_word = ""; - if (number < 20) - local_word = GetUnitValue(number, isOrdinal); - else if (number is >= 20 and <= 99) + var local_word = ""; + if (number < 20) + local_word = GetUnitValue(number, isOrdinal); + else if (number is >= 20 and <= 99) + { + var lastPart = TensMap[number / 10]; + var quot = number / 10; + if (number % 10 > 0) + { + if (quot == 9) + lastPart += "ற்றி "; + else if (quot is 7 or 8 or 4) + lastPart += "த்தி "; + else + lastPart += "த்து "; + + if (!isThousand) lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; + } + else if (number % 10 == 0) { - var lastPart = TensMap[number / 10]; - var quot = number / 10; - if (number % 10 > 0) + if (isThousand) { if (quot == 9) - lastPart += "ற்றி "; - else if (quot is 7 or 8 or 4) - lastPart += "த்தி "; + lastPart += "றா"; else - lastPart += "த்து "; - - if (!isThousand) lastPart += $"{GetUnitValue(number % 10, isOrdinal)}"; + lastPart += "தா"; } - else if (number % 10 == 0) + else { - if (isThousand) - { - if (quot == 9) - lastPart += "றா"; - else - lastPart += "தா"; - } + if (quot == 9) + lastPart += "று"; else - { - if (quot == 9) - lastPart += "று"; - else - lastPart += "து"; - } + lastPart += "து"; } - else if (isOrdinal) - lastPart = lastPart.TrimEnd('y') + "ieth"; - - local_word = lastPart; } - return local_word; + else if (isOrdinal) + lastPart = lastPart.TrimEnd('y') + "ieth"; + + local_word = lastPart; } + + return local_word; + } + static string GetLakhsValue(ref long number, bool isOrdinal) { - var num_above_10 = number / 100000; - var local_word = ""; - if (num_above_10 >= 20) - { - local_word = GetTensValue(num_above_10, false, false); - local_word += " " + LakhsMap[0]; - } - else if (num_above_10 == 1) - local_word = "ஒரு " + LakhsMap[0]; - else local_word += GetTensValue(number / 100000, isOrdinal) + " " + LakhsMap[0]; + var num_above_10 = number / 100000; + var local_word = ""; + if (num_above_10 >= 20) + { + local_word = GetTensValue(num_above_10, false, false); + local_word += " " + LakhsMap[0]; + } + else if (num_above_10 == 1) + local_word = "ஒரு " + LakhsMap[0]; + else local_word += GetTensValue(number / 100000, isOrdinal) + " " + LakhsMap[0]; - if (number % 1000000 == 0 || number % 100000 == 0) - local_word += "ம்"; - else - local_word += "த்து"; + if (number % 1000000 == 0 || number % 100000 == 0) + local_word += "ம்"; + else + local_word += "த்து"; + + number %= 100000; + return local_word; + } - number %= 100000; - return local_word; - } static string GetCroresValue(ref long number) { - var local_word = ""; - var num_above_10 = number / 10000000; - var str_crore = "கோடி"; + var local_word = ""; + var num_above_10 = number / 10000000; + var str_crore = "கோடி"; + + if (num_above_10 is > 99999 and <= 9999999) + { + local_word = GetLakhsValue(ref num_above_10, false); + local_word += " "; + } - if (num_above_10 is > 99999 and <= 9999999) - { - local_word = GetLakhsValue(ref num_above_10, false); - local_word += " "; - } + if (num_above_10 is > 999 and <= 99999) + { + local_word += GetThousandsValue(ref num_above_10); + local_word += " "; + } - if (num_above_10 is > 999 and <= 99999) - { - local_word += GetThousandsValue(ref num_above_10); - local_word += " "; - } - if (num_above_10 is > 99 and <= 999) - { - local_word += GetHundredsValue(ref num_above_10); - local_word += " "; - } + if (num_above_10 is > 99 and <= 999) + { + local_word += GetHundredsValue(ref num_above_10); + local_word += " "; + } - if (num_above_10 >= 20) - { - local_word += GetTensValue(num_above_10, false, false); - local_word += " "; - } - else if (num_above_10 == 1) - local_word = "ஒரு "; - else if (num_above_10 > 0) local_word += GetTensValue(num_above_10, false) + " "; + if (num_above_10 >= 20) + { + local_word += GetTensValue(num_above_10, false, false); + local_word += " "; + } + else if (num_above_10 == 1) + local_word = "ஒரு "; + else if (num_above_10 > 0) local_word += GetTensValue(num_above_10, false) + " "; - local_word = local_word.TrimEnd() + " " + str_crore; - if (number % 10000000 == 0 || number % 100000000 == 0) - local_word += ""; - else - local_word += "யே"; + local_word = local_word.TrimEnd() + " " + str_crore; + if (number % 10000000 == 0 || number % 100000000 == 0) + local_word += ""; + else + local_word += "யே"; - number %= 10000000; - return local_word; - } + number %= 10000000; + return local_word; + } static string GetThousandsValue(ref long number) { - var num_above_10 = number / 1000; - var local_word = ""; - if (num_above_10 >= 20) - { - local_word = GetTensValue(num_above_10, false, true); + var num_above_10 = number / 1000; + var local_word = ""; + if (num_above_10 >= 20) + { + local_word = GetTensValue(num_above_10, false, true); - if (num_above_10 % 10 == 1) - local_word += "ஓரா"; - else if (num_above_10 % 10 > 1) - local_word += ThousandsMap[num_above_10 % 10 - 1]; + if (num_above_10 % 10 == 1) + local_word += "ஓரா"; + else if (num_above_10 % 10 > 1) + local_word += ThousandsMap[num_above_10 % 10 - 1]; - } - else - local_word += ThousandsMap[number / 1000 - 1]; + } + else + local_word += ThousandsMap[number / 1000 - 1]; - number %= 1000; + number %= 1000; - if (number > 0) - local_word += "யிரத்து"; - else - local_word += "யிரம்"; + if (number > 0) + local_word += "யிரத்து"; + else + local_word += "யிரம்"; + + return local_word; + } - return local_word; - } static string GetHundredsValue(ref long number) { - var local_word = HundredsMap[number / 100 - 1]; - if (number / 100 == 9) - { - if (number % 100 == 0) - local_word += "ம்"; - else - local_word += "த்து"; - } - else if (number % 100 >= 1) - local_word += "ற்று"; + var local_word = HundredsMap[number / 100 - 1]; + if (number / 100 == 9) + { + if (number % 100 == 0) + local_word += "ம்"; else - local_word += "று"; + local_word += "த்து"; + } + else if (number % 100 >= 1) + local_word += "ற்று"; + else + local_word += "று"; - number %= 100; + number %= 100; - return local_word; - } + return local_word; + } static string RemoveOnePrefix(string toWords) { - // one hundred => hundredth - if (toWords.StartsWith("one", StringComparison.Ordinal)) - toWords = toWords.Remove(0, 4); + // one hundred => hundredth + if (toWords.StartsWith("one", StringComparison.Ordinal)) + toWords = toWords.Remove(0, 4); - return toWords; - } + return toWords; + } static bool ExceptionNumbersToWords(long number, [NotNullWhen(true)] out string? words) => OrdinalExceptions.TryGetValue(number, out words); diff --git a/src/Humanizer/Localisation/NumberToWords/ThaiNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/ThaiNumberToWordsConverter.cs index 45d3d77b3..1b83d6766 100644 --- a/src/Humanizer/Localisation/NumberToWords/ThaiNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/ThaiNumberToWordsConverter.cs @@ -4,72 +4,109 @@ class ThaiNumberToWordsConverter : GenderlessNumberToWordsConverter { public override string Convert(long numbermoney) { - var Textreturn = ""; - if (numbermoney == 0) - { - return "ศูนย์"; - } + var Textreturn = ""; + if (numbermoney == 0) + { + return "ศูนย์"; + } - if (numbermoney < 0) - { - Textreturn = "ลบ"; - numbermoney = -numbermoney; - } + if (numbermoney < 0) + { + Textreturn = "ลบ"; + numbermoney = -numbermoney; + } - if (numbermoney / 1000000 > 0) - { - Textreturn += Convert(numbermoney / 1000000) + "ล้าน"; - numbermoney %= 1000000; - } - if (numbermoney / 100000 > 0) + if (numbermoney / 1000000 > 0) + { + Textreturn += Convert(numbermoney / 1000000) + "ล้าน"; + numbermoney %= 1000000; + } + + if (numbermoney / 100000 > 0) + { + Textreturn += Convert(numbermoney / 100000) + "แสน"; + numbermoney %= 100000; + } + + if (numbermoney / 10000 > 0) + { + Textreturn += Convert(numbermoney / 10000) + "หมื่น"; + numbermoney %= 10000; + } + + if (numbermoney / 1000 > 0) + { + Textreturn += Convert(numbermoney / 1000) + "พัน"; + numbermoney %= 1000; + } + + if (numbermoney / 100 > 0) + { + Textreturn += Convert(numbermoney / 100) + "ร้อย"; + numbermoney %= 100; + } + + if (numbermoney > 0) + { + if (Textreturn != "") { - Textreturn += Convert(numbermoney / 100000) + "แสน"; - numbermoney %= 100000; + Textreturn += ""; } - if (numbermoney / 10000 > 0) + + var unitsMap = new[] { - Textreturn += Convert(numbermoney / 10000) + "หมื่น"; - numbermoney %= 10000; - } - if (numbermoney / 1000 > 0) + "ศูนย์", + "หนึ่ง", + "สอง", + "สาม", + "สี่", + "ห้า", + "หก", + "เจ็ด", + "เเปด", + "เก้า", + "สิบ", + "สิบเอ็ด", + "สิบสอง", + "สิบสาม", + "สิบสี่", + "สิบห้า", + "สิบหก", + "สิบเจ็ด", + "สิบเเปด", + "สิบเก้า" + }; + var tensMap = new[] { - Textreturn += Convert(numbermoney / 1000) + "พัน"; - numbermoney %= 1000; - } + "ศูนย์", + "สิบ", + "ยี่สิบ", + "สามสิบ", + "สี่สิบ", + "ห้าสิบ", + "หกสิบ", + "เจ็ดสิบ", + "แปดสิบ", + "เก้าสิบ" + }; - if (numbermoney / 100 > 0) + if (numbermoney < 20) { - Textreturn += Convert(numbermoney / 100) + "ร้อย"; - numbermoney %= 100; + Textreturn += unitsMap[numbermoney]; } - - if (numbermoney > 0) + else { - if (Textreturn != "") + Textreturn += tensMap[numbermoney / 10]; + if (numbermoney % 10 > 0) { - Textreturn += ""; - } - - var unitsMap = new[] { "ศูนย์", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "เเปด", "เก้า", "สิบ", "สิบเอ็ด", "สิบสอง", "สิบสาม", "สิบสี่", "สิบห้า", "สิบหก", "สิบเจ็ด", "สิบเเปด", "สิบเก้า" }; - var tensMap = new[] { "ศูนย์", "สิบ", "ยี่สิบ", "สามสิบ", "สี่สิบ", "ห้าสิบ", "หกสิบ", "เจ็ดสิบ", "แปดสิบ", "เก้าสิบ" }; - - if (numbermoney < 20) - { - Textreturn += unitsMap[numbermoney]; - } - else - { - Textreturn += tensMap[numbermoney / 10]; - if (numbermoney % 10 > 0) - { - Textreturn += "" + unitsMap[numbermoney % 10]; - } + Textreturn += "" + unitsMap[numbermoney % 10]; } } - - return Textreturn; } + return Textreturn; + } + public override string ConvertToOrdinal(int number) => Convert(number); } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/TurkishNumberToWordConverter.cs b/src/Humanizer/Localisation/NumberToWords/TurkishNumberToWordConverter.cs index 842b5f386..dfe8d3793 100644 --- a/src/Humanizer/Localisation/NumberToWords/TurkishNumberToWordConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/TurkishNumberToWordConverter.cs @@ -8,152 +8,184 @@ class TurkishNumberToWordConverter : static readonly Dictionary OrdinalSuffix = new() { - {'ı', "ıncı"}, - {'i', "inci"}, - {'u', "uncu"}, - {'ü', "üncü"}, - {'o', "uncu"}, - {'ö', "üncü"}, - {'e', "inci"}, - {'a', "ıncı"}, + { + 'ı', "ıncı" + }, + { + 'i', "inci" + }, + { + 'u', "uncu" + }, + { + 'ü', "üncü" + }, + { + 'o', "uncu" + }, + { + 'ö', "üncü" + }, + { + 'e', "inci" + }, + { + 'a', "ıncı" + }, }; static readonly Dictionary TupleSuffix = new() { - {'ı', "lı"}, - {'i', "li"}, - {'u', "lu"}, - {'ü', "lü"}, - {'o', "lu"}, - {'ö', "lü"}, - {'e', "li"}, - {'a', "lı"}, + { + 'ı', "lı" + }, + { + 'i', "li" + }, + { + 'u', "lu" + }, + { + 'ü', "lü" + }, + { + 'o', "lu" + }, + { + 'ö', "lü" + }, + { + 'e', "li" + }, + { + 'a', "lı" + }, }; public override string Convert(long input) { - var number = input; - if (number == 0) - { - return UnitsMap[0]; - } + var number = input; + if (number == 0) + { + return UnitsMap[0]; + } - if (number < 0) - { - return $"eksi {Convert(-number)}"; - } + if (number < 0) + { + return $"eksi {Convert(-number)}"; + } - var parts = new List(); + var parts = new List(); - if (number / 1000000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000000)} kentilyon"); - number %= 1000000000000000000; - } + if (number / 1000000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000000)} kentilyon"); + number %= 1000000000000000000; + } - if (number / 1000000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000000)} katrilyon"); - number %= 1000000000000000; - } + if (number / 1000000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000000)} katrilyon"); + number %= 1000000000000000; + } - if (number / 1000000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000000)} trilyon"); - number %= 1000000000000; - } + if (number / 1000000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000000)} trilyon"); + number %= 1000000000000; + } - if (number / 1000000000 > 0) - { - parts.Add($"{Convert(number / 1000000000)} milyar"); - number %= 1000000000; - } + if (number / 1000000000 > 0) + { + parts.Add($"{Convert(number / 1000000000)} milyar"); + number %= 1000000000; + } - if (number / 1000000 > 0) - { - parts.Add($"{Convert(number / 1000000)} milyon"); - number %= 1000000; - } + if (number / 1000000 > 0) + { + parts.Add($"{Convert(number / 1000000)} milyon"); + number %= 1000000; + } - var thousand = number / 1000; - if (thousand > 0) - { - parts.Add($"{(thousand > 1 ? Convert(thousand) : "")} bin".Trim()); - number %= 1000; - } + var thousand = number / 1000; + if (thousand > 0) + { + parts.Add($"{(thousand > 1 ? Convert(thousand) : "")} bin".Trim()); + number %= 1000; + } - var hundred = number / 100; - if (hundred > 0) - { - parts.Add($"{(hundred > 1 ? Convert(hundred) : "")} yüz".Trim()); - number %= 100; - } + var hundred = number / 100; + if (hundred > 0) + { + parts.Add($"{(hundred > 1 ? Convert(hundred) : "")} yüz".Trim()); + number %= 100; + } - if (number / 10 > 0) - { - parts.Add(TensMap[number / 10]); - number %= 10; - } + if (number / 10 > 0) + { + parts.Add(TensMap[number / 10]); + number %= 10; + } - if (number > 0) - { - parts.Add(UnitsMap[number]); - } + if (number > 0) + { + parts.Add(UnitsMap[number]); + } - var toWords = string.Join(" ", parts); + var toWords = string.Join(" ", parts); - return toWords; - } + return toWords; + } public override string ConvertToOrdinal(int number) { - var word = Convert(number); - var wordSuffix = string.Empty; - var suffixFoundOnLastVowel = false; - - for (var i = word.Length - 1; i >= 0; i--) - { - if (OrdinalSuffix.TryGetValue(word[i], out wordSuffix)) - { - suffixFoundOnLastVowel = i == word.Length - 1; - break; - } - } + var word = Convert(number); + var wordSuffix = string.Empty; + var suffixFoundOnLastVowel = false; - if (word[^1] == 't') + for (var i = word.Length - 1; i >= 0; i--) + { + if (OrdinalSuffix.TryGetValue(word[i], out wordSuffix)) { - word = word.Substring(0, word.Length - 1) + 'd'; + suffixFoundOnLastVowel = i == word.Length - 1; + break; } + } - if (suffixFoundOnLastVowel) - { - word = word.Substring(0, word.Length - 1); - } + if (word[^1] == 't') + { + word = word.Substring(0, word.Length - 1) + 'd'; + } - return $"{word}{wordSuffix}"; + if (suffixFoundOnLastVowel) + { + word = word.Substring(0, word.Length - 1); } + return $"{word}{wordSuffix}"; + } + public override string ConvertToTuple(int number) { - switch (number) - { - case 1: - return "tek"; - case 2: - return "çift"; - default: - var word = Convert(number); - var wordSuffix = string.Empty; - - for (var i = word.Length - 1; i >= 0; i--) + switch (number) + { + case 1: + return "tek"; + case 2: + return "çift"; + default: + var word = Convert(number); + var wordSuffix = string.Empty; + + for (var i = word.Length - 1; i >= 0; i--) + { + if (TupleSuffix.TryGetValue(word[i], out wordSuffix)) { - if (TupleSuffix.TryGetValue(word[i], out wordSuffix)) - { - break; - } + break; } + } - return $"{word}{wordSuffix}"; - } + return $"{word}{wordSuffix}"; } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/UkrainianNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/UkrainianNumberToWordsConverter.cs index e69e00fe2..e4da5c907 100644 --- a/src/Humanizer/Localisation/NumberToWords/UkrainianNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/UkrainianNumberToWordsConverter.cs @@ -12,246 +12,246 @@ class UkrainianNumberToWordsConverter : GenderedNumberToWordsConverter public override string Convert(long input, GrammaticalGender gender, bool addAnd = true) { - if (input == 0) - { - return "нуль"; - } + if (input == 0) + { + return "нуль"; + } - var parts = new List(); + var parts = new List(); - if (input < 0) - { - parts.Add("мінус"); - } + if (input < 0) + { + parts.Add("мінус"); + } - CollectParts(parts, ref input, 1000000000000000000, GrammaticalGender.Masculine, "квінтильйон", "квінтильйона", "квінтильйонів"); - CollectParts(parts, ref input, 1000000000000000, GrammaticalGender.Masculine, "квадрильйон", "квадрильйона", "квадрильйонів"); - CollectParts(parts, ref input, 1000000000000, GrammaticalGender.Masculine, "трильйон", "трильйона", "трильйонів"); - CollectParts(parts, ref input, 1000000000, GrammaticalGender.Masculine, "мільярд", "мільярда", "мільярдів"); - CollectParts(parts, ref input, 1000000, GrammaticalGender.Masculine, "мільйон", "мільйона", "мільйонів"); - CollectParts(parts, ref input, 1000, GrammaticalGender.Feminine, "тисяча", "тисячі", "тисяч"); + CollectParts(parts, ref input, 1000000000000000000, GrammaticalGender.Masculine, "квінтильйон", "квінтильйона", "квінтильйонів"); + CollectParts(parts, ref input, 1000000000000000, GrammaticalGender.Masculine, "квадрильйон", "квадрильйона", "квадрильйонів"); + CollectParts(parts, ref input, 1000000000000, GrammaticalGender.Masculine, "трильйон", "трильйона", "трильйонів"); + CollectParts(parts, ref input, 1000000000, GrammaticalGender.Masculine, "мільярд", "мільярда", "мільярдів"); + CollectParts(parts, ref input, 1000000, GrammaticalGender.Masculine, "мільйон", "мільйона", "мільйонів"); + CollectParts(parts, ref input, 1000, GrammaticalGender.Feminine, "тисяча", "тисячі", "тисяч"); - if (input > 0) - { - CollectPartsUnderOneThousand(parts, input, gender); - } - - return string.Join(" ", parts); + if (input > 0) + { + CollectPartsUnderOneThousand(parts, input, gender); } + return string.Join(" ", parts); + } + public override string ConvertToOrdinal(int number, GrammaticalGender gender) { - if (number == 0) - { - return "нульов" + GetEndingForGender(gender, number); - } + if (number == 0) + { + return "нульов" + GetEndingForGender(gender, number); + } - var parts = new List(); + var parts = new List(); - if (number < 0) - { - parts.Add("мінус"); - number = -number; - } + if (number < 0) + { + parts.Add("мінус"); + number = -number; + } - CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "мільярдн" + GetEndingForGender(gender, number), "мільярд", "мільярда", "мільярдів"); - CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "мільйонн" + GetEndingForGender(gender, number), "мільйон", "мільйона", "мільйонів"); - CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Feminine, "тисячн" + GetEndingForGender(gender, number), "тисяча", "тисячі", "тисяч"); + CollectOrdinalParts(parts, ref number, 1000000000, GrammaticalGender.Masculine, "мільярдн" + GetEndingForGender(gender, number), "мільярд", "мільярда", "мільярдів"); + CollectOrdinalParts(parts, ref number, 1000000, GrammaticalGender.Masculine, "мільйонн" + GetEndingForGender(gender, number), "мільйон", "мільйона", "мільйонів"); + CollectOrdinalParts(parts, ref number, 1000, GrammaticalGender.Feminine, "тисячн" + GetEndingForGender(gender, number), "тисяча", "тисячі", "тисяч"); - if (number >= 100) + if (number >= 100) + { + var ending = GetEndingForGender(gender, number); + var hundreds = number / 100; + number %= 100; + if (number == 0) { - var ending = GetEndingForGender(gender, number); - var hundreds = number / 100; - number %= 100; - if (number == 0) - { - parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот" + ending); - } - else - { - parts.Add(HundredsMap[hundreds]); - } + parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот" + ending); } - - if (number >= 20) + else { - var ending = GetEndingForGender(gender, number); - var tens = number / 10; - number %= 10; - if (number == 0) - { - parts.Add(TensOrdinal[tens] + ending); - } - else - { - parts.Add(TensMap[tens]); - } + parts.Add(HundredsMap[hundreds]); } + } - if (number > 0) + if (number >= 20) + { + var ending = GetEndingForGender(gender, number); + var tens = number / 10; + number %= 10; + if (number == 0) { - parts.Add(UnitsOrdinal[number] + GetEndingForGender(gender, number)); + parts.Add(TensOrdinal[tens] + ending); } + else + { + parts.Add(TensMap[tens]); + } + } - return string.Join(" ", parts); + if (number > 0) + { + parts.Add(UnitsOrdinal[number] + GetEndingForGender(gender, number)); } + return string.Join(" ", parts); + } + static void CollectPartsUnderOneThousand(ICollection parts, long number, GrammaticalGender gender) { - if (number >= 100) + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + parts.Add(HundredsMap[hundreds]); + } + + if (number >= 20) + { + var tens = number / 10; + parts.Add(TensMap[tens]); + number %= 10; + } + + if (number > 0) + { + if (number == 1 && gender == GrammaticalGender.Feminine) { - var hundreds = number / 100; - number %= 100; - parts.Add(HundredsMap[hundreds]); + parts.Add("одна"); } - - if (number >= 20) + else if (number == 1 && gender == GrammaticalGender.Neuter) { - var tens = number / 10; - parts.Add(TensMap[tens]); - number %= 10; + parts.Add("одне"); } - - if (number > 0) + else if (number == 2 && gender == GrammaticalGender.Feminine) { - if (number == 1 && gender == GrammaticalGender.Feminine) - { - parts.Add("одна"); - } - else if (number == 1 && gender == GrammaticalGender.Neuter) - { - parts.Add("одне"); - } - else if (number == 2 && gender == GrammaticalGender.Feminine) - { - parts.Add("дві"); - } - else if (number < 20) - { - parts.Add(UnitsMap[number]); - } + parts.Add("дві"); + } + else if (number < 20) + { + parts.Add(UnitsMap[number]); } } + } static string GetPrefix(int number) { - var parts = new List(); + var parts = new List(); - if (number >= 100) + if (number >= 100) + { + var hundreds = number / 100; + number %= 100; + if (hundreds != 1) { - var hundreds = number / 100; - number %= 100; - if (hundreds != 1) - { - parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот"); - } - else - { - parts.Add("сто"); - } + parts.Add(UnitsOrdinalPrefixes[hundreds] + "сот"); } - - if (number >= 20) + else { - var tens = number / 10; - number %= 10; - parts.Add(TensOrdinalPrefixes[tens]); + parts.Add("сто"); } + } - if (number > 0) - { - parts.Add(number == 1 ? "одно" : UnitsOrdinalPrefixes[number]); - } + if (number >= 20) + { + var tens = number / 10; + number %= 10; + parts.Add(TensOrdinalPrefixes[tens]); + } - return string.Concat(parts); + if (number > 0) + { + parts.Add(number == 1 ? "одно" : UnitsOrdinalPrefixes[number]); } + return string.Concat(parts); + } + static void CollectParts(ICollection parts, ref long number, long divisor, GrammaticalGender gender, params string[] forms) { - var result = Math.Abs(number / divisor); - if (result == 0) - { - return; - } + var result = Math.Abs(number / divisor); + if (result == 0) + { + return; + } - number = Math.Abs(number % divisor); + number = Math.Abs(number % divisor); - CollectPartsUnderOneThousand(parts, result, gender); - parts.Add(ChooseOneForGrammaticalNumber(result, forms)); - } + CollectPartsUnderOneThousand(parts, result, gender); + parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + } static void CollectOrdinalParts(ICollection parts, ref int number, int divisor, GrammaticalGender gender, string prefixedForm, params string[] forms) { - if (number < divisor) - { - return; - } + if (number < divisor) + { + return; + } - var result = number / divisor; - number %= divisor; - if (number == 0) + var result = number / divisor; + number %= divisor; + if (number == 0) + { + if (result == 1) { - if (result == 1) - { - parts.Add(prefixedForm); - } - else - { - parts.Add(GetPrefix(result) + prefixedForm); - } + parts.Add(prefixedForm); } else { - CollectPartsUnderOneThousand(parts, result, gender); - parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + parts.Add(GetPrefix(result) + prefixedForm); } } + else + { + CollectPartsUnderOneThousand(parts, result, gender); + parts.Add(ChooseOneForGrammaticalNumber(result, forms)); + } + } static int GetIndex(RussianGrammaticalNumber number) { - if (number == RussianGrammaticalNumber.Singular) - { - return 0; - } - - if (number == RussianGrammaticalNumber.Paucal) - { - return 1; - } + if (number == RussianGrammaticalNumber.Singular) + { + return 0; + } - return 2; + if (number == RussianGrammaticalNumber.Paucal) + { + return 1; } + return 2; + } + static string ChooseOneForGrammaticalNumber(long number, string[] forms) => forms[GetIndex(RussianGrammaticalNumberDetector.Detect(number))]; static string GetEndingForGender(GrammaticalGender gender, int number) { - switch (gender) - { - case GrammaticalGender.Masculine: - if (number == 3) - { - return "ій"; - } - - return "ий"; - case GrammaticalGender.Feminine: - if (number == 3) - { - return "я"; - } - - return "а"; - case GrammaticalGender.Neuter: - if (number == 3) - { - return "є"; - } - - return "е"; - default: - throw new ArgumentOutOfRangeException(nameof(gender)); - } + switch (gender) + { + case GrammaticalGender.Masculine: + if (number == 3) + { + return "ій"; + } + + return "ий"; + case GrammaticalGender.Feminine: + if (number == 3) + { + return "я"; + } + + return "а"; + case GrammaticalGender.Neuter: + if (number == 3) + { + return "є"; + } + + return "е"; + default: + throw new ArgumentOutOfRangeException(nameof(gender)); } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/UzbekCyrlNumberToWordConverter.cs b/src/Humanizer/Localisation/NumberToWords/UzbekCyrlNumberToWordConverter.cs index 0efd49b7e..fec9b6f0f 100644 --- a/src/Humanizer/Localisation/NumberToWords/UzbekCyrlNumberToWordConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/UzbekCyrlNumberToWordConverter.cs @@ -9,88 +9,91 @@ class UzbekCyrlNumberToWordConverter : GenderlessNumberToWordsConverter public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - if (number < 0) - { - return $"минус {Convert(-number, true)}"; - } - - return Convert(number, true); + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); } + var number = (int) input; + if (number < 0) + { + return $"минус {Convert(-number, true)}"; + } + + return Convert(number, true); + } + static string Convert(int number, bool checkForHundredRule) { - if (number == 0) - { - return UnitsMap[0]; - } - - if (checkForHundredRule && number == 100) - { - return "юз"; - } - - var sb = new StringBuilder(); - - if (number / 1000000000 > 0) - { - sb.AppendFormat("{0} миллиард ", Convert(number / 1000000000, false)); - number %= 1000000000; - } - - if (number / 1000000 > 0) - { - sb.AppendFormat("{0} миллион ", Convert(number / 1000000, true)); - number %= 1000000; - } - - var thousand = number / 1000; - if (thousand > 0) - { - sb.AppendFormat("{0} минг ", Convert(thousand, true)); - number %= 1000; - } - - var hundred = number / 100; - if (hundred > 0) - { - sb.AppendFormat("{0} юз ", Convert(hundred, false)); - number %= 100; - } - - if (number / 10 > 0) - { - sb.AppendFormat("{0} ", TensMap[number / 10]); - number %= 10; - } - - if (number > 0) - { - sb.AppendFormat("{0} ", UnitsMap[number]); - } - - return sb.ToString().Trim(); + if (number == 0) + { + return UnitsMap[0]; + } + + if (checkForHundredRule && number == 100) + { + return "юз"; + } + + var sb = new StringBuilder(); + + if (number / 1000000000 > 0) + { + sb.AppendFormat("{0} миллиард ", Convert(number / 1000000000, false)); + number %= 1000000000; + } + + if (number / 1000000 > 0) + { + sb.AppendFormat("{0} миллион ", Convert(number / 1000000, true)); + number %= 1000000; + } + + var thousand = number / 1000; + if (thousand > 0) + { + sb.AppendFormat("{0} минг ", Convert(thousand, true)); + number %= 1000; + } + + var hundred = number / 100; + if (hundred > 0) + { + sb.AppendFormat("{0} юз ", Convert(hundred, false)); + number %= 100; } + if (number / 10 > 0) + { + sb.AppendFormat("{0} ", TensMap[number / 10]); + number %= 10; + } + + if (number > 0) + { + sb.AppendFormat("{0} ", UnitsMap[number]); + } + + return sb + .ToString() + .Trim(); + } + public override string ConvertToOrdinal(int number) { - var word = Convert(number); - var i = 0; - if (string.IsNullOrEmpty(word)) - { - return string.Empty; - } - - var lastChar = word[^1]; - if (lastChar is 'и' or 'а') - { - i = 1; - } - - return $"{word}{OrdinalSuffixes[i]}"; + var word = Convert(number); + var i = 0; + if (string.IsNullOrEmpty(word)) + { + return string.Empty; } + + var lastChar = word[^1]; + if (lastChar is 'и' or 'а') + { + i = 1; + } + + return $"{word}{OrdinalSuffixes[i]}"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/NumberToWords/UzbekLatnNumberToWordConverter.cs b/src/Humanizer/Localisation/NumberToWords/UzbekLatnNumberToWordConverter.cs index c9aabf638..f3d884b27 100644 --- a/src/Humanizer/Localisation/NumberToWords/UzbekLatnNumberToWordConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/UzbekLatnNumberToWordConverter.cs @@ -9,88 +9,91 @@ class UzbekLatnNumberToWordConverter : GenderlessNumberToWordsConverter public override string Convert(long input) { - if (input is > int.MaxValue or < int.MinValue) - { - throw new NotImplementedException(); - } - var number = (int)input; - if (number < 0) - { - return $"minus {Convert(-number, true)}"; - } - - return Convert(number, true); + if (input is > int.MaxValue or < int.MinValue) + { + throw new NotImplementedException(); } + var number = (int) input; + if (number < 0) + { + return $"minus {Convert(-number, true)}"; + } + + return Convert(number, true); + } + static string Convert(int number, bool checkForHundredRule) { - if (number == 0) - { - return UnitsMap[0]; - } - - if (checkForHundredRule && number == 100) - { - return "yuz"; - } - - var sb = new StringBuilder(); - - if (number / 1000000000 > 0) - { - sb.AppendFormat("{0} milliard ", Convert(number / 1000000000, false)); - number %= 1000000000; - } - - if (number / 1000000 > 0) - { - sb.AppendFormat("{0} million ", Convert(number / 1000000, true)); - number %= 1000000; - } - - var thousand = number / 1000; - if (thousand > 0) - { - sb.AppendFormat("{0} ming ", Convert(thousand, true)); - number %= 1000; - } - - var hundred = number / 100; - if (hundred > 0) - { - sb.AppendFormat("{0} yuz ", Convert(hundred, false)); - number %= 100; - } - - if (number / 10 > 0) - { - sb.AppendFormat("{0} ", TensMap[number / 10]); - number %= 10; - } - - if (number > 0) - { - sb.AppendFormat("{0} ", UnitsMap[number]); - } - - return sb.ToString().Trim(); + if (number == 0) + { + return UnitsMap[0]; + } + + if (checkForHundredRule && number == 100) + { + return "yuz"; + } + + var sb = new StringBuilder(); + + if (number / 1000000000 > 0) + { + sb.AppendFormat("{0} milliard ", Convert(number / 1000000000, false)); + number %= 1000000000; + } + + if (number / 1000000 > 0) + { + sb.AppendFormat("{0} million ", Convert(number / 1000000, true)); + number %= 1000000; + } + + var thousand = number / 1000; + if (thousand > 0) + { + sb.AppendFormat("{0} ming ", Convert(thousand, true)); + number %= 1000; + } + + var hundred = number / 100; + if (hundred > 0) + { + sb.AppendFormat("{0} yuz ", Convert(hundred, false)); + number %= 100; } + if (number / 10 > 0) + { + sb.AppendFormat("{0} ", TensMap[number / 10]); + number %= 10; + } + + if (number > 0) + { + sb.AppendFormat("{0} ", UnitsMap[number]); + } + + return sb + .ToString() + .Trim(); + } + public override string ConvertToOrdinal(int number) { - var word = Convert(number); - var i = 0; - if (string.IsNullOrEmpty(word)) - { - return string.Empty; - } - - var lastChar = word[^1]; - if (lastChar is 'i' or 'a') - { - i = 1; - } - - return $"{word}{OrdinalSuffixes[i]}"; + var word = Convert(number); + var i = 0; + if (string.IsNullOrEmpty(word)) + { + return string.Empty; } + + var lastChar = word[^1]; + if (lastChar is 'i' or 'a') + { + i = 1; + } + + return $"{word}{OrdinalSuffixes[i]}"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Ordinalizers/DutchOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/DutchOrdinalizer.cs index 4923d7a47..f286bc7b8 100644 --- a/src/Humanizer/Localisation/Ordinalizers/DutchOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/DutchOrdinalizer.cs @@ -7,12 +7,12 @@ public override string Convert(int number, string numberString) => public override string Convert(int number, string numberString, GrammaticalGender gender) { - // N/A in Dutch - if (number == 0) - { - return "0"; - } - - return numberString + "e"; + // N/A in Dutch + if (number == 0) + { + return "0"; } + + return numberString + "e"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs index 01a14c1be..2dd0f5dbb 100644 --- a/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs @@ -4,26 +4,26 @@ class EnglishOrdinalizer : DefaultOrdinalizer { public override string Convert(int number, string numberString) { - var nMod100 = number % 100; + var nMod100 = number % 100; - if (nMod100 is >= 11 and <= 20) - { - return numberString + "th"; - } + if (nMod100 is >= 11 and <= 20) + { + return numberString + "th"; + } - switch (number % 10) - { - case 1: - return numberString + "st"; + switch (number % 10) + { + case 1: + return numberString + "st"; - case 2: - return numberString + "nd"; + case 2: + return numberString + "nd"; - case 3: - return numberString + "rd"; + case 3: + return numberString + "rd"; - default: - return numberString + "th"; - } + default: + return numberString + "th"; } + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Ordinalizers/FrenchOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/FrenchOrdinalizer.cs index 55621dfb4..9a6a92890 100644 --- a/src/Humanizer/Localisation/Ordinalizers/FrenchOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/FrenchOrdinalizer.cs @@ -7,15 +7,16 @@ public override string Convert(int number, string numberString) => public override string Convert(int number, string numberString, GrammaticalGender gender) { - if (number == 1) + if (number == 1) + { + if (gender == GrammaticalGender.Feminine) { - if (gender == GrammaticalGender.Feminine) - { - return numberString + "ère"; - } - return numberString + "er"; + return numberString + "ère"; } - return numberString + "ème"; + return numberString + "er"; } + + return numberString + "ème"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Ordinalizers/ItalianOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/ItalianOrdinalizer.cs index 49bb595f4..90fee3715 100644 --- a/src/Humanizer/Localisation/Ordinalizers/ItalianOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/ItalianOrdinalizer.cs @@ -7,17 +7,17 @@ public override string Convert(int number, string numberString) => public override string Convert(int number, string numberString, GrammaticalGender gender) { - // No ordinal for 0 in italian (neologism apart) - if (number == 0) - { - return "0"; - } - - if (gender == GrammaticalGender.Feminine) - { - return numberString + "ª"; - } + // No ordinal for 0 in italian (neologism apart) + if (number == 0) + { + return "0"; + } - return numberString + "°"; + if (gender == GrammaticalGender.Feminine) + { + return numberString + "ª"; } + + return numberString + "°"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Ordinalizers/SpanishOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/SpanishOrdinalizer.cs index 50aa32adf..7d7df53ab 100644 --- a/src/Humanizer/Localisation/Ordinalizers/SpanishOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/SpanishOrdinalizer.cs @@ -10,29 +10,29 @@ public override string Convert(int number, string numberString, GrammaticalGende public override string Convert(int number, string numberString, GrammaticalGender gender, WordForm wordForm) { - // N/A in Spanish - if (number is 0 or int.MinValue) - { - return "0"; - } - - if (number < 0) - { - return Convert(-number, GetNumberString(-number), gender); - } - - switch (gender) - { - case GrammaticalGender.Masculine: - case GrammaticalGender.Neuter: - return numberString + GetWordForm(number, wordForm); - case GrammaticalGender.Feminine: - return numberString + ".ª"; - default: - throw new ArgumentOutOfRangeException(nameof(gender), gender, null); - } + // N/A in Spanish + if (number is 0 or int.MinValue) + { + return "0"; } + if (number < 0) + { + return Convert(-number, GetNumberString(-number), gender); + } + + switch (gender) + { + case GrammaticalGender.Masculine: + case GrammaticalGender.Neuter: + return numberString + GetWordForm(number, wordForm); + case GrammaticalGender.Feminine: + return numberString + ".ª"; + default: + throw new ArgumentOutOfRangeException(nameof(gender), gender, null); + } + } + static CultureInfo _spanishCulture = new("es-ES"); static string GetNumberString(int number) => diff --git a/src/Humanizer/Localisation/Ordinalizers/UkrainianOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/UkrainianOrdinalizer.cs index 95aa22867..71aee5326 100644 --- a/src/Humanizer/Localisation/Ordinalizers/UkrainianOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/UkrainianOrdinalizer.cs @@ -7,29 +7,29 @@ public override string Convert(int number, string numberString) => public override string Convert(int number, string numberString, GrammaticalGender gender) { - if (gender == GrammaticalGender.Masculine) - { - return numberString + "-й"; - } + if (gender == GrammaticalGender.Masculine) + { + return numberString + "-й"; + } - if (gender == GrammaticalGender.Feminine) + if (gender == GrammaticalGender.Feminine) + { + if (number % 10 == 3) { - if (number % 10 == 3) - { - return numberString + "-я"; - } - - return numberString + "-а"; + return numberString + "-я"; } - if (gender == GrammaticalGender.Neuter) + return numberString + "-а"; + } + + if (gender == GrammaticalGender.Neuter) + { + if (number % 10 == 3) { - if (number % 10 == 3) - { - return numberString + "-є"; - } + return numberString + "-є"; } - - return numberString + "-е"; } + + return numberString + "-е"; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/Resources.cs b/src/Humanizer/Localisation/Resources.cs index 33c8a828d..ef771751e 100644 --- a/src/Humanizer/Localisation/Resources.cs +++ b/src/Humanizer/Localisation/Resources.cs @@ -7,7 +7,8 @@ namespace Humanizer; /// public static class Resources { - static readonly ResourceManager ResourceManager = new("Humanizer.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly); + static readonly ResourceManager ResourceManager = new("Humanizer.Properties.Resources", typeof(Resources).GetTypeInfo() + .Assembly); /// /// Returns the value of the specified string resource @@ -17,16 +18,16 @@ public static class Resources /// The value of the resource localized for the specified culture. public static string GetResource(string resourceKey, CultureInfo? culture = null) { - var resource = ResourceManager.GetString(resourceKey, culture); + var resource = ResourceManager.GetString(resourceKey, culture); - if (resource == null || string.IsNullOrEmpty(resource)) - { - throw new ArgumentException($@"The resource object with key '{resourceKey}' was not found", nameof(resourceKey)); - } - - return resource; + if (resource == null || string.IsNullOrEmpty(resource)) + { + throw new ArgumentException($@"The resource object with key '{resourceKey}' was not found", nameof(resourceKey)); } + return resource; + } + /// /// Tries to get the value of the specified string resource, without fallback /// @@ -36,9 +37,9 @@ public static string GetResource(string resourceKey, CultureInfo? culture = null /// true if the specified string resource was found for the given culture; otherwise, false. public static bool TryGetResource(string resourceKey, CultureInfo? culture, [NotNullWhen(true)] out string? result) { - culture ??= CultureInfo.CurrentUICulture; - var resourceSet = ResourceManager.GetResourceSet(culture, createIfNotExists: false, tryParents: false); - result = resourceSet?.GetString(resourceKey); - return result is not null; - } + culture ??= CultureInfo.CurrentUICulture; + var resourceSet = ResourceManager.GetResourceSet(culture, createIfNotExists: false, tryParents: false); + result = resourceSet?.GetString(resourceKey); + return result is not null; + } } \ No newline at end of file diff --git a/src/Humanizer/Localisation/TimeToClockNotation/BrazilianPortugueseTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/BrazilianPortugueseTimeOnlyToClockNotationConverter.cs index 728390eb3..4ee18ee9f 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/BrazilianPortugueseTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/BrazilianPortugueseTimeOnlyToClockNotationConverter.cs @@ -1,36 +1,35 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class BrazilianPortugueseTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { - class BrazilianPortugueseTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter + public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) { - public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + switch (time) { - switch (time) - { - case { Hour: 0, Minute: 0 }: - return "meia-noite"; - case { Hour: 12, Minute: 0 }: - return "meio-dia"; - } + case { Hour: 0, Minute: 0 }: + return "meia-noite"; + case { Hour: 12, Minute: 0 }: + return "meio-dia"; + } - var normalizedHour = time.Hour % 12; - var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes - ? 5 * Math.Round(time.Minute / 5.0) - : time.Minute); + var normalizedHour = time.Hour % 12; + var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes + ? 5 * Math.Round(time.Minute / 5.0) + : time.Minute); - return normalizedMinutes switch - { - 00 => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} em ponto", - 30 => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} e meia", - 40 => $"vinte para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", - 45 => $"quinze para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", - 50 => $"dez para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", - 55 => $"cinco para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", - 60 => $"{(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)} em ponto", - _ => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} e {normalizedMinutes.ToWords()}" - }; - } + return normalizedMinutes switch + { + 00 => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} em ponto", + 30 => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} e meia", + 40 => $"vinte para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", + 45 => $"quinze para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", + 50 => $"dez para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", + 55 => $"cinco para as {(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)}", + 60 => $"{(normalizedHour + 1).ToWords(GrammaticalGender.Feminine)} em ponto", + _ => $"{normalizedHour.ToWords(GrammaticalGender.Feminine)} e {normalizedMinutes.ToWords()}" + }; } } diff --git a/src/Humanizer/Localisation/TimeToClockNotation/DefaultTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/DefaultTimeOnlyToClockNotationConverter.cs index b5bb47124..3efc3a5ab 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/DefaultTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/DefaultTimeOnlyToClockNotationConverter.cs @@ -1,41 +1,40 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class DefaultTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { - class DefaultTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter + public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) { - public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + switch (time) { - switch (time) - { - case { Hour: 0, Minute: 0 }: - return "midnight"; - case { Hour: 12, Minute: 0 }: - return "noon"; - } + case { Hour: 0, Minute: 0 }: + return "midnight"; + case { Hour: 12, Minute: 0 }: + return "noon"; + } - var normalizedHour = time.Hour % 12; - var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes - ? 5 * Math.Round(time.Minute / 5.0) - : time.Minute); + var normalizedHour = time.Hour % 12; + var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes + ? 5 * Math.Round(time.Minute / 5.0) + : time.Minute); - return normalizedMinutes switch - { - 00 => $"{normalizedHour.ToWords()} o'clock", - 05 => $"five past {normalizedHour.ToWords()}", - 10 => $"ten past {normalizedHour.ToWords()}", - 15 => $"a quarter past {normalizedHour.ToWords()}", - 20 => $"twenty past {normalizedHour.ToWords()}", - 25 => $"twenty-five past {normalizedHour.ToWords()}", - 30 => $"half past {normalizedHour.ToWords()}", - 40 => $"twenty to {(normalizedHour + 1).ToWords()}", - 45 => $"a quarter to {(normalizedHour + 1).ToWords()}", - 50 => $"ten to {(normalizedHour + 1).ToWords()}", - 55 => $"five to {(normalizedHour + 1).ToWords()}", - 60 => $"{(normalizedHour + 1).ToWords()} o'clock", - _ => $"{normalizedHour.ToWords()} {normalizedMinutes.ToWords()}" - }; - } + return normalizedMinutes switch + { + 00 => $"{normalizedHour.ToWords()} o'clock", + 05 => $"five past {normalizedHour.ToWords()}", + 10 => $"ten past {normalizedHour.ToWords()}", + 15 => $"a quarter past {normalizedHour.ToWords()}", + 20 => $"twenty past {normalizedHour.ToWords()}", + 25 => $"twenty-five past {normalizedHour.ToWords()}", + 30 => $"half past {normalizedHour.ToWords()}", + 40 => $"twenty to {(normalizedHour + 1).ToWords()}", + 45 => $"a quarter to {(normalizedHour + 1).ToWords()}", + 50 => $"ten to {(normalizedHour + 1).ToWords()}", + 55 => $"five to {(normalizedHour + 1).ToWords()}", + 60 => $"{(normalizedHour + 1).ToWords()} o'clock", + _ => $"{normalizedHour.ToWords()} {normalizedMinutes.ToWords()}" + }; } } diff --git a/src/Humanizer/Localisation/TimeToClockNotation/EsTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/EsTimeOnlyToClockNotationConverter.cs index bda38abb4..b644c9c27 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/EsTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/EsTimeOnlyToClockNotationConverter.cs @@ -1,88 +1,87 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class EsTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { - class EsTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter - { - const int MORNING = 6; - const int NOON = 12; - const int AFTERNOON = 21; + const int MORNING = 6; + const int NOON = 12; + const int AFTERNOON = 21; - public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + { + switch (time) { - switch (time) - { - case { Hour: 0, Minute: 0 }: - return "medianoche"; - - case { Hour: 12, Minute: 0 }: - return "mediodía"; - } - - var article = GetArticle(time); - var articleNextHour = GetArticle(time.AddHours(1)); - var hour = NormalizeHour(time).ToWords(GrammaticalGender.Feminine); - var nextHour = NormalizeHour(time.AddHours(1)).ToWords(GrammaticalGender.Feminine); - var dayPeriod = GetDayPeriod(time); - var dayPeriodNextHour = GetDayPeriod(time.AddHours(1)); - - var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes - ? 5 * Math.Round(time.Minute / 5.0) - : time.Minute); - - var clockNotationMap = new Dictionary() - { - { 0, $"{article} {hour} {dayPeriod}" }, - { 15 , $"{article} {hour} y cuarto {dayPeriod}" }, - { 30 , $"{article} {hour} y media {dayPeriod}"}, - { 35 , $"{articleNextHour} {nextHour} menos veinticinco {dayPeriodNextHour}"}, - { 40 , $"{articleNextHour} {nextHour} menos veinte {dayPeriodNextHour}"}, - { 45 , $"{articleNextHour} {nextHour} menos cuarto {dayPeriodNextHour}"}, - { 50 , $"{articleNextHour} {nextHour} menos diez {dayPeriodNextHour}"}, - { 55 , $"{articleNextHour} {nextHour} menos cinco {dayPeriodNextHour}"}, - { 60 , $"{articleNextHour} {nextHour} {dayPeriodNextHour}"}, - }; - - return clockNotationMap.GetValueOrDefault( - normalizedMinutes, - $"{article} {hour} y {normalizedMinutes.ToWords()} {dayPeriod}"); + case { Hour: 0, Minute: 0 }: + return "medianoche"; + + case { Hour: 12, Minute: 0 }: + return "mediodía"; } - static int NormalizeHour(TimeOnly time) => - time.Hour % 12 != 0 ? time.Hour % 12 : 12; + var article = GetArticle(time); + var articleNextHour = GetArticle(time.AddHours(1)); + var hour = NormalizeHour(time).ToWords(GrammaticalGender.Feminine); + var nextHour = NormalizeHour(time.AddHours(1)).ToWords(GrammaticalGender.Feminine); + var dayPeriod = GetDayPeriod(time); + var dayPeriodNextHour = GetDayPeriod(time.AddHours(1)); - static string GetArticle(TimeOnly time) => - time.Hour is 1 or 13 ? "la" : "las"; + var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes + ? 5 * Math.Round(time.Minute / 5.0) + : time.Minute); - static string GetDayPeriod(TimeOnly time) + var clockNotationMap = new Dictionary() { - if (IsEarlyMorning(time)) - { - return "de la madrugada"; - } - - if (IsMorning(time)) - { - return "de la mañana"; - } - - if (IsAfternoon(time)) - { - return "de la tarde"; - } - - return "de la noche"; + { 0, $"{article} {hour} {dayPeriod}" }, + { 15 , $"{article} {hour} y cuarto {dayPeriod}" }, + { 30 , $"{article} {hour} y media {dayPeriod}"}, + { 35 , $"{articleNextHour} {nextHour} menos veinticinco {dayPeriodNextHour}"}, + { 40 , $"{articleNextHour} {nextHour} menos veinte {dayPeriodNextHour}"}, + { 45 , $"{articleNextHour} {nextHour} menos cuarto {dayPeriodNextHour}"}, + { 50 , $"{articleNextHour} {nextHour} menos diez {dayPeriodNextHour}"}, + { 55 , $"{articleNextHour} {nextHour} menos cinco {dayPeriodNextHour}"}, + { 60 , $"{articleNextHour} {nextHour} {dayPeriodNextHour}"}, + }; + + return clockNotationMap.GetValueOrDefault( + normalizedMinutes, + $"{article} {hour} y {normalizedMinutes.ToWords()} {dayPeriod}"); + } + + static int NormalizeHour(TimeOnly time) => + time.Hour % 12 != 0 ? time.Hour % 12 : 12; + + static string GetArticle(TimeOnly time) => + time.Hour is 1 or 13 ? "la" : "las"; + + static string GetDayPeriod(TimeOnly time) + { + if (IsEarlyMorning(time)) + { + return "de la madrugada"; } - static bool IsEarlyMorning(TimeOnly time) => - time.Hour is >= 1 and < MORNING; + if (IsMorning(time)) + { + return "de la mañana"; + } - static bool IsMorning(TimeOnly time) => - time.Hour is >= MORNING and < NOON; + if (IsAfternoon(time)) + { + return "de la tarde"; + } - static bool IsAfternoon(TimeOnly time) => - time.Hour is >= NOON and < AFTERNOON; + return "de la noche"; } + + static bool IsEarlyMorning(TimeOnly time) => + time.Hour is >= 1 and < MORNING; + + static bool IsMorning(TimeOnly time) => + time.Hour is >= MORNING and < NOON; + + static bool IsAfternoon(TimeOnly time) => + time.Hour is >= NOON and < AFTERNOON; } #endif diff --git a/src/Humanizer/Localisation/TimeToClockNotation/FrTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/FrTimeOnlyToClockNotationConverter.cs index 63d5812c0..62bdf31d3 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/FrTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/FrTimeOnlyToClockNotationConverter.cs @@ -1,30 +1,29 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +class FrTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { - class FrTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter + public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) { - public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes + ? 5 * Math.Round(time.Minute / 5.0) + : time.Minute); + + return normalizedMinutes switch { - var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes - ? 5 * Math.Round(time.Minute / 5.0) - : time.Minute); + 00 => GetHourExpression(time.Hour), + 60 => GetHourExpression(time.Hour + 1), + _ => $"{GetHourExpression(time.Hour)} {normalizedMinutes.ToWords(GrammaticalGender.Feminine)}" + }; - return normalizedMinutes switch + static string GetHourExpression(int hour) => + hour switch { - 00 => GetHourExpression(time.Hour), - 60 => GetHourExpression(time.Hour + 1), - _ => $"{GetHourExpression(time.Hour)} {normalizedMinutes.ToWords(GrammaticalGender.Feminine)}" + 0 => "minuit", + 12 => "midi", + _ => hour.ToWords(GrammaticalGender.Feminine) + (hour > 1 ? " heures" : " heure") }; - - static string GetHourExpression(int hour) => - hour switch - { - 0 => "minuit", - 12 => "midi", - _ => hour.ToWords(GrammaticalGender.Feminine) + (hour > 1 ? " heures" : " heure") - }; - } } } diff --git a/src/Humanizer/Localisation/TimeToClockNotation/ITimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/ITimeOnlyToClockNotationConverter.cs index 3ec06fbca..a2ad41551 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/ITimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/ITimeOnlyToClockNotationConverter.cs @@ -1,17 +1,16 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// The interface used to localise the ToClockNotation method. +/// +public interface ITimeOnlyToClockNotationConverter { /// - /// The interface used to localise the ToClockNotation method. + /// Converts the time to Clock Notation /// - public interface ITimeOnlyToClockNotationConverter - { - /// - /// Converts the time to Clock Notation - /// - string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive); - } + string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive); } #endif diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 0cd867ebb..d49bbef48 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -34,10 +34,10 @@ public static class MetricNumeralExtensions static MetricNumeralExtensions() { - const int limit = 27; - BigLimit = Math.Pow(10, limit); - SmallLimit = Math.Pow(10, -limit); - } + const int limit = 27; + BigLimit = Math.Pow(10, limit); + SmallLimit = Math.Pow(10, -limit); + } /// /// Symbols is a list of every symbols for the Metric system. @@ -60,23 +60,55 @@ static MetricNumeralExtensions() /// static readonly Dictionary UnitPrefixes = new() { - {'Y', new("yotta", "septillion", "quadrillion")}, - {'Z', new("zetta", "sextillion", "trilliard")}, - {'E', new("exa", "quintillion", "trillion")}, - {'P', new("peta", "quadrillion", "billiard")}, - {'T', new("tera", "trillion", "billion")}, - {'G', new("giga", "billion", "milliard")}, - {'M', new("mega", "million")}, - {'k', new("kilo", "thousand")}, - - {'m', new("milli", "thousandth")}, - {'μ', new("micro", "millionth")}, - {'n', new("nano", "billionth", "milliardth")}, - {'p', new("pico", "trillionth", "billionth")}, - {'f', new("femto", "quadrillionth", "billiardth")}, - {'a', new("atto", "quintillionth", "trillionth")}, - {'z', new("zepto", "sextillionth", "trilliardth")}, - {'y', new("yocto", "septillionth", "quadrillionth")} + { + 'Y', new("yotta", "septillion", "quadrillion") + }, + { + 'Z', new("zetta", "sextillion", "trilliard") + }, + { + 'E', new("exa", "quintillion", "trillion") + }, + { + 'P', new("peta", "quadrillion", "billiard") + }, + { + 'T', new("tera", "trillion", "billion") + }, + { + 'G', new("giga", "billion", "milliard") + }, + { + 'M', new("mega", "million") + }, + { + 'k', new("kilo", "thousand") + }, + + { + 'm', new("milli", "thousandth") + }, + { + 'μ', new("micro", "millionth") + }, + { + 'n', new("nano", "billionth", "milliardth") + }, + { + 'p', new("pico", "trillionth", "billionth") + }, + { + 'f', new("femto", "quadrillionth", "billiardth") + }, + { + 'a', new("atto", "quintillionth", "trillionth") + }, + { + 'z', new("zepto", "sextillionth", "trilliardth") + }, + { + 'y', new("yocto", "septillionth", "quadrillionth") + } }; /// @@ -97,9 +129,9 @@ static MetricNumeralExtensions() /// A number after a conversion from a Metric representation. public static double FromMetric(this string input) { - input = CleanRepresentation(input); - return BuildNumber(input, input[^1]); - } + input = CleanRepresentation(input); + return BuildNumber(input, input[^1]); + } /// /// Converts a number into a valid and Human-readable Metric representation. @@ -120,7 +152,7 @@ public static double FromMetric(this string input) /// /// A valid Metric representation public static string ToMetric(this int input, MetricNumeralFormats? formats = null, int? decimals = null) => - ((double)input).ToMetric(formats, decimals); + ((double) input).ToMetric(formats, decimals); /// /// Converts a number into a valid and Human-readable Metric representation. @@ -142,19 +174,19 @@ public static string ToMetric(this int input, MetricNumeralFormats? formats = nu /// A valid Metric representation public static string ToMetric(this double input, MetricNumeralFormats? formats = null, int? decimals = null) { - if (input.Equals(0)) - { - return input.ToString(); - } - - if (input.IsOutOfRange()) - { - throw new ArgumentOutOfRangeException(nameof(input)); - } + if (input.Equals(0)) + { + return input.ToString(); + } - return BuildRepresentation(input, formats, decimals); + if (input.IsOutOfRange()) + { + throw new ArgumentOutOfRangeException(nameof(input)); } + return BuildRepresentation(input, formats, decimals); + } + /// /// Clean or handle any wrong input /// @@ -162,21 +194,21 @@ public static string ToMetric(this double input, MetricNumeralFormats? formats = /// A cleaned representation static string CleanRepresentation(string input) { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - input = input.Trim(); - input = ReplaceNameBySymbol(input); - if (input.Length == 0 || input.IsInvalidMetricNumeral()) - { - throw new ArgumentException("Empty or invalid Metric string.", nameof(input)); - } - - return input.Replace(" ", string.Empty); + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + input = input.Trim(); + input = ReplaceNameBySymbol(input); + if (input.Length == 0 || input.IsInvalidMetricNumeral()) + { + throw new ArgumentException("Empty or invalid Metric string.", nameof(input)); } + return input.Replace(" ", string.Empty); + } + /// /// Build a number from a metric representation or from a number /// @@ -196,13 +228,14 @@ static double BuildNumber(string input, char last) => /// A number build from a Metric representation static double BuildMetricNumber(string input, char last) { - double getExponent(List symbols) => (symbols.IndexOf(last) + 1) * 3; - var number = double.Parse(input.Remove(input.Length - 1)); - var exponent = Math.Pow(10, Symbols[0].Contains(last) - ? getExponent(Symbols[0]) - : -getExponent(Symbols[1])); - return number * exponent; - } + double getExponent(List symbols) => (symbols.IndexOf(last) + 1) * 3; + var number = double.Parse(input.Remove(input.Length - 1)); + var exponent = Math.Pow(10, Symbols[0] + .Contains(last) + ? getExponent(Symbols[0]) + : -getExponent(Symbols[1])); + return number * exponent; + } /// /// Replace every symbol's name by its symbol representation. @@ -222,17 +255,22 @@ static string ReplaceNameBySymbol(string input) => /// A number in a Metric representation static string BuildRepresentation(double input, MetricNumeralFormats? formats, int? decimals) { - var exponent = (int)Math.Floor(Math.Log10(Math.Abs(input)) / 3); - - if (!exponent.Equals(0)) return BuildMetricRepresentation(input, exponent, formats, decimals); - var representation = decimals.HasValue ? Math.Round(input, decimals.Value).ToString() : input.ToString(); - if ((formats & MetricNumeralFormats.WithSpace) == MetricNumeralFormats.WithSpace) - { - representation += " "; - } - return representation; + var exponent = (int) Math.Floor(Math.Log10(Math.Abs(input)) / 3); + + if (!exponent.Equals(0)) return BuildMetricRepresentation(input, exponent, formats, decimals); + var representation = decimals.HasValue + ? Math + .Round(input, decimals.Value) + .ToString() + : input.ToString(); + if ((formats & MetricNumeralFormats.WithSpace) == MetricNumeralFormats.WithSpace) + { + representation += " "; } + return representation; + } + /// /// Build a Metric representation of the number. /// @@ -243,20 +281,20 @@ static string BuildRepresentation(double input, MetricNumeralFormats? formats, i /// A number in a Metric representation static string BuildMetricRepresentation(double input, int exponent, MetricNumeralFormats? formats, int? decimals) { - var number = input * Math.Pow(1000, -exponent); - if (decimals.HasValue) - { - number = Math.Round(number, decimals.Value); - } - - var symbol = Math.Sign(exponent) == 1 - ? Symbols[0][exponent - 1] - : Symbols[1][-exponent - 1]; - return number.ToString("G15") - + (formats.HasValue && formats.Value.HasFlag(MetricNumeralFormats.WithSpace) ? " " : string.Empty) - + GetUnitText(symbol, formats); + var number = input * Math.Pow(1000, -exponent); + if (decimals.HasValue) + { + number = Math.Round(number, decimals.Value); } + var symbol = Math.Sign(exponent) == 1 + ? Symbols[0][exponent - 1] + : Symbols[1][-exponent - 1]; + return number.ToString("G15") + + (formats.HasValue && formats.Value.HasFlag(MetricNumeralFormats.WithSpace) ? " " : string.Empty) + + GetUnitText(symbol, formats); + } + /// /// Get the unit from a symbol of from the symbol's name. /// @@ -265,24 +303,27 @@ static string BuildMetricRepresentation(double input, int exponent, MetricNumera /// A symbol, a symbol's name, a symbol's short scale word or a symbol's long scale word static string GetUnitText(char symbol, MetricNumeralFormats? formats) { - if (formats.HasValue - && formats.Value.HasFlag(MetricNumeralFormats.UseName)) - { - return UnitPrefixes[symbol].Name; - } - if (formats.HasValue - && formats.Value.HasFlag(MetricNumeralFormats.UseShortScaleWord)) - { - return UnitPrefixes[symbol].ShortScaleWord; - } - if (formats.HasValue - && formats.Value.HasFlag(MetricNumeralFormats.UseLongScaleWord)) - { - return UnitPrefixes[symbol].LongScaleWord; - } - return symbol.ToString(); + if (formats.HasValue + && formats.Value.HasFlag(MetricNumeralFormats.UseName)) + { + return UnitPrefixes[symbol].Name; + } + + if (formats.HasValue + && formats.Value.HasFlag(MetricNumeralFormats.UseShortScaleWord)) + { + return UnitPrefixes[symbol].ShortScaleWord; } + if (formats.HasValue + && formats.Value.HasFlag(MetricNumeralFormats.UseLongScaleWord)) + { + return UnitPrefixes[symbol].LongScaleWord; + } + + return symbol.ToString(); + } + /// /// Check if a Metric representation is out of the valid range. /// @@ -290,11 +331,11 @@ static string GetUnitText(char symbol, MetricNumeralFormats? formats) /// True if input is out of the valid range. static bool IsOutOfRange(this double input) { - bool outside(double min, double max) => !(max > input && input > min); + bool outside(double min, double max) => !(max > input && input > min); - return (Math.Sign(input) == 1 && outside(SmallLimit, BigLimit)) - || (Math.Sign(input) == -1 && outside(-BigLimit, -SmallLimit)); - } + return (Math.Sign(input) == 1 && outside(SmallLimit, BigLimit)) + || (Math.Sign(input) == -1 && outside(-BigLimit, -SmallLimit)); + } /// /// Check if a string is not a valid Metric representation. @@ -308,11 +349,13 @@ static bool IsOutOfRange(this double input) /// True if input is not a valid Metric representation. static bool IsInvalidMetricNumeral(this string input) { - var index = input.Length - 1; - var last = input[index]; - var isSymbol = Symbols[0].Contains(last) || Symbols[1].Contains(last); - return !double.TryParse(isSymbol ? input.Remove(index) : input, out _); - } + var index = input.Length - 1; + var last = input[index]; + var isSymbol = Symbols[0] + .Contains(last) || Symbols[1] + .Contains(last); + return !double.TryParse(isSymbol ? input.Remove(index) : input, out _); + } struct UnitPrefix(string name, string shortScaleWord, string? longScaleWord = null) { @@ -320,4 +363,4 @@ struct UnitPrefix(string name, string shortScaleWord, string? longScaleWord = nu public string ShortScaleWord { get; } = shortScaleWord; public string LongScaleWord => longScaleWord ?? ShortScaleWord; } -} \ No newline at end of file +} diff --git a/src/Humanizer/RomanNumeralExtensions.cs b/src/Humanizer/RomanNumeralExtensions.cs index 89bd974d9..3d57b298c 100644 --- a/src/Humanizer/RomanNumeralExtensions.cs +++ b/src/Humanizer/RomanNumeralExtensions.cs @@ -12,19 +12,45 @@ public static class RomanNumeralExtensions static readonly IDictionary RomanNumerals = new Dictionary(NumberOfRomanNumeralMaps) { - { "M", 1000 }, - { "CM", 900 }, - { "D", 500 }, - { "CD", 400 }, - { "C", 100 }, - { "XC", 90 }, - { "L", 50 }, - { "XL", 40 }, - { "X", 10 }, - { "IX", 9 }, - { "V", 5 }, - { "IV", 4 }, - { "I", 1 } + { + "M", 1000 + }, + { + "CM", 900 + }, + { + "D", 500 + }, + { + "CD", 400 + }, + { + "C", 100 + }, + { + "XC", 90 + }, + { + "L", 50 + }, + { + "XL", 40 + }, + { + "X", 10 + }, + { + "IX", 9 + }, + { + "V", 5 + }, + { + "IV", 4 + }, + { + "I", 1 + } }; static readonly Regex ValidRomanNumeral = @@ -39,44 +65,48 @@ public static class RomanNumeralExtensions /// Human-readable number public static int FromRoman(this string input) { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } - input = input.Trim().ToUpperInvariant(); + input = input + .Trim() + .ToUpperInvariant(); - var length = input.Length; + var length = input.Length; - if (length == 0 || IsInvalidRomanNumeral(input)) - { - throw new ArgumentException("Empty or invalid Roman numeral string.", nameof(input)); - } + if (length == 0 || IsInvalidRomanNumeral(input)) + { + throw new ArgumentException("Empty or invalid Roman numeral string.", nameof(input)); + } - var total = 0; - var i = length; + var total = 0; + var i = length; - while (i > 0) + while (i > 0) + { + var digit = RomanNumerals[input[--i] + .ToString()]; + + if (i > 0) { - var digit = RomanNumerals[input[--i].ToString()]; + var previousDigit = RomanNumerals[input[i - 1] + .ToString()]; - if (i > 0) + if (previousDigit < digit) { - var previousDigit = RomanNumerals[input[i - 1].ToString()]; - - if (previousDigit < digit) - { - digit -= previousDigit; - i--; - } + digit -= previousDigit; + i--; } - - total += digit; } - return total; + total += digit; } + return total; + } + /// /// Converts the input to Roman number /// @@ -85,29 +115,29 @@ public static int FromRoman(this string input) /// Thrown when the input is smaller than 1 or larger than 3999 public static string ToRoman(this int input) { - const int minValue = 1; - const int maxValue = 3999; - const int maxRomanNumeralLength = 15; + const int minValue = 1; + const int maxValue = 3999; + const int maxRomanNumeralLength = 15; - if (input is < minValue or > maxValue) - { - throw new ArgumentOutOfRangeException(); - } + if (input is < minValue or > maxValue) + { + throw new ArgumentOutOfRangeException(); + } - var sb = new StringBuilder(maxRomanNumeralLength); + var sb = new StringBuilder(maxRomanNumeralLength); - foreach (var pair in RomanNumerals) + foreach (var pair in RomanNumerals) + { + while (input / pair.Value > 0) { - while (input / pair.Value > 0) - { - sb.Append(pair.Key); - input -= pair.Value; - } + sb.Append(pair.Key); + input -= pair.Value; } - - return sb.ToString(); } + return sb.ToString(); + } + static bool IsInvalidRomanNumeral(string input) => !ValidRomanNumeral.IsMatch(input); } \ No newline at end of file diff --git a/src/Humanizer/StringDehumanizeExtensions.cs b/src/Humanizer/StringDehumanizeExtensions.cs index 853d9f8be..f6f3ce07e 100644 --- a/src/Humanizer/StringDehumanizeExtensions.cs +++ b/src/Humanizer/StringDehumanizeExtensions.cs @@ -12,7 +12,13 @@ public static class StringDehumanizeExtensions /// The string to be dehumanized public static string Dehumanize(this string input) { - var pascalizedWords = input.Split(' ').Select(word => word.Humanize().Pascalize()); - return string.Concat(pascalizedWords).Replace(" ", ""); - } + var pascalizedWords = input + .Split(' ') + .Select(word => word + .Humanize() + .Pascalize()); + return string + .Concat(pascalizedWords) + .Replace(" ", ""); + } } \ No newline at end of file diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index 1e6d2baa5..c220a7191 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -16,70 +16,77 @@ public static class StringHumanizeExtensions static StringHumanizeExtensions() { - PascalCaseWordPartsRegex = new( - $"({OptionallyCapitalizedWord}|{IntegerAndOptionalLowercaseLetters}|{Acronym}|{SequenceOfOtherLetters}){MidSentencePunctuation}", - RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture | RegexOptions.Compiled); - FreestandingSpacingCharRegex = new(@"\s[-_]|[-_]\s", RegexOptions.Compiled); - } + PascalCaseWordPartsRegex = new( + $"({OptionallyCapitalizedWord}|{IntegerAndOptionalLowercaseLetters}|{Acronym}|{SequenceOfOtherLetters}){MidSentencePunctuation}", + RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture | RegexOptions.Compiled); + FreestandingSpacingCharRegex = new(@"\s[-_]|[-_]\s", RegexOptions.Compiled); + } static string FromUnderscoreDashSeparatedWords(string input) => string.Join(" ", input.Split(['_', '-'])); static string FromPascalCase(string input) { - var result = string.Join(" ", PascalCaseWordPartsRegex - .Matches(input).Cast() - .Select(match => - { - var value = match.Value; - return value.All(char.IsUpper) && - (value.Length > 1 || (match.Index > 0 && input[match.Index - 1] == ' ') || value == "I") - ? value - : value.ToLower(); - })); - - if (result.Replace(" ", "").All(char.IsUpper) && - result.Contains(" ")) + var result = string.Join(" ", PascalCaseWordPartsRegex + .Matches(input) + .Cast() + .Select(match => { - result = result.ToLower(); - } + var value = match.Value; + return value.All(char.IsUpper) && + (value.Length > 1 || (match.Index > 0 && input[match.Index - 1] == ' ') || value == "I") + ? value + : value.ToLower(); + })); - return result.Length > 0 ? char.ToUpper(result[0]) + - result.Substring(1, result.Length - 1) : result; + if (result + .Replace(" ", "") + .All(char.IsUpper) && + result.Contains(" ")) + { + result = result.ToLower(); } + return result.Length > 0 + ? char.ToUpper(result[0]) + + result.Substring(1, result.Length - 1) + : result; + } + /// /// Humanizes the input string; e.g. Underscored_input_String_is_turned_INTO_sentence -> 'Underscored input String is turned INTO sentence' /// /// The string to be humanized public static string Humanize(this string input) { - // if input is all capitals (e.g. an acronym) then return it without change - if (input.All(char.IsUpper)) - { - return input; - } - - // if input contains a dash or underscore which precedes or follows a space (or both, e.g. free-standing) - // remove the dash/underscore and run it through FromPascalCase - if (FreestandingSpacingCharRegex.IsMatch(input)) - { - return FromPascalCase(FromUnderscoreDashSeparatedWords(input)); - } + // if input is all capitals (e.g. an acronym) then return it without change + if (input.All(char.IsUpper)) + { + return input; + } - if (input.Contains("_") || input.Contains("-")) - { - return FromUnderscoreDashSeparatedWords(input); - } + // if input contains a dash or underscore which precedes or follows a space (or both, e.g. free-standing) + // remove the dash/underscore and run it through FromPascalCase + if (FreestandingSpacingCharRegex.IsMatch(input)) + { + return FromPascalCase(FromUnderscoreDashSeparatedWords(input)); + } - return FromPascalCase(input); + if (input.Contains("_") || input.Contains("-")) + { + return FromUnderscoreDashSeparatedWords(input); } + return FromPascalCase(input); + } + /// /// Humanized the input string based on the provided casing /// /// The string to be humanized /// The desired casing for the output public static string Humanize(this string input, LetterCasing casing) => - input.Humanize().ApplyCase(casing); + input + .Humanize() + .ApplyCase(casing); } \ No newline at end of file diff --git a/src/Humanizer/TimeOnlyToClockNotationExtensions.cs b/src/Humanizer/TimeOnlyToClockNotationExtensions.cs index 0bc3f2f22..871598e45 100644 --- a/src/Humanizer/TimeOnlyToClockNotationExtensions.cs +++ b/src/Humanizer/TimeOnlyToClockNotationExtensions.cs @@ -1,21 +1,20 @@ #if NET6_0_OR_GREATER -namespace Humanizer +namespace Humanizer; + +/// +/// Humanizes TimeOnly into human readable sentence +/// +public static class TimeOnlyToClockNotationExtensions { /// - /// Humanizes TimeOnly into human readable sentence + /// Turns the provided time into clock notation /// - public static class TimeOnlyToClockNotationExtensions - { - /// - /// Turns the provided time into clock notation - /// - /// The time to be made into clock notation - /// Whether to round the minutes to the nearest five or not - /// The time in clock notation - public static string ToClockNotation(this TimeOnly input, ClockNotationRounding roundToNearestFive = ClockNotationRounding.None) => - Configurator.TimeOnlyToClockNotationConverter.Convert(input, roundToNearestFive); - } + /// The time to be made into clock notation + /// Whether to round the minutes to the nearest five or not + /// The time in clock notation + public static string ToClockNotation(this TimeOnly input, ClockNotationRounding roundToNearestFive = ClockNotationRounding.None) => + Configurator.TimeOnlyToClockNotationConverter.Convert(input, roundToNearestFive); } #endif diff --git a/src/Humanizer/TimeSpanHumanizeExtensions.cs b/src/Humanizer/TimeSpanHumanizeExtensions.cs index d0ae8244c..b448710fe 100644 --- a/src/Humanizer/TimeSpanHumanizeExtensions.cs +++ b/src/Humanizer/TimeSpanHumanizeExtensions.cs @@ -9,7 +9,8 @@ public static class TimeSpanHumanizeExtensions const double _daysInAYear = 365.2425; // see https://en.wikipedia.org/wiki/Gregorian_calendar const double _daysInAMonth = _daysInAYear / 12; - static TimeUnit[] _timeUnits = Enum.GetValues(typeof(TimeUnit)) + static TimeUnit[] _timeUnits = Enum + .GetValues(typeof(TimeUnit)) .Cast() .Reverse() .ToArray(); @@ -38,11 +39,11 @@ public static string Humanize(this TimeSpan timeSpan, int precision = 1, Culture /// Uses words instead of numbers if true. E.g. one day. public static string Humanize(this TimeSpan timeSpan, int precision, bool countEmptyUnits, CultureInfo? culture = null, TimeUnit maxUnit = TimeUnit.Week, TimeUnit minUnit = TimeUnit.Millisecond, string? collectionSeparator = ", ", bool toWords = false) { - var timeParts = CreateTheTimePartsWithUpperAndLowerLimits(timeSpan, culture, maxUnit, minUnit, toWords); - timeParts = SetPrecisionOfTimeSpan(timeParts, precision, countEmptyUnits); + var timeParts = CreateTheTimePartsWithUpperAndLowerLimits(timeSpan, culture, maxUnit, minUnit, toWords); + timeParts = SetPrecisionOfTimeSpan(timeParts, precision, countEmptyUnits); - return ConcatenateTimeSpanParts(timeParts, culture, collectionSeparator); - } + return ConcatenateTimeSpanParts(timeParts, culture, collectionSeparator); + } /// /// Turns a TimeSpan into an age expression, e.g. "40 years old" @@ -54,127 +55,135 @@ public static string Humanize(this TimeSpan timeSpan, int precision, bool countE /// Age expression in the given culture/language public static string ToAge(this TimeSpan timeSpan, CultureInfo? culture = null, TimeUnit maxUnit = TimeUnit.Year, bool toWords = false) { - var timeSpanExpression = timeSpan.Humanize(culture: culture, maxUnit: maxUnit, toWords: toWords); + var timeSpanExpression = timeSpan.Humanize(culture: culture, maxUnit: maxUnit, toWords: toWords); - var cultureFormatter = Configurator.GetFormatter(culture); - return string.Format(cultureFormatter.TimeSpanHumanize_Age(), timeSpanExpression); - } + var cultureFormatter = Configurator.GetFormatter(culture); + return string.Format(cultureFormatter.TimeSpanHumanize_Age(), timeSpanExpression); + } static IEnumerable CreateTheTimePartsWithUpperAndLowerLimits(TimeSpan timespan, CultureInfo? culture, TimeUnit maxUnit, TimeUnit minUnit, bool toWords = false) { - var cultureFormatter = Configurator.GetFormatter(culture); - var firstValueFound = false; - var timeParts = new List(); + var cultureFormatter = Configurator.GetFormatter(culture); + var firstValueFound = false; + var timeParts = new List(); - foreach (var timeUnit in _timeUnits) - { - var timePart = GetTimeUnitPart(timeUnit, timespan, maxUnit, minUnit, cultureFormatter, toWords); + foreach (var timeUnit in _timeUnits) + { + var timePart = GetTimeUnitPart(timeUnit, timespan, maxUnit, minUnit, cultureFormatter, toWords); - if (timePart != null || firstValueFound) - { - firstValueFound = true; - timeParts.Add(timePart); - } - } - if (IsContainingOnlyNullValue(timeParts)) + if (timePart != null || firstValueFound) { - var noTimeValueCultureFormatted = toWords ? cultureFormatter.TimeSpanHumanize_Zero() - : cultureFormatter.TimeSpanHumanize(minUnit, 0); - timeParts = CreateTimePartsWithNoTimeValue(noTimeValueCultureFormatted); + firstValueFound = true; + timeParts.Add(timePart); } - return timeParts; } + if (IsContainingOnlyNullValue(timeParts)) + { + var noTimeValueCultureFormatted = toWords + ? cultureFormatter.TimeSpanHumanize_Zero() + : cultureFormatter.TimeSpanHumanize(minUnit, 0); + timeParts = CreateTimePartsWithNoTimeValue(noTimeValueCultureFormatted); + } + + return timeParts; + } + static string? GetTimeUnitPart(TimeUnit timeUnitToGet, TimeSpan timespan, TimeUnit maximumTimeUnit, TimeUnit minimumTimeUnit, IFormatter cultureFormatter, bool toWords = false) { - if (timeUnitToGet <= maximumTimeUnit && timeUnitToGet >= minimumTimeUnit) - { - var numberOfTimeUnits = GetTimeUnitNumericalValue(timeUnitToGet, timespan, maximumTimeUnit); - return BuildFormatTimePart(cultureFormatter, timeUnitToGet, numberOfTimeUnits, toWords); - } - return null; + if (timeUnitToGet <= maximumTimeUnit && timeUnitToGet >= minimumTimeUnit) + { + var numberOfTimeUnits = GetTimeUnitNumericalValue(timeUnitToGet, timespan, maximumTimeUnit); + return BuildFormatTimePart(cultureFormatter, timeUnitToGet, numberOfTimeUnits, toWords); } + return null; + } + static int GetTimeUnitNumericalValue(TimeUnit timeUnitToGet, TimeSpan timespan, TimeUnit maximumTimeUnit) { - var isTimeUnitToGetTheMaximumTimeUnit = timeUnitToGet == maximumTimeUnit; - switch (timeUnitToGet) - { - case TimeUnit.Millisecond: - return GetNormalCaseTimeAsInteger(timespan.Milliseconds, timespan.TotalMilliseconds, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Second: - return GetNormalCaseTimeAsInteger(timespan.Seconds, timespan.TotalSeconds, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Minute: - return GetNormalCaseTimeAsInteger(timespan.Minutes, timespan.TotalMinutes, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Hour: - return GetNormalCaseTimeAsInteger(timespan.Hours, timespan.TotalHours, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Day: - return GetSpecialCaseDaysAsInteger(timespan, maximumTimeUnit); - case TimeUnit.Week: - return GetSpecialCaseWeeksAsInteger(timespan, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Month: - return GetSpecialCaseMonthAsInteger(timespan, isTimeUnitToGetTheMaximumTimeUnit); - case TimeUnit.Year: - return GetSpecialCaseYearAsInteger(timespan); - default: - return 0; - } + var isTimeUnitToGetTheMaximumTimeUnit = timeUnitToGet == maximumTimeUnit; + switch (timeUnitToGet) + { + case TimeUnit.Millisecond: + return GetNormalCaseTimeAsInteger(timespan.Milliseconds, timespan.TotalMilliseconds, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Second: + return GetNormalCaseTimeAsInteger(timespan.Seconds, timespan.TotalSeconds, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Minute: + return GetNormalCaseTimeAsInteger(timespan.Minutes, timespan.TotalMinutes, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Hour: + return GetNormalCaseTimeAsInteger(timespan.Hours, timespan.TotalHours, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Day: + return GetSpecialCaseDaysAsInteger(timespan, maximumTimeUnit); + case TimeUnit.Week: + return GetSpecialCaseWeeksAsInteger(timespan, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Month: + return GetSpecialCaseMonthAsInteger(timespan, isTimeUnitToGetTheMaximumTimeUnit); + case TimeUnit.Year: + return GetSpecialCaseYearAsInteger(timespan); + default: + return 0; } + } static int GetSpecialCaseMonthAsInteger(TimeSpan timespan, bool isTimeUnitToGetTheMaximumTimeUnit) { - if (isTimeUnitToGetTheMaximumTimeUnit) - { - return (int)(timespan.Days / _daysInAMonth); - } - - var remainingDays = timespan.Days % _daysInAYear; - return (int)(remainingDays / _daysInAMonth); + if (isTimeUnitToGetTheMaximumTimeUnit) + { + return (int) (timespan.Days / _daysInAMonth); } + var remainingDays = timespan.Days % _daysInAYear; + return (int) (remainingDays / _daysInAMonth); + } + static int GetSpecialCaseYearAsInteger(TimeSpan timespan) => - (int)(timespan.Days / _daysInAYear); + (int) (timespan.Days / _daysInAYear); static int GetSpecialCaseWeeksAsInteger(TimeSpan timespan, bool isTimeUnitToGetTheMaximumTimeUnit) { - if (isTimeUnitToGetTheMaximumTimeUnit || timespan.Days < _daysInAMonth) - { - return timespan.Days / _daysInAWeek; - } - return 0; + if (isTimeUnitToGetTheMaximumTimeUnit || timespan.Days < _daysInAMonth) + { + return timespan.Days / _daysInAWeek; } + return 0; + } + static int GetSpecialCaseDaysAsInteger(TimeSpan timespan, TimeUnit maximumTimeUnit) { - if (maximumTimeUnit == TimeUnit.Day) - { - return timespan.Days; - } - if (timespan.Days < _daysInAMonth || maximumTimeUnit == TimeUnit.Week) - { - var remainingDays = timespan.Days % _daysInAWeek; - return remainingDays; - } - return (int)(timespan.Days % _daysInAMonth); + if (maximumTimeUnit == TimeUnit.Day) + { + return timespan.Days; + } + + if (timespan.Days < _daysInAMonth || maximumTimeUnit == TimeUnit.Week) + { + var remainingDays = timespan.Days % _daysInAWeek; + return remainingDays; } + return (int) (timespan.Days % _daysInAMonth); + } + static int GetNormalCaseTimeAsInteger(int timeNumberOfUnits, double totalTimeNumberOfUnits, bool isTimeUnitToGetTheMaximumTimeUnit) { - if (isTimeUnitToGetTheMaximumTimeUnit) + if (isTimeUnitToGetTheMaximumTimeUnit) + { + try + { + return (int) totalTimeNumberOfUnits; + } + catch { - try - { - return (int)totalTimeNumberOfUnits; - } - catch - { - //To be implemented so that TimeSpanHumanize method accepts double type as unit - return 0; - } + //To be implemented so that TimeSpanHumanize method accepts double type as unit + return 0; } - return timeNumberOfUnits; } + return timeNumberOfUnits; + } + static string? BuildFormatTimePart(IFormatter cultureFormatter, TimeUnit timeUnitType, int amountOfTimeUnits, bool toWords = false) => // Always use positive units to account for negative timespans amountOfTimeUnits != 0 @@ -189,27 +198,29 @@ static bool IsContainingOnlyNullValue(IEnumerable timeParts) => static IEnumerable SetPrecisionOfTimeSpan(IEnumerable timeParts, int precision, bool countEmptyUnits) { - if (!countEmptyUnits) - { - timeParts = timeParts.Where(x => x != null); - } - - timeParts = timeParts.Take(precision); - if (countEmptyUnits) - { - timeParts = timeParts.Where(x => x != null); - } + if (!countEmptyUnits) + { + timeParts = timeParts.Where(x => x != null); + } - return timeParts; + timeParts = timeParts.Take(precision); + if (countEmptyUnits) + { + timeParts = timeParts.Where(x => x != null); } + return timeParts; + } + static string ConcatenateTimeSpanParts(IEnumerable timeSpanParts, CultureInfo? culture, string? collectionSeparator) { - if (collectionSeparator == null) - { - return Configurator.CollectionFormatters.ResolveForCulture(culture).Humanize(timeSpanParts); - } - - return string.Join(collectionSeparator, timeSpanParts); + if (collectionSeparator == null) + { + return Configurator + .CollectionFormatters.ResolveForCulture(culture) + .Humanize(timeSpanParts); } + + return string.Join(collectionSeparator, timeSpanParts); + } } \ No newline at end of file diff --git a/src/Humanizer/ToQuantityExtensions.cs b/src/Humanizer/ToQuantityExtensions.cs index 11680a6a6..52b086556 100644 --- a/src/Humanizer/ToQuantityExtensions.cs +++ b/src/Humanizer/ToQuantityExtensions.cs @@ -62,23 +62,23 @@ public static string ToQuantity(this string input, long quantity, string? format static string ToQuantity(this string input, long quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric, string? format = null, IFormatProvider? formatProvider = null) { - var transformedInput = quantity == 1 - ? input.Singularize(inputIsKnownToBePlural: false) - : input.Pluralize(inputIsKnownToBeSingular: false); + var transformedInput = quantity == 1 + ? input.Singularize(inputIsKnownToBePlural: false) + : input.Pluralize(inputIsKnownToBeSingular: false); - if (showQuantityAs == ShowQuantityAs.None) - { - return transformedInput; - } - - if (showQuantityAs == ShowQuantityAs.Numeric) - { - return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); - } + if (showQuantityAs == ShowQuantityAs.None) + { + return transformedInput; + } - return $"{quantity.ToWords()} {transformedInput}"; + if (showQuantityAs == ShowQuantityAs.Numeric) + { + return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); } + return $"{quantity.ToWords()} {transformedInput}"; + } + /// /// Prefixes the provided word with the number and accordingly pluralizes or singularizes the word /// @@ -93,12 +93,12 @@ static string ToQuantity(this string input, long quantity, ShowQuantityAs showQu /// public static string ToQuantity(this string input, double quantity, string? format = null, IFormatProvider? formatProvider = null) { - var transformedInput = quantity == 1 - ? input.Singularize(inputIsKnownToBePlural: false) - : input.Pluralize(inputIsKnownToBeSingular: false); + var transformedInput = quantity == 1 + ? input.Singularize(inputIsKnownToBePlural: false) + : input.Pluralize(inputIsKnownToBeSingular: false); - return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); - } + return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); + } /// /// Prefixes the provided word with the number and accordingly pluralizes or singularizes the word diff --git a/src/Humanizer/Transformer/ToLowerCase.cs b/src/Humanizer/Transformer/ToLowerCase.cs index 3b7f7fb45..a7c5bc00a 100644 --- a/src/Humanizer/Transformer/ToLowerCase.cs +++ b/src/Humanizer/Transformer/ToLowerCase.cs @@ -7,8 +7,8 @@ public string Transform(string input) => public string Transform(string input, CultureInfo? culture) { - culture ??= CultureInfo.CurrentCulture; + culture ??= CultureInfo.CurrentCulture; - return culture.TextInfo.ToLower(input); - } + return culture.TextInfo.ToLower(input); + } } \ No newline at end of file diff --git a/src/Humanizer/Transformer/ToUpperCase.cs b/src/Humanizer/Transformer/ToUpperCase.cs index f91e7264c..0304e3766 100644 --- a/src/Humanizer/Transformer/ToUpperCase.cs +++ b/src/Humanizer/Transformer/ToUpperCase.cs @@ -7,8 +7,8 @@ public string Transform(string input) => public string Transform(string input, CultureInfo? culture) { - culture ??= CultureInfo.CurrentCulture; + culture ??= CultureInfo.CurrentCulture; - return culture.TextInfo.ToUpper(input); - } + return culture.TextInfo.ToUpper(input); + } } \ No newline at end of file diff --git a/src/Humanizer/TruncateExtensions.cs b/src/Humanizer/TruncateExtensions.cs index 31c782968..500f13dd0 100644 --- a/src/Humanizer/TruncateExtensions.cs +++ b/src/Humanizer/TruncateExtensions.cs @@ -51,31 +51,16 @@ public static class TruncateExtensions [return: NotNullIfNotNull(nameof(input))] public static string? Truncate(this string? input, int length, string? truncationString, ITruncator truncator, TruncateFrom from = TruncateFrom.Right) { - if (truncator == null) - { - throw new ArgumentNullException(nameof(truncator)); - } - - if (input == null) - { - return null; - } + if (truncator == null) + { + throw new ArgumentNullException(nameof(truncator)); + } - return truncator.Truncate(input, length, truncationString, from); + if (input == null) + { + return null; } -} -/// -/// Truncation location for humanizer -/// -public enum TruncateFrom -{ - /// - /// Truncate letters from the left (start) of the string - /// - Left, - /// - /// Truncate letters from the right (end) of the string - /// - Right + return truncator.Truncate(input, length, truncationString, from); + } } \ No newline at end of file diff --git a/src/Humanizer/TruncateFrom.cs b/src/Humanizer/TruncateFrom.cs new file mode 100644 index 000000000..61b52d498 --- /dev/null +++ b/src/Humanizer/TruncateFrom.cs @@ -0,0 +1,17 @@ +namespace Humanizer; + +/// +/// Truncation location for humanizer +/// +public enum TruncateFrom +{ + /// + /// Truncate letters from the left (start) of the string + /// + Left, + + /// + /// Truncate letters from the right (end) of the string + /// + Right +} \ No newline at end of file diff --git a/src/Humanizer/Truncation/FixedLengthTruncator.cs b/src/Humanizer/Truncation/FixedLengthTruncator.cs index d9707e420..cea07bd98 100644 --- a/src/Humanizer/Truncation/FixedLengthTruncator.cs +++ b/src/Humanizer/Truncation/FixedLengthTruncator.cs @@ -8,32 +8,32 @@ class FixedLengthTruncator : ITruncator [return: NotNullIfNotNull(nameof(value))] public string? Truncate(string? value, int length, string? truncationString, TruncateFrom truncateFrom = TruncateFrom.Right) { - if (value == null) - { - return null; - } - - if (value.Length == 0) - { - return value; - } + if (value == null) + { + return null; + } - if (truncationString == null || truncationString.Length > length) - { - return truncateFrom == TruncateFrom.Right - ? value.Substring(0, length) - : value.Substring(value.Length - length); - } + if (value.Length == 0) + { + return value; + } - if (truncateFrom == TruncateFrom.Left) - { - return value.Length > length - ? truncationString + value.Substring(value.Length - length + truncationString.Length) - : value; - } + if (truncationString == null || truncationString.Length > length) + { + return truncateFrom == TruncateFrom.Right + ? value.Substring(0, length) + : value.Substring(value.Length - length); + } + if (truncateFrom == TruncateFrom.Left) + { return value.Length > length - ? value.Substring(0, length - truncationString.Length) + truncationString + ? truncationString + value.Substring(value.Length - length + truncationString.Length) : value; } + + return value.Length > length + ? value.Substring(0, length - truncationString.Length) + truncationString + : value; + } } \ No newline at end of file diff --git a/src/Humanizer/Truncation/FixedNumberOfCharactersTruncator.cs b/src/Humanizer/Truncation/FixedNumberOfCharactersTruncator.cs index b3680102f..a53453094 100644 --- a/src/Humanizer/Truncation/FixedNumberOfCharactersTruncator.cs +++ b/src/Humanizer/Truncation/FixedNumberOfCharactersTruncator.cs @@ -8,47 +8,33 @@ class FixedNumberOfCharactersTruncator : ITruncator [return: NotNullIfNotNull(nameof(value))] public string? Truncate(string? value, int length, string? truncationString, TruncateFrom truncateFrom = TruncateFrom.Right) { - if (value == null) - { - return null; - } - - if (value.Length == 0) - { - return value; - } - - truncationString ??= string.Empty; + if (value == null) + { + return null; + } - if (truncationString.Length > length) - { - return truncateFrom == TruncateFrom.Right ? value.Substring(0, length) : value.Substring(value.Length - length); - } + if (value.Length == 0) + { + return value; + } - var alphaNumericalCharactersProcessed = 0; + truncationString ??= string.Empty; - if (value.Count(char.IsLetterOrDigit) <= length) - { - return value; - } + if (truncationString.Length > length) + { + return truncateFrom == TruncateFrom.Right ? value.Substring(0, length) : value.Substring(value.Length - length); + } - if (truncateFrom == TruncateFrom.Left) - { - for (var i = value.Length - 1; i > 0; i--) - { - if (char.IsLetterOrDigit(value[i])) - { - alphaNumericalCharactersProcessed++; - } + var alphaNumericalCharactersProcessed = 0; - if (alphaNumericalCharactersProcessed + truncationString.Length == length) - { - return truncationString + value.Substring(i); - } - } - } + if (value.Count(char.IsLetterOrDigit) <= length) + { + return value; + } - for (var i = 0; i < value.Length - truncationString.Length; i++) + if (truncateFrom == TruncateFrom.Left) + { + for (var i = value.Length - 1; i > 0; i--) { if (char.IsLetterOrDigit(value[i])) { @@ -57,10 +43,24 @@ class FixedNumberOfCharactersTruncator : ITruncator if (alphaNumericalCharactersProcessed + truncationString.Length == length) { - return value.Substring(0, i + 1) + truncationString; + return truncationString + value.Substring(i); } } + } + + for (var i = 0; i < value.Length - truncationString.Length; i++) + { + if (char.IsLetterOrDigit(value[i])) + { + alphaNumericalCharactersProcessed++; + } - return value; + if (alphaNumericalCharactersProcessed + truncationString.Length == length) + { + return value.Substring(0, i + 1) + truncationString; + } } + + return value; + } } \ No newline at end of file diff --git a/src/Humanizer/TupleizeExtensions.cs b/src/Humanizer/TupleizeExtensions.cs index f5256a7d8..e8fa0b1d1 100644 --- a/src/Humanizer/TupleizeExtensions.cs +++ b/src/Humanizer/TupleizeExtensions.cs @@ -15,34 +15,34 @@ public static class TupleizeExtensions /// Named tuple public static string Tupleize(this int input) { - switch (input) - { - case 1: - return "single"; - case 2: - return "double"; - case 3: - return "triple"; - case 4: - return "quadruple"; - case 5: - return "quintuple"; - case 6: - return "sextuple"; - case 7: - return "septuple"; - case 8: - return "octuple"; - case 9: - return "nonuple"; - case 10: - return "decuple"; - case 100: - return "centuple"; - case 1000: - return "milluple"; - default: - return $"{input}-tuple"; - } + switch (input) + { + case 1: + return "single"; + case 2: + return "double"; + case 3: + return "triple"; + case 4: + return "quadruple"; + case 5: + return "quintuple"; + case 6: + return "sextuple"; + case 7: + return "septuple"; + case 8: + return "octuple"; + case 9: + return "nonuple"; + case 10: + return "decuple"; + case 100: + return "centuple"; + case 1000: + return "milluple"; + default: + return $"{input}-tuple"; } + } } \ No newline at end of file