diff --git a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor
index 3ee9dd98595..d4b99467754 100644
--- a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor
+++ b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor
@@ -32,6 +32,17 @@
@Loc[nameof(Dialogs.SettingsDialogDashboardLogsAndTelemetry)]
diff --git a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs
index 462ab86dcb7..ae71402a233 100644
--- a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs
+++ b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs
@@ -15,6 +15,7 @@ public partial class SettingsDialog : IDialogContentComponent, IDisposable
private string? _currentSetting;
private List _languageOptions = null!;
private CultureInfo? _selectedUiCulture;
+ private TimeFormat _timeFormat;
private IDisposable? _themeChangedSubscription;
@@ -30,6 +31,12 @@ public partial class SettingsDialog : IDialogContentComponent, IDisposable
[Inject]
public required DashboardDialogService DialogService { get; init; }
+ [Inject]
+ public required BrowserTimeProvider TimeProvider { get; init; }
+
+ [Inject]
+ public required ILocalStorage LocalStorage { get; init; }
+
protected override void OnInitialized()
{
_languageOptions = GlobalizationHelpers.OrderedLocalizedCultures;
@@ -39,6 +46,8 @@ protected override void OnInitialized()
// Otherwise, Blazor has fallen back to a supported language
CultureInfo.CurrentUICulture;
+ _timeFormat = TimeProvider.TimeFormat;
+
_currentSetting = ThemeManager.SelectedTheme ?? ThemeManager.ThemeSettingSystem;
// Handle value being changed in a different browser window.
@@ -99,6 +108,26 @@ private async Task LaunchManageDataAsync()
await DialogService.ShowDialogAsync(parameters);
}
+ private async Task OnTimeFormatChanged()
+ {
+ TimeProvider.SetTimeFormat(_timeFormat);
+ await LocalStorage.SetAsync(BrowserStorageKeys.TimeFormat, _timeFormat);
+
+ // Reload the page to ensure all components pick up the new format
+ var uri = new Uri(NavigationManager.Uri)
+ .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
+
+ NavigationManager.NavigateTo(uri, forceLoad: true);
+ }
+
+ private string FormatTimeFormatOption(TimeFormat format) => format switch
+ {
+ TimeFormat.System => Loc[nameof(Dashboard.Resources.Dialogs.SettingsDialogTimeFormatSystem)],
+ TimeFormat.TwelveHour => Loc[nameof(Dashboard.Resources.Dialogs.SettingsDialogTimeFormatTwelveHour)],
+ TimeFormat.TwentyFourHour => Loc[nameof(Dashboard.Resources.Dialogs.SettingsDialogTimeFormatTwentyFourHour)],
+ _ => format.ToString()
+ };
+
public void Dispose()
{
_themeChangedSubscription?.Dispose();
diff --git a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs
index 6c1596b2f27..3b1f1e06c7d 100644
--- a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs
+++ b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs
@@ -114,6 +114,12 @@ protected override async Task OnInitializedAsync()
TimeProvider.SetBrowserTimeZone(result.TimeZone);
TelemetryContextProvider.SetBrowserUserAgent(result.UserAgent);
+ var timeFormatResult = await LocalStorage.GetAsync(BrowserStorageKeys.TimeFormat);
+ if (timeFormatResult.Success)
+ {
+ TimeProvider.SetTimeFormat(timeFormatResult.Value);
+ }
+
await DisplayUnsecuredEndpointsMessageAsync();
_aiDisplayChangedSubscription = AIContextProvider.OnDisplayChanged(() => InvokeAsync(StateHasChanged));
diff --git a/src/Aspire.Dashboard/Model/BrowserTimeProvider.cs b/src/Aspire.Dashboard/Model/BrowserTimeProvider.cs
index 3d83dc69a4e..95708109b37 100644
--- a/src/Aspire.Dashboard/Model/BrowserTimeProvider.cs
+++ b/src/Aspire.Dashboard/Model/BrowserTimeProvider.cs
@@ -36,4 +36,18 @@ public void SetBrowserTimeZone(string? timeZone)
_logger.LogDebug("Browser time zone set to '{TimeZone}' with UTC offset {UtcOffset}.", timeZoneInfo.Id, timeZoneInfo.BaseUtcOffset);
_browserLocalTimeZone = timeZoneInfo;
}
+
+ public TimeFormat TimeFormat { get; private set; } = TimeFormat.System;
+
+ public void SetTimeFormat(TimeFormat timeFormat)
+ {
+ TimeFormat = timeFormat;
+ }
+}
+
+public enum TimeFormat
+{
+ System,
+ TwelveHour,
+ TwentyFourHour
}
diff --git a/src/Aspire.Dashboard/Resources/Dialogs.Designer.cs b/src/Aspire.Dashboard/Resources/Dialogs.Designer.cs
index 0ee1cff92b4..3aaace5c0dd 100644
--- a/src/Aspire.Dashboard/Resources/Dialogs.Designer.cs
+++ b/src/Aspire.Dashboard/Resources/Dialogs.Designer.cs
@@ -1319,5 +1319,41 @@ public static string TextVisualizerSelectFormatType {
return ResourceManager.GetString("TextVisualizerSelectFormatType", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Time Format.
+ ///
+ public static string SettingsDialogTimeFormat {
+ get {
+ return ResourceManager.GetString("SettingsDialogTimeFormat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to System.
+ ///
+ public static string SettingsDialogTimeFormatSystem {
+ get {
+ return ResourceManager.GetString("SettingsDialogTimeFormatSystem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to 12-Hour.
+ ///
+ public static string SettingsDialogTimeFormatTwelveHour {
+ get {
+ return ResourceManager.GetString("SettingsDialogTimeFormatTwelveHour", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to 24-Hour.
+ ///
+ public static string SettingsDialogTimeFormatTwentyFourHour {
+ get {
+ return ResourceManager.GetString("SettingsDialogTimeFormatTwentyFourHour", resourceCulture);
+ }
+ }
}
}
diff --git a/src/Aspire.Dashboard/Resources/Dialogs.resx b/src/Aspire.Dashboard/Resources/Dialogs.resx
index 80a7776df81..09a3caf7858 100644
--- a/src/Aspire.Dashboard/Resources/Dialogs.resx
+++ b/src/Aspire.Dashboard/Resources/Dialogs.resx
@@ -549,4 +549,16 @@
Resource
-
\ No newline at end of file
+
+ Time Format
+
+
+ System
+
+
+ 12-Hour
+
+
+ 24-Hour
+
+
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.cs.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.cs.xlf
index d405f9616c0..9b63ca53105 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.cs.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.cs.xlf
@@ -637,6 +637,26 @@
Motiv
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Verze: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.de.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.de.xlf
index b696edbf67d..81cddebbbd9 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.de.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.de.xlf
@@ -637,6 +637,26 @@
Design
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Version: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.es.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.es.xlf
index a9ad0f95f72..0127ae379bc 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.es.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.es.xlf
@@ -637,6 +637,26 @@
Tema
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Versión: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.fr.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.fr.xlf
index 70cc79009dd..62452687af1 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.fr.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.fr.xlf
@@ -637,6 +637,26 @@
Thème
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Version : {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.it.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.it.xlf
index 96b22cb7817..38577055853 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.it.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.it.xlf
@@ -637,6 +637,26 @@
Tema
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Versione: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ja.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ja.xlf
index c2cb7186279..629006a204b 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ja.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ja.xlf
@@ -637,6 +637,26 @@
テーマ
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
バージョン: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ko.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ko.xlf
index 0039de13b5f..ce5eb0cb86f 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ko.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ko.xlf
@@ -637,6 +637,26 @@
테마
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
버전: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.pl.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.pl.xlf
index 3bfdefa21bb..65c51881558 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.pl.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.pl.xlf
@@ -637,6 +637,26 @@
Motyw
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Wersja: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.pt-BR.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.pt-BR.xlf
index 4c7da7dc54b..1d2626fa9ad 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.pt-BR.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.pt-BR.xlf
@@ -637,6 +637,26 @@
Tema
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Versão: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ru.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ru.xlf
index c04f210898e..e72914db7b9 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.ru.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.ru.xlf
@@ -637,6 +637,26 @@
Тема
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Версия: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.tr.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.tr.xlf
index 49099dbd949..51a150fc19d 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.tr.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.tr.xlf
@@ -637,6 +637,26 @@
Tema
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
Sürüm: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hans.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hans.xlf
index 97ee9fa4326..022ef1b2187 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hans.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hans.xlf
@@ -637,6 +637,26 @@
主题
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
版本: {0}
diff --git a/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hant.xlf b/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hant.xlf
index d70ecedcfbd..80e2940b02e 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hant.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Dialogs.zh-Hant.xlf
@@ -637,6 +637,26 @@
佈景主題
+
+ Time Format
+ Time Format
+
+
+
+ System
+ System
+
+
+
+ 12-Hour
+ 12-Hour
+
+
+
+ 24-Hour
+ 24-Hour
+
+
Version: {0}
版本: {0}
diff --git a/src/Aspire.Dashboard/Utils/BrowserStorageKeys.cs b/src/Aspire.Dashboard/Utils/BrowserStorageKeys.cs
index 640a0a82e7f..1be06837add 100644
--- a/src/Aspire.Dashboard/Utils/BrowserStorageKeys.cs
+++ b/src/Aspire.Dashboard/Utils/BrowserStorageKeys.cs
@@ -10,6 +10,7 @@ internal static class BrowserStorageKeys
{
public const string UnsecuredTelemetryMessageDismissedKey = "Aspire_Telemetry_UnsecuredMessageDismissed";
public const string UnsecuredEndpointMessageDismissedKey = "Aspire_Security_UnsecuredEndpointMessageDismissed";
+ public const string TimeFormat = "Aspire_TimeFormat";
public const string TracesPageState = "Aspire_PageState_Traces";
public const string StructuredLogsPageState = "Aspire_PageState_StructuredLogs";
diff --git a/src/Aspire.Dashboard/Utils/FormatHelpers.cs b/src/Aspire.Dashboard/Utils/FormatHelpers.cs
index ee3c313492d..d81fc4db5c9 100644
--- a/src/Aspire.Dashboard/Utils/FormatHelpers.cs
+++ b/src/Aspire.Dashboard/Utils/FormatHelpers.cs
@@ -81,6 +81,11 @@ public static string FormatTime(BrowserTimeProvider timeProvider, DateTime value
cultureInfo ??= CultureInfo.CurrentCulture;
var local = timeProvider.ToLocal(value);
+ if (timeProvider.TimeFormat != TimeFormat.System)
+ {
+ return local.ToString(GetForcedTimePattern(timeProvider.TimeFormat, millisecondsDisplay, cultureInfo), cultureInfo);
+ }
+
// Long time
return millisecondsDisplay switch
{
@@ -96,6 +101,12 @@ public static string FormatDateTime(BrowserTimeProvider timeProvider, DateTime v
cultureInfo ??= CultureInfo.CurrentCulture;
var local = timeProvider.ToLocal(value);
+ if (timeProvider.TimeFormat != TimeFormat.System)
+ {
+ var timePattern = GetForcedTimePattern(timeProvider.TimeFormat, millisecondsDisplay, cultureInfo);
+ return local.ToString($"{cultureInfo.DateTimeFormat.ShortDatePattern} {timePattern}", cultureInfo);
+ }
+
// Short date, long time
return millisecondsDisplay switch
{
@@ -158,4 +169,25 @@ public static string CombineWithSeparator(string separator, params string?[] par
{
return string.Join(separator, parts.Where(p => !string.IsNullOrEmpty(p)));
}
+
+ private static string GetForcedTimePattern(TimeFormat timeFormat, MillisecondsDisplay millisecondsDisplay, CultureInfo cultureInfo)
+ {
+ var timeSeparator = cultureInfo.DateTimeFormat.TimeSeparator;
+ var decimalSeparator = cultureInfo.NumberFormat.NumberDecimalSeparator;
+
+ var secondsPattern = millisecondsDisplay switch
+ {
+ MillisecondsDisplay.None => "ss",
+ MillisecondsDisplay.Truncated => $"ss'{decimalSeparator}'fff",
+ MillisecondsDisplay.Full => $"ss'{decimalSeparator}'FFFFFFF",
+ _ => throw new NotImplementedException()
+ };
+
+ return timeFormat switch
+ {
+ TimeFormat.TwelveHour => $"h'{timeSeparator}'mm'{timeSeparator}'{secondsPattern} tt",
+ TimeFormat.TwentyFourHour => $"H'{timeSeparator}'mm'{timeSeparator}'{secondsPattern}",
+ _ => throw new NotImplementedException()
+ };
+ }
}
diff --git a/tests/Aspire.Dashboard.Tests/FormatHelpersTests.cs b/tests/Aspire.Dashboard.Tests/FormatHelpersTests.cs
index 0851d1f6aa1..8db56df0f44 100644
--- a/tests/Aspire.Dashboard.Tests/FormatHelpersTests.cs
+++ b/tests/Aspire.Dashboard.Tests/FormatHelpersTests.cs
@@ -100,6 +100,74 @@ private static DateTime GetLocalDateTime(string value)
return date;
}
+ [Theory]
+ [InlineData("2009-06-15T13:45:30.0000000Z", TimeFormat.TwelveHour, "1:45:30 PM")]
+ [InlineData("2009-06-15T13:45:30.0000000Z", TimeFormat.TwentyFourHour, "13:45:30")]
+ public void FormatTime_WithTimeFormatPreference(string value, TimeFormat format, string expected)
+ {
+ var date = GetLocalDateTime(value);
+ var provider = CreateTimeProvider();
+ provider.SetTimeFormat(format);
+
+ // Use a culture that would normally be opposite
+ var culture = format == TimeFormat.TwelveHour ? CultureInfo.GetCultureInfo("de-DE") : CultureInfo.GetCultureInfo("en-US");
+
+ Assert.Equal(expected, FormatHelpers.FormatTime(provider, date, MillisecondsDisplay.None, culture));
+ }
+
+ [Theory]
+ [InlineData("2009-06-15T13:45:30.0000000Z", TimeFormat.TwelveHour, "6/15/2009 1:45:30 PM")] // en-US date pattern + 12h time
+ [InlineData("2009-06-15T13:45:30.0000000Z", TimeFormat.TwentyFourHour, "6/15/2009 13:45:30")] // en-US date pattern + 24h time
+ public void FormatDateTime_WithTimeFormatPreference_EnUS(string value, TimeFormat format, string expected)
+ {
+ var date = GetLocalDateTime(value);
+ var provider = CreateTimeProvider();
+ provider.SetTimeFormat(format);
+
+ Assert.Equal(expected, FormatHelpers.FormatDateTime(provider, date, MillisecondsDisplay.None, CultureInfo.GetCultureInfo("en-US")));
+ }
+
+ [Theory]
+ [InlineData("fi-FI", TimeFormat.TwentyFourHour, MillisecondsDisplay.None, "15.6.2009 13.45.30")]
+ [InlineData("fi-FI", TimeFormat.TwentyFourHour, MillisecondsDisplay.Truncated, "15.6.2009 13.45.30,123")]
+ [InlineData("de-DE", TimeFormat.TwentyFourHour, MillisecondsDisplay.Truncated, "15.06.2009 13:45:30,123")]
+ [InlineData("en-US", TimeFormat.TwelveHour, MillisecondsDisplay.Truncated, "6/15/2009 1:45:30.123 PM")]
+ public void FormatDateTime_WithTimeFormatPreference_UsesCultureSeparators(string cultureName, TimeFormat format, MillisecondsDisplay includeMilliseconds, string expected)
+ {
+ var date = GetLocalDateTime("2009-06-15T13:45:30.1234567Z");
+ var provider = CreateTimeProvider();
+ provider.SetTimeFormat(format);
+
+ Assert.Equal(expected, FormatHelpers.FormatDateTime(provider, date, includeMilliseconds, CultureInfo.GetCultureInfo(cultureName)));
+ }
+
+ [Fact]
+ public void FormatTime_TwelveHour_UsesAmPm_EvenIfCultureIs24Hour()
+ {
+ // en-GB is typically 24-hour.
+ var date = GetLocalDateTime("2009-06-15T13:45:30.0000000Z");
+ var provider = CreateTimeProvider();
+ provider.SetTimeFormat(TimeFormat.TwelveHour);
+
+ // en-GB has AM/PM designators "am"/"pm" even if standard pattern is 24h.
+ var result = FormatHelpers.FormatTime(provider, date, MillisecondsDisplay.None, CultureInfo.GetCultureInfo("en-GB"));
+ Assert.Contains("pm", result.ToLowerInvariant());
+ Assert.DoesNotContain("13", result);
+ }
+
+ [Fact]
+ public void FormatTime_TwentyFourHour_Uses13_EvenIfCultureIs12Hour()
+ {
+ // en-US is typically 12-hour.
+ var date = GetLocalDateTime("2009-06-15T13:45:30.0000000Z");
+ var provider = CreateTimeProvider();
+ provider.SetTimeFormat(TimeFormat.TwentyFourHour);
+
+ var result = FormatHelpers.FormatTime(provider, date, MillisecondsDisplay.None, CultureInfo.GetCultureInfo("en-US"));
+ Assert.Contains("13", result);
+ Assert.DoesNotContain("PM", result);
+ }
+
private static BrowserTimeProvider CreateTimeProvider()
{
return new BrowserTimeProvider(NullLoggerFactory.Instance);