Skip to content

Use internationally viable formatting for dates used in, for example, file paths #46745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 14, 2025

Conversation

Forgind
Copy link
Contributor

@Forgind Forgind commented Feb 12, 2025

Fixes #46727
Fixes #37932
(@MiYanni commented that it looks similar to the issue I'd been looking at. Turns out 46727 is a dupe, but since I have a PR out already, I'll leave them up and close both via this.)

This replaces an explicit format with "u" for two specific DateTime.ToString instances. Lowercase u is for a sortable, universal date/time pattern:
image

(https://learn.microsoft.com/dotnet/standard/base-types/standard-date-and-time-format-strings)

I saw a number of other instances in which we currently use an explicit string format like this. I was a little split on whether I should change them all without looking at it too closely, but I can if desired.

@Forgind Forgind requested a review from Copilot February 12, 2025 01:21
@ghost ghost added Area-Workloads untriaged Request triage from a team member labels Feb 12, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

@KalleOlaviNiemitalo
Copy link
Contributor

The "u" format includes colons that are not valid for file paths on Windows.

@KalleOlaviNiemitalo
Copy link
Contributor

@Forgind
Copy link
Contributor Author

Forgind commented Feb 12, 2025

Could instead use String.Create(IFormatProvider? provider, ref System.Runtime.CompilerServices.DefaultInterpolatedStringHandler handler) with CultureInfo.InvariantCulture.

I'm trying to figure out how to make this make sense, and I don't, I'm afraid. The IFormatProvider can be CultureInfo.InvariantCulture, but what to use for the DefaultInterpolatedStringHandler? That essentially takes in a format string and some arguments and interpolates them, as the name suggests. There's a format in the current version already, so that would just mean replacing one format with another, and I don't see how that improves things.

I'm thinking about just replacing ':' (and perhaps ' ') with '_' in the 'u' format. Is there any reason that wouldn't work?

@KalleOlaviNiemitalo
Copy link
Contributor

KalleOlaviNiemitalo commented Feb 12, 2025

I meant like string.Create(CultureInfo.InvariantCulture, $"Microsoft.NET.Workload_{Environment.ProcessId}_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"), to prevent a user-specified culture from introducing quotation marks or other problematic characters.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-interpolated-strings

@Forgind
Copy link
Contributor Author

Forgind commented Feb 13, 2025

Thanks for the extra color 🙂 That sounds reasonable to me; I want to do some testing to make sure it works as expected, and if so, I can switch to that.

@Forgind
Copy link
Contributor Author

Forgind commented Feb 13, 2025

Ok, made a console to check out the difference. This was the result:
image

Will push the change 🙂

Comment on lines 45 to 46
protected static string TimeStamp => $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]";
protected static string TimeStamp => $"[{string.Create(CultureInfo.InvariantCulture, $"Microsoft.NET.Workload_{Environment.ProcessId}_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log")}]";
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this what's written as text to each log entry in the log file? I wouldn't expect the process ID and ".log" there. The nested interpolation looks unnecessarily complex, too.

Copy link
Contributor

@KalleOlaviNiemitalo KalleOlaviNiemitalo Feb 13, 2025

Choose a reason for hiding this comment

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

For this, $"[{DateTime.Now:u}]" would be safe because the result is not used as part of a file path. However, the u format does not include milliseconds, unlike the current format. Have the milliseconds in the log been useful for tracking down performance problems?

Copy link
Member

Choose a reason for hiding this comment

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

Hmm. I'm confused here. How does string.Create(CultureInfo.InvariantCulture, apply the culture to the string?

Copy link
Member

Choose a reason for hiding this comment

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

To clarify, in the past I've used this version of ToString on the DateTime to set it to invariant culture.

date.ToString("yyyyMMdd", CultureInfo.InvariantCulture);

Copy link
Contributor

Choose a reason for hiding this comment

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

How does string.Create(CultureInfo.InvariantCulture, apply the culture to the string?

An expression like string.Create(CultureInfo.InvariantCulture, $"[{DateTime.Now:yyyyMMdd}]") calls public static string Create(IFormatProvider? provider, [InterpolatedStringHandlerArgument(nameof(provider))] ref DefaultInterpolatedStringHandler handler). The C# compiler generates code to convert the interpolated string $"[{DateTime.Now:yyyyMMdd}]" to a DefaultInterpolatedStringHandler instance. Because of the InterpolatedStringHandlerArgumentAttribute, the value of the IFormatProvider? provider parameter, i.e. CultureInfo.InvariantCulture, is passed to the DefaultInterpolatedStringHandler constructor.

SharpLab

Copy link
Member

Choose a reason for hiding this comment

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

@KalleOlaviNiemitalo Makes sense. I've only briefly worked with interpolated string handler in the past so I didn't think about it pulling apart things like that. Nice! Thanks for the explanation.

@Forgind Forgind merged commit c32fff3 into dotnet:release/9.0.3xx Feb 14, 2025
30 checks passed
@Forgind Forgind deleted the calendar-format-bug branch February 14, 2025 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Workloads untriaged Request triage from a team member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants