Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormat
}
else if (pt.PropertyName == OutputProperties.TimestampPropertyName)
{
renderers.Add(new TimestampTokenRenderer(theme, pt, formatProvider));
renderers.Add(new TimestampTokenRenderer(theme, pt, formatProvider, convertToUtc: false));
}
else if (pt.PropertyName == OutputProperties.UtcTimestampPropertyName)
{
renderers.Add(new TimestampTokenRenderer(theme, pt, formatProvider, convertToUtc: true));
}
else if (pt.PropertyName == OutputProperties.PropertiesPropertyName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ class TimestampTokenRenderer : OutputTemplateTokenRenderer
readonly ConsoleTheme _theme;
readonly PropertyToken _token;
readonly IFormatProvider? _formatProvider;
readonly bool _convertToUtc;

public TimestampTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider)
public TimestampTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider, bool convertToUtc)
{
_theme = theme;
_token = token;
_formatProvider = formatProvider;
}
_convertToUtc = convertToUtc;
}

public override void Render(LogEvent logEvent, TextWriter output)
{
var sv = new DateTimeOffsetValue(logEvent.Timestamp);
var timestamp = _convertToUtc
? logEvent.Timestamp.ToUniversalTime()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately DateTimeOffset ISO formatting in UTC renders as the unanticipated T00:00 rather than the more common and compact Z notation. You should be able to see this by running the code with {UtcTimestamp} and no format string.

MessageTemplateTextFormatter gets around this using .UtcDateTime and renders the value as a DateTime with DateTimeKind.Utc:

https://github.com/serilog/serilog/blob/dev/src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs#L107

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out, I'll have a look into that and will address it in an update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nblumhardt, the issue you pointed out is now addressed in the latest update. Rendering {UtcTimestamp} is now done as a DateTime.

: logEvent.Timestamp;
var sv = new DateTimeOffsetValue(timestamp);

var _ = 0;
using (_theme.Apply(output, ConsoleThemeStyle.SecondaryText, ref _))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,4 +400,28 @@ public void TraceAndSpanAreIncludedWhenPresent()
formatter.Format(evt, sw);
Assert.Equal($"{traceId}/{spanId}", sw.ToString());
}

[Fact]
public void TimestampTokenRendersLocalTime()
{
var logTimestampWithTimeZoneOffset = DateTimeOffset.Parse("2024-09-03T14:15:16.079+02:00", CultureInfo.InvariantCulture);
var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Timestamp:yyyy-MM-dd HH:mm:ss}", CultureInfo.InvariantCulture);
var evt = new LogEvent(logTimestampWithTimeZoneOffset, LogEventLevel.Information, null, MessageTemplate.Empty, Array.Empty<LogEventProperty>());
var sw = new StringWriter();
formatter.Format(evt, sw);
// expect time in local time, unchanged from the input, the +02:00 offset should not affect the output
Assert.Equal("2024-09-03 14:15:16", sw.ToString());
}

[Fact]
public void UtcTimestampTokenRendersUtcTime()
{
var logTimestampWithTimeZoneOffset = DateTimeOffset.Parse("2024-09-03T14:15:16.079+02:00", CultureInfo.InvariantCulture);
var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{UtcTimestamp:yyyy-MM-dd HH:mm:ss}", CultureInfo.InvariantCulture);
var evt = new LogEvent(logTimestampWithTimeZoneOffset, LogEventLevel.Information, null, MessageTemplate.Empty, Array.Empty<LogEventProperty>());
var sw = new StringWriter();
formatter.Format(evt, sw);
// expect time in UTC, the +02:00 offset must be applied to adjust the hour
Assert.Equal("2024-09-03 12:15:16", sw.ToString());
}
}