From 768f3553aba3e3692afd7dc946c7a81a4e2ad867 Mon Sep 17 00:00:00 2001 From: Drew Noakes Date: Thu, 8 Feb 2024 14:30:26 +1100 Subject: [PATCH] Show OLTP timestamps using user's time format preferences We want to show timestamps with millisecond-level precision, however there's no built-in format string for that that respects the user's preferences. Microsoft docs provided the approach taken here, which uses the user's default pattern (which comes from the machines culture and may be overridden by the user at the system level), and modifies it to append milliseconds after the seconds. It respects the user's preference for decimal separators too. --- .../Otlp/Model/OtlpHelpers.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Dashboard/Otlp/Model/OtlpHelpers.cs b/src/Aspire.Dashboard/Otlp/Model/OtlpHelpers.cs index 2cc54d6d054..001b6683ffd 100644 --- a/src/Aspire.Dashboard/Otlp/Model/OtlpHelpers.cs +++ b/src/Aspire.Dashboard/Otlp/Model/OtlpHelpers.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Runtime.CompilerServices; using System.Text; +using System.Text.RegularExpressions; using Aspire.Dashboard.Otlp.Storage; using Google.Protobuf; using Google.Protobuf.Collections; @@ -13,8 +14,27 @@ namespace Aspire.Dashboard.Otlp.Model; -public static class OtlpHelpers +public static partial class OtlpHelpers { + private static readonly string s_longTimePatternWithMilliseconds = GetLongTimePatternWithMilliseconds(); + + static string GetLongTimePatternWithMilliseconds() + { + // From https://learn.microsoft.com/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values + + // Gets the long time pattern, which is something like "h:mm:ss tt" (en-US), "H:mm:ss" (ja-JP), "HH:mm:ss" (fr-FR). + var longTimePattern = DateTimeFormatInfo.CurrentInfo.LongTimePattern; + + // Create a format similar to .fff but based on the current culture. + var millisecondFormat = $"{NumberFormatInfo.CurrentInfo.NumberDecimalSeparator}fff"; + + // Append millisecond pattern to current culture's long time pattern. + return MatchSecondsInTimeFormatPattern().Replace(longTimePattern, $"$1{millisecondFormat}"); + } + + [GeneratedRegex("(:ss|:s)")] + private static partial Regex MatchSecondsInTimeFormatPattern(); + public static string? GetServiceId(this Resource resource) { string? serviceName = null; @@ -44,7 +64,7 @@ public static string ToShortenedId(string id) => public static string FormatTimeStamp(DateTime timestamp) { - return timestamp.ToLocalTime().ToString("h:mm:ss.fff tt", CultureInfo.CurrentCulture); + return timestamp.ToLocalTime().ToString(s_longTimePatternWithMilliseconds, CultureInfo.CurrentCulture); } public static string ToHexString(ReadOnlyMemory bytes)