diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt
index 52553d968..df13478b9 100644
--- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt
+++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt
@@ -216,14 +216,16 @@ namespace Humanizer
public class DefaultFormatter : Humanizer.IFormatter
{
public DefaultFormatter(string localeCode) { }
+ protected System.Globalization.CultureInfo Culture { get; }
public virtual string DataUnitHumanize(Humanizer.DataUnit dataUnit, double count, bool toSymbol = true) { }
public virtual string DateHumanize(Humanizer.TimeUnit timeUnit, Humanizer.Tense timeUnitTense, int unit) { }
public virtual string DateHumanize_Never() { }
public virtual string DateHumanize_Now() { }
protected virtual string Format(string resourceKey) { }
- protected virtual string Format(string resourceKey, int number, bool toWords = false) { }
+ protected virtual string Format(Humanizer.TimeUnit unit, string resourceKey, int number, bool toWords = false) { }
protected virtual string GetResourceKey(string resourceKey) { }
protected virtual string GetResourceKey(string resourceKey, int number) { }
+ protected virtual string NumberToWords(Humanizer.TimeUnit unit, int number, System.Globalization.CultureInfo culture) { }
public virtual string TimeSpanHumanize(Humanizer.TimeUnit timeUnit, int unit, bool toWords = false) { }
public virtual string TimeSpanHumanize_Age() { }
public virtual string TimeSpanHumanize_Zero() { }
diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
index 90a3d038d..06213bab0 100644
--- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
+++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
@@ -201,14 +201,16 @@ namespace Humanizer
public class DefaultFormatter : Humanizer.IFormatter
{
public DefaultFormatter(string localeCode) { }
+ protected System.Globalization.CultureInfo Culture { get; }
public virtual string DataUnitHumanize(Humanizer.DataUnit dataUnit, double count, bool toSymbol = true) { }
public virtual string DateHumanize(Humanizer.TimeUnit timeUnit, Humanizer.Tense timeUnitTense, int unit) { }
public virtual string DateHumanize_Never() { }
public virtual string DateHumanize_Now() { }
protected virtual string Format(string resourceKey) { }
- protected virtual string Format(string resourceKey, int number, bool toWords = false) { }
+ protected virtual string Format(Humanizer.TimeUnit unit, string resourceKey, int number, bool toWords = false) { }
protected virtual string GetResourceKey(string resourceKey) { }
protected virtual string GetResourceKey(string resourceKey, int number) { }
+ protected virtual string NumberToWords(Humanizer.TimeUnit unit, int number, System.Globalization.CultureInfo culture) { }
public virtual string TimeSpanHumanize(Humanizer.TimeUnit timeUnit, int unit, bool toWords = false) { }
public virtual string TimeSpanHumanize_Age() { }
public virtual string TimeSpanHumanize_Zero() { }
diff --git a/src/Humanizer.Tests/Localisation/ru-RU/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/ru-RU/TimeSpanHumanizeTests.cs
index 6e58c8405..9f7ab9860 100644
--- a/src/Humanizer.Tests/Localisation/ru-RU/TimeSpanHumanizeTests.cs
+++ b/src/Humanizer.Tests/Localisation/ru-RU/TimeSpanHumanizeTests.cs
@@ -76,6 +76,7 @@ public void Hours(int hours, string expected, bool toWords = false) =>
[InlineData(19, "19 минут")]
[InlineData(20, "20 минут")]
[InlineData(21, "21 минута")]
+ [InlineData(21, "двадцать одна минута", true)]
[InlineData(22, "22 минуты")]
[InlineData(23, "23 минуты")]
[InlineData(24, "24 минуты")]
@@ -97,6 +98,7 @@ public void Minutes(int minutes, string expected, bool toWords = false) =>
[InlineData(19, "19 секунд")]
[InlineData(20, "20 секунд")]
[InlineData(21, "21 секунда")]
+ [InlineData(21, "двадцать одна секунда", true)]
[InlineData(22, "22 секунды")]
[InlineData(23, "23 секунды")]
[InlineData(24, "24 секунды")]
@@ -118,7 +120,9 @@ public void Seconds(int seconds, string expected, bool toWords = false) =>
[InlineData(19, "19 миллисекунд")]
[InlineData(20, "20 миллисекунд")]
[InlineData(21, "21 миллисекунда")]
+ [InlineData(21, "двадцать одна миллисекунда", true)]
[InlineData(22, "22 миллисекунды")]
+ [InlineData(22, "двадцать две миллисекунды", true)]
[InlineData(23, "23 миллисекунды")]
[InlineData(24, "24 миллисекунды")]
[InlineData(25, "25 миллисекунд")]
diff --git a/src/Humanizer.Tests/Localisation/uk-UA/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/uk-UA/TimeSpanHumanizeTests.cs
index 06f361b82..551a0ff72 100644
--- a/src/Humanizer.Tests/Localisation/uk-UA/TimeSpanHumanizeTests.cs
+++ b/src/Humanizer.Tests/Localisation/uk-UA/TimeSpanHumanizeTests.cs
@@ -5,44 +5,51 @@ public class TimeSpanHumanizeTests
{
[Theory]
[Trait("Translation", "Google")]
- [InlineData(366, "один рік")]
+ [InlineData(366, "один рік", true)]
+ [InlineData(366, "1 рік")]
[InlineData(731, "2 роки")]
[InlineData(1096, "3 роки")]
[InlineData(4018, "11 років")]
- public void Years(int days, string expected) =>
- Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year));
+ public void Years(int days, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year, toWords: toWords));
[Theory]
[Trait("Translation", "Google")]
- [InlineData(31, "один місяць")]
+ [InlineData(31, "один місяць", true)]
+ [InlineData(31, "1 місяць")]
[InlineData(61, "2 місяці")]
[InlineData(92, "3 місяці")]
[InlineData(335, "11 місяців")]
- public void Months(int days, string expected) =>
- Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year));
+ public void Months(int days, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(maxUnit: TimeUnit.Year, toWords: toWords));
[Theory]
- [InlineData(7, "один тиждень")]
+ [InlineData(7, "один тиждень", true)]
+ [InlineData(7, "1 тиждень")]
[InlineData(14, "2 тижні")]
[InlineData(21, "3 тижні")]
[InlineData(28, "4 тижні")]
[InlineData(35, "5 тижнів")]
[InlineData(77, "11 тижнів")]
- public void Weeks(int days, string expected) =>
- Assert.Equal(expected, TimeSpan.FromDays(days).Humanize());
+ [InlineData(147, "двадцять один тиждень", true)]
+ public void Weeks(int days, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(toWords: toWords));
[Theory]
- [InlineData(1, "один день")]
+ [InlineData(1, "один день", true)]
+ [InlineData(1, "1 день")]
[InlineData(2, "2 дні")]
[InlineData(3, "3 дні")]
[InlineData(4, "4 дні")]
[InlineData(5, "5 днів")]
[InlineData(6, "6 днів")]
- public void Days(int days, string expected) =>
- Assert.Equal(expected, TimeSpan.FromDays(days).Humanize());
+ [InlineData(21, "двадцять один день", true)]
+ public void Days(int days, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromDays(days).Humanize(toWords: toWords, maxUnit: TimeUnit.Day));
[Theory]
- [InlineData(1, "одна година")]
+ [InlineData(1, "одна година", true)]
+ [InlineData(1, "1 година")]
[InlineData(2, "2 години")]
[InlineData(3, "3 години")]
[InlineData(4, "4 години")]
@@ -53,13 +60,15 @@ public void Days(int days, string expected) =>
[InlineData(19, "19 годин")]
[InlineData(20, "20 годин")]
[InlineData(21, "21 година")]
+ [InlineData(21, "двадцять одна година", true)]
[InlineData(22, "22 години")]
[InlineData(23, "23 години")]
- public void Hours(int hours, string expected) =>
- Assert.Equal(expected, TimeSpan.FromHours(hours).Humanize());
+ public void Hours(int hours, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromHours(hours).Humanize(toWords: toWords));
[Theory]
- [InlineData(1, "одна хвилина")]
+ [InlineData(1, "одна хвилина",true)]
+ [InlineData(1, "1 хвилина")]
[InlineData(2, "2 хвилини")]
[InlineData(3, "3 хвилини")]
[InlineData(4, "4 хвилини")]
@@ -70,16 +79,18 @@ public void Hours(int hours, string expected) =>
[InlineData(19, "19 хвилин")]
[InlineData(20, "20 хвилин")]
[InlineData(21, "21 хвилина")]
+ [InlineData(21, "двадцять одна хвилина", true)]
[InlineData(22, "22 хвилини")]
[InlineData(23, "23 хвилини")]
[InlineData(24, "24 хвилини")]
[InlineData(25, "25 хвилин")]
[InlineData(40, "40 хвилин")]
- public void Minutes(int minutes, string expected) =>
- Assert.Equal(expected, TimeSpan.FromMinutes(minutes).Humanize());
+ public void Minutes(int minutes, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromMinutes(minutes).Humanize(toWords: toWords));
[Theory]
- [InlineData(1, "одна секунда")]
+ [InlineData(1, "одна секунда", true)]
+ [InlineData(1, "1 секунда")]
[InlineData(2, "2 секунди")]
[InlineData(3, "3 секунди")]
[InlineData(4, "4 секунди")]
@@ -90,16 +101,18 @@ public void Minutes(int minutes, string expected) =>
[InlineData(19, "19 секунд")]
[InlineData(20, "20 секунд")]
[InlineData(21, "21 секунда")]
+ [InlineData(21, "двадцять одна секунда", true)]
[InlineData(22, "22 секунди")]
[InlineData(23, "23 секунди")]
[InlineData(24, "24 секунди")]
[InlineData(25, "25 секунд")]
[InlineData(40, "40 секунд")]
- public void Seconds(int seconds, string expected) =>
- Assert.Equal(expected, TimeSpan.FromSeconds(seconds).Humanize());
+ public void Seconds(int seconds, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromSeconds(seconds).Humanize(toWords: toWords));
[Theory]
- [InlineData(1, "одна мілісекунда")]
+ [InlineData(1, "одна мілісекунда", true)]
+ [InlineData(1, "1 мілісекунда")]
[InlineData(2, "2 мілісекунди")]
[InlineData(3, "3 мілісекунди")]
[InlineData(4, "4 мілісекунди")]
@@ -110,13 +123,14 @@ public void Seconds(int seconds, string expected) =>
[InlineData(19, "19 мілісекунд")]
[InlineData(20, "20 мілісекунд")]
[InlineData(21, "21 мілісекунда")]
+ [InlineData(21, "двадцять одна мілісекунда", true)]
[InlineData(22, "22 мілісекунди")]
[InlineData(23, "23 мілісекунди")]
[InlineData(24, "24 мілісекунди")]
[InlineData(25, "25 мілісекунд")]
[InlineData(40, "40 мілісекунд")]
- public void Milliseconds(int milliseconds, string expected) =>
- Assert.Equal(expected, TimeSpan.FromMilliseconds(milliseconds).Humanize());
+ public void Milliseconds(int milliseconds, string expected, bool toWords = false) =>
+ Assert.Equal(expected, TimeSpan.FromMilliseconds(milliseconds).Humanize(toWords: toWords));
[Fact]
public void NoTime() =>
diff --git a/src/Humanizer.Tests/Localisation/vi/NumberToWordsTests.cs b/src/Humanizer.Tests/Localisation/vi/NumberToWordsTests.cs
index 18699a039..bb4d4bef6 100644
--- a/src/Humanizer.Tests/Localisation/vi/NumberToWordsTests.cs
+++ b/src/Humanizer.Tests/Localisation/vi/NumberToWordsTests.cs
@@ -1,4 +1,4 @@
-namespace Humanizer.Tests.vi;
+namespace Humanizer.Tests.Localisation.vi;
[UseCulture("vi")]
public class NumberToWordsTests
diff --git a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
index 2c1df2c01..344b3bd53 100644
--- a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
@@ -5,11 +5,11 @@
///
public class DefaultFormatter : IFormatter
{
- readonly CultureInfo _culture;
+ protected CultureInfo Culture { get; }
/// Name of the culture to use.
public DefaultFormatter(string localeCode) =>
- _culture = new(localeCode);
+ Culture = new(localeCode);
public virtual string DateHumanize_Now() =>
GetResourceForDate(TimeUnit.Millisecond, Tense.Past, 0);
@@ -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(unit, 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(unit, resourceKey, count, toWords);
+ }
///
/// Formats the specified resource key.
@@ -84,28 +84,28 @@ 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.
///
+ ///
/// The resource key.
/// The number.
+ ///
/// If the resource not exists on the specified culture.
- protected virtual string Format(string resourceKey, int number, bool toWords = false)
+ protected virtual string Format(TimeUnit unit, 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, toWords ? NumberToWords(unit, number, Culture) : number.ToString(Culture));
+ }
- return string.Format(resourceString, number);
- }
+ protected virtual string NumberToWords(TimeUnit unit, int number, CultureInfo culture) =>
+ number.ToWords(culture);
///
/// Override this method if your locale has complex rules around multiple units; e.g. Arabic, Russian
diff --git a/src/Humanizer/Localisation/Formatters/IcelandicFormatter.cs b/src/Humanizer/Localisation/Formatters/IcelandicFormatter.cs
index d6210f371..e10536554 100644
--- a/src/Humanizer/Localisation/Formatters/IcelandicFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/IcelandicFormatter.cs
@@ -1,40 +1,19 @@
namespace Humanizer;
class IcelandicFormatter() :
- DefaultFormatter(LocaleCode)
+ DefaultFormatter("is")
{
- const string LocaleCode = "is";
- readonly CultureInfo localCulture = new(LocaleCode);
-
public override string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true) =>
base.DataUnitHumanize(dataUnit, count, toSymbol).TrimEnd('s');
- protected override string Format(string resourceKey, int number, bool toWords = false)
- {
- var resourceString = Resources.GetResource(GetResourceKey(resourceKey, number), localCulture);
-
- if (toWords)
- {
- var unitGender = GetGrammaticalGender(resourceString);
- return string.Format(resourceString, number.ToWords(unitGender, localCulture));
- }
-
- return string.Format(resourceString, number);
- }
+ protected override string NumberToWords(TimeUnit unit, int number, CultureInfo culture) =>
+ number.ToWords(GetUnitGender(unit), culture);
- static GrammaticalGender GetGrammaticalGender(string resource)
- {
- if (resource.Contains(" mán") ||
- resource.Contains(" dag"))
+ static GrammaticalGender GetUnitGender(TimeUnit unit) =>
+ unit switch
{
- return GrammaticalGender.Masculine;
- }
-
- if (resource.Contains(" ár"))
- {
- return GrammaticalGender.Neuter;
- }
-
- return GrammaticalGender.Feminine;
- }
+ TimeUnit.Day or TimeUnit.Month => GrammaticalGender.Masculine,
+ TimeUnit.Year => GrammaticalGender.Neuter,
+ _ => GrammaticalGender.Feminine
+ };
}
\ No newline at end of file
diff --git a/src/Humanizer/Localisation/Formatters/LuxembourgishFormatter.cs b/src/Humanizer/Localisation/Formatters/LuxembourgishFormatter.cs
index f234f7a8e..cd1e4682a 100644
--- a/src/Humanizer/Localisation/Formatters/LuxembourgishFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/LuxembourgishFormatter.cs
@@ -1,11 +1,10 @@
namespace Humanizer;
class LuxembourgishFormatter() :
- DefaultFormatter(LocaleCode)
+ DefaultFormatter("lb")
{
- const string LocaleCode = "lb";
- readonly CultureInfo localCulture = new(LocaleCode);
const string DualPostfix = "_Dual";
+
// https://lb.wikipedia.org/wiki/Eifeler_Reegel
const char EifelerRuleSuffix = 'n';
const string EifelerRuleCharacters = "unitedzohay";
@@ -25,30 +24,14 @@ public static bool DoesEifelerRuleApply(string nextWord)
=> !string.IsNullOrWhiteSpace(nextWord)
&& !EifelerRuleCharacters.Contains(nextWord[0]);
- protected override string Format(string resourceKey, int number, bool toWords = false)
+ protected override string Format(TimeUnit unit, string resourceKey, int number, bool toWords = false)
{
- var resourceString = Resources.GetResource(GetResourceKey(resourceKey, number), localCulture);
-
- var unitGender = GetUnitGender(resourceString);
-
- var numberAsWord = number.ToWords(unitGender, localCulture);
-
- if (DoesEifelerRuleApply(numberAsWord))
- {
- if (toWords)
- {
- return string.Format(resourceString, numberAsWord, string.Empty);
- }
-
- return string.Format(resourceString, number, string.Empty);
- }
+ var resourceString = Resources.GetResource(GetResourceKey(resourceKey, number), Culture);
+ var numberAsWord = number.ToWords(GetUnitGender(unit), Culture);
- if (toWords)
- {
- return string.Format(resourceString, numberAsWord, EifelerRuleSuffix);
- }
-
- return string.Format(resourceString, number, EifelerRuleSuffix);
+ return string.Format(resourceString,
+ toWords ? numberAsWord : number,
+ DoesEifelerRuleApply(numberAsWord) ? "" : EifelerRuleSuffix);
}
protected override string GetResourceKey(string resourceKey, int number)
@@ -62,17 +45,10 @@ protected override string GetResourceKey(string resourceKey, int number)
return resourceKey;
}
- static GrammaticalGender GetUnitGender(string resourceString)
- {
- if (resourceString.EndsWith(" Millisekonnen") ||
- resourceString.EndsWith(" Sekonnen") ||
- resourceString.EndsWith(" Minutten") ||
- resourceString.EndsWith(" Stonnen") ||
- resourceString.EndsWith(" Wochen"))
+ static GrammaticalGender GetUnitGender(TimeUnit unit) =>
+ unit switch
{
- return GrammaticalGender.Feminine;
- }
-
- return GrammaticalGender.Masculine;
- }
+ TimeUnit.Day or TimeUnit.Month or TimeUnit.Year => GrammaticalGender.Masculine,
+ _ => GrammaticalGender.Feminine
+ };
}
diff --git a/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs b/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs
index efa29fe31..774593842 100644
--- a/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs
@@ -1,21 +1,18 @@
namespace Humanizer;
class RomanianFormatter() :
- DefaultFormatter(RomanianCultureCode)
+ DefaultFormatter("ro")
{
const int PrepositionIndicatingDecimals = 2;
const int MaxNumeralWithNoPreposition = 19;
const int MinNumeralWithNoPreposition = 1;
const string UnitPreposition = " de";
- const string RomanianCultureCode = "ro";
static readonly double Divider = Math.Pow(10, PrepositionIndicatingDecimals);
- readonly CultureInfo _romanianCulture = new(RomanianCultureCode);
-
- protected override string Format(string resourceKey, int number, bool toWords = false)
+ protected override string Format(TimeUnit unit, string resourceKey, int number, bool toWords = false)
{
- var format = Resources.GetResource(GetResourceKey(resourceKey, number), _romanianCulture);
+ var format = Resources.GetResource(GetResourceKey(resourceKey, number), Culture);
var preposition = ShouldUsePreposition(number)
? UnitPreposition
: string.Empty;
diff --git a/src/Humanizer/Localisation/Formatters/RussianFormatter.cs b/src/Humanizer/Localisation/Formatters/RussianFormatter.cs
index 8e0d75117..5b81b125b 100644
--- a/src/Humanizer/Localisation/Formatters/RussianFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/RussianFormatter.cs
@@ -5,23 +5,26 @@ 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";
- }
+ protected override string NumberToWords(TimeUnit unit, int number, CultureInfo culture) =>
+ number.ToWords(GetUnitGender(unit), culture);
- if (grammaticalNumber == RussianGrammaticalNumber.Paucal)
- {
- return "_Paucal";
- }
+ static string GetSuffix(RussianGrammaticalNumber grammaticalNumber) =>
+ grammaticalNumber switch
+ {
+ RussianGrammaticalNumber.Singular => "_Singular",
+ RussianGrammaticalNumber.Paucal => "_Paucal",
+ _ => ""
+ };
- return "";
- }
+ static GrammaticalGender GetUnitGender(TimeUnit unit) =>
+ unit switch
+ {
+ TimeUnit.Hour or TimeUnit.Day or TimeUnit.Month or TimeUnit.Year => GrammaticalGender.Masculine,
+ _ => GrammaticalGender.Feminine
+ };
}
\ No newline at end of file
diff --git a/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs b/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs
index ab7da5176..ad28a1058 100644
--- a/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs
+++ b/src/Humanizer/Localisation/Formatters/UkrainianFormatter.cs
@@ -4,23 +4,26 @@ 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";
- }
+ protected override string NumberToWords(TimeUnit unit, int number, CultureInfo culture) =>
+ number.ToWords(GetUnitGender(unit), culture);
- if (grammaticalNumber == RussianGrammaticalNumber.Paucal)
- {
- return "_Paucal";
- }
+ static string GetSuffix(RussianGrammaticalNumber grammaticalNumber) =>
+ grammaticalNumber switch
+ {
+ RussianGrammaticalNumber.Singular => "_Singular",
+ RussianGrammaticalNumber.Paucal => "_Paucal",
+ _ => ""
+ };
- return "";
- }
+ static GrammaticalGender GetUnitGender(TimeUnit unit) =>
+ unit switch
+ {
+ TimeUnit.Day or TimeUnit.Week or TimeUnit.Month or TimeUnit.Year => GrammaticalGender.Masculine,
+ _ => GrammaticalGender.Feminine
+ };
}
\ No newline at end of file
diff --git a/src/Humanizer/Properties/Resources.uk.resx b/src/Humanizer/Properties/Resources.uk.resx
index 1147b8176..b608ae002 100644
--- a/src/Humanizer/Properties/Resources.uk.resx
+++ b/src/Humanizer/Properties/Resources.uk.resx
@@ -247,22 +247,22 @@
{0} тиждень
- один день
+ 1 день
- одна година
+ 1 година
- одна мілісекунда
+ 1 мілісекунда
- одна хвилина
+ 1 хвилина
- одна секунда
+ 1 секунда
- один тиждень
+ 1 тиждень
без часу
@@ -358,9 +358,33 @@
{0} рік
- один місяць
+ 1 місяць
+ 1 рік
+
+
+ один день
+
+
+ одна година
+
+
+ одна мілісекунда
+
+
+ одна хвилина
+
+
+ один місяць
+
+
+ одна секунда
+
+
+ один тиждень
+
+
один рік
\ No newline at end of file