Add filename-compatible date & time format (#25020)

* enable the functionality to have filename-compatible date & time

* fix PowerToys.sln

* fix DateTime format

* remove unrelated code

* modify date time format

* fix tests

* fix hours to 24h format and modify tests to cover the case better. Simplify tests slightly
This commit is contained in:
Jachym Metlicka
2023-03-28 14:52:21 +02:00
committed by GitHub
parent 543d5d1b6d
commit b2b7dc3ccf
6 changed files with 76 additions and 41 deletions

View File

@@ -60,6 +60,7 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("iso zone", "ISO 8601 with time zone - ", "Images\\timeDate.dark.png")] [DataRow("iso zone", "ISO 8601 with time zone - ", "Images\\timeDate.dark.png")]
[DataRow("iso utc zone", "ISO 8601 UTC with time zone - ", "Images\\timeDate.dark.png")] [DataRow("iso utc zone", "ISO 8601 UTC with time zone - ", "Images\\timeDate.dark.png")]
[DataRow("rfc", "RFC1123 -", "Images\\timeDate.dark.png")] [DataRow("rfc", "RFC1123 -", "Images\\timeDate.dark.png")]
[DataRow("compatible", "Date and time in filename-compatible format", "Images\\timeDate.dark.png")]
public void IconThemeDarkTest(string typedString, string subTitleMatch, string expectedResult) public void IconThemeDarkTest(string typedString, string subTitleMatch, string expectedResult)
{ {
// Setup // Setup
@@ -105,6 +106,7 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("iso zone", "ISO 8601 with time zone - ", "Images\\timeDate.light.png")] [DataRow("iso zone", "ISO 8601 with time zone - ", "Images\\timeDate.light.png")]
[DataRow("iso utc zone", "ISO 8601 UTC with time zone - ", "Images\\timeDate.light.png")] [DataRow("iso utc zone", "ISO 8601 UTC with time zone - ", "Images\\timeDate.light.png")]
[DataRow("rfc", "RFC1123 -", "Images\\timeDate.light.png")] [DataRow("rfc", "RFC1123 -", "Images\\timeDate.light.png")]
[DataRow("compatible", "Date and time in filename-compatible format", "Images\\timeDate.light.png")]
public void IconThemeLightTest(string typedString, string subTitleMatch, string expectedResult) public void IconThemeLightTest(string typedString, string subTitleMatch, string expectedResult)
{ {
// Setup // Setup

View File

@@ -52,12 +52,12 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
} }
[DataTestMethod] [DataTestMethod]
[DataRow("(time", 16)] [DataRow("(time", 17)]
[DataRow("(date", 24)] [DataRow("(date", 25)]
[DataRow("(year", 7)] [DataRow("(year", 7)]
[DataRow("(now", 30)] [DataRow("(now", 31)]
[DataRow("(current", 30)] [DataRow("(current", 31)]
[DataRow("(", 30)] [DataRow("(", 31)]
[DataRow("(now::10:10:10", 1)] // Windows file time [DataRow("(now::10:10:10", 1)] // Windows file time
[DataRow("(current::10:10:10", 0)] [DataRow("(current::10:10:10", 0)]
public void CountWithPluginKeyword(string typedString, int expectedResultCount) public void CountWithPluginKeyword(string typedString, int expectedResultCount)

View File

@@ -26,11 +26,16 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
CultureInfo.CurrentUICulture = new CultureInfo("en-us"); CultureInfo.CurrentUICulture = new CultureInfo("en-us");
} }
private DateTime GetDateTimeForTest()
{
return new DateTime(2022, 03, 02, 22, 30, 45);
}
[DataTestMethod] [DataTestMethod]
[DataRow("time", "10:30 AM")] [DataRow("time", "10:30 PM")]
[DataRow("date", "3/2/2022")] [DataRow("date", "3/2/2022")]
[DataRow("date and time", "3/2/2022 10:30 AM")] [DataRow("date and time", "3/2/2022 10:30 PM")]
[DataRow("hour", "10")] [DataRow("hour", "22")]
[DataRow("minute", "30")] [DataRow("minute", "30")]
[DataRow("second", "45")] [DataRow("second", "45")]
[DataRow("millisecond", "0")] [DataRow("millisecond", "0")]
@@ -45,13 +50,14 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("month and day", "March 2")] [DataRow("month and day", "March 2")]
[DataRow("year", "2022")] [DataRow("year", "2022")]
[DataRow("month and year", "March 2022")] [DataRow("month and year", "March 2022")]
[DataRow("ISO 8601", "2022-03-02T10:30:45")] [DataRow("ISO 8601", "2022-03-02T22:30:45")]
[DataRow("ISO 8601 with time zone", "2022-03-02T10:30:45")] [DataRow("ISO 8601 with time zone", "2022-03-02T22:30:45")]
[DataRow("RFC1123", "Wed, 02 Mar 2022 10:30:45 GMT")] [DataRow("RFC1123", "Wed, 02 Mar 2022 22:30:45 GMT")]
[DataRow("Date and time in filename-compatible format", "2022-03-02_22-30-45")]
public void LocalFormatsWithShortTimeAndShortDate(string formatLabel, string expectedResult) public void LocalFormatsWithShortTimeAndShortDate(string formatLabel, string expectedResult)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, false, false, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, false, false, GetDateTimeForTest());
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -61,10 +67,10 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
} }
[DataTestMethod] [DataTestMethod]
[DataRow("time", "10:30 AM")] [DataRow("time", "10:30 PM")]
[DataRow("date", "Wednesday, March 2, 2022")] [DataRow("date", "Wednesday, March 2, 2022")]
[DataRow("date and time", "Wednesday, March 2, 2022 10:30 AM")] [DataRow("date and time", "Wednesday, March 2, 2022 10:30 PM")]
[DataRow("hour", "10")] [DataRow("hour", "22")]
[DataRow("minute", "30")] [DataRow("minute", "30")]
[DataRow("second", "45")] [DataRow("second", "45")]
[DataRow("millisecond", "0")] [DataRow("millisecond", "0")]
@@ -79,13 +85,14 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("month and day", "March 2")] [DataRow("month and day", "March 2")]
[DataRow("year", "2022")] [DataRow("year", "2022")]
[DataRow("month and year", "March 2022")] [DataRow("month and year", "March 2022")]
[DataRow("ISO 8601", "2022-03-02T10:30:45")] [DataRow("ISO 8601", "2022-03-02T22:30:45")]
[DataRow("ISO 8601 with time zone", "2022-03-02T10:30:45")] [DataRow("ISO 8601 with time zone", "2022-03-02T22:30:45")]
[DataRow("RFC1123", "Wed, 02 Mar 2022 10:30:45 GMT")] [DataRow("RFC1123", "Wed, 02 Mar 2022 22:30:45 GMT")]
[DataRow("Date and time in filename-compatible format", "2022-03-02_22-30-45")]
public void LocalFormatsWithShortTimeAndLongDate(string formatLabel, string expectedResult) public void LocalFormatsWithShortTimeAndLongDate(string formatLabel, string expectedResult)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, false, true, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, false, true, GetDateTimeForTest());
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -95,10 +102,10 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
} }
[DataTestMethod] [DataTestMethod]
[DataRow("time", "10:30:45 AM")] [DataRow("time", "10:30:45 PM")]
[DataRow("date", "3/2/2022")] [DataRow("date", "3/2/2022")]
[DataRow("date and time", "3/2/2022 10:30:45 AM")] [DataRow("date and time", "3/2/2022 10:30:45 PM")]
[DataRow("hour", "10")] [DataRow("hour", "22")]
[DataRow("minute", "30")] [DataRow("minute", "30")]
[DataRow("second", "45")] [DataRow("second", "45")]
[DataRow("millisecond", "0")] [DataRow("millisecond", "0")]
@@ -113,13 +120,14 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("month and day", "March 2")] [DataRow("month and day", "March 2")]
[DataRow("year", "2022")] [DataRow("year", "2022")]
[DataRow("month and year", "March 2022")] [DataRow("month and year", "March 2022")]
[DataRow("ISO 8601", "2022-03-02T10:30:45")] [DataRow("ISO 8601", "2022-03-02T22:30:45")]
[DataRow("ISO 8601 with time zone", "2022-03-02T10:30:45")] [DataRow("ISO 8601 with time zone", "2022-03-02T22:30:45")]
[DataRow("RFC1123", "Wed, 02 Mar 2022 10:30:45 GMT")] [DataRow("RFC1123", "Wed, 02 Mar 2022 22:30:45 GMT")]
[DataRow("Date and time in filename-compatible format", "2022-03-02_22-30-45")]
public void LocalFormatsWithLongTimeAndShortDate(string formatLabel, string expectedResult) public void LocalFormatsWithLongTimeAndShortDate(string formatLabel, string expectedResult)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, true, false, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, true, false, GetDateTimeForTest());
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -129,10 +137,10 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
} }
[DataTestMethod] [DataTestMethod]
[DataRow("time", "10:30:45 AM")] [DataRow("time", "10:30:45 PM")]
[DataRow("date", "Wednesday, March 2, 2022")] [DataRow("date", "Wednesday, March 2, 2022")]
[DataRow("date and time", "Wednesday, March 2, 2022 10:30:45 AM")] [DataRow("date and time", "Wednesday, March 2, 2022 10:30:45 PM")]
[DataRow("hour", "10")] [DataRow("hour", "22")]
[DataRow("minute", "30")] [DataRow("minute", "30")]
[DataRow("second", "45")] [DataRow("second", "45")]
[DataRow("millisecond", "0")] [DataRow("millisecond", "0")]
@@ -147,13 +155,14 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("month and day", "March 2")] [DataRow("month and day", "March 2")]
[DataRow("year", "2022")] [DataRow("year", "2022")]
[DataRow("month and year", "March 2022")] [DataRow("month and year", "March 2022")]
[DataRow("ISO 8601", "2022-03-02T10:30:45")] [DataRow("ISO 8601", "2022-03-02T22:30:45")]
[DataRow("ISO 8601 with time zone", "2022-03-02T10:30:45")] [DataRow("ISO 8601 with time zone", "2022-03-02T22:30:45")]
[DataRow("RFC1123", "Wed, 02 Mar 2022 10:30:45 GMT")] [DataRow("RFC1123", "Wed, 02 Mar 2022 22:30:45 GMT")]
[DataRow("Date and time in filename-compatible format", "2022-03-02_22-30-45")]
public void LocalFormatsWithLongTimeAndLongDate(string formatLabel, string expectedResult) public void LocalFormatsWithLongTimeAndLongDate(string formatLabel, string expectedResult)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, true, true, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, true, true, GetDateTimeForTest());
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -168,11 +177,12 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")] [DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")]
[DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")] [DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")]
[DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")] [DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")]
[DataRow("Date and time in filename-compatible format", "yyyy-MM-dd_HH-mm-ss")]
public void UtcFormatsWithShortTimeAndShortDate(string formatLabel, string expectedFormat) public void UtcFormatsWithShortTimeAndShortDate(string formatLabel, string expectedFormat)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, false, false, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, false, false, GetDateTimeForTest());
var expectedResult = new DateTime(2022, 03, 02, 10, 30, 45).ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture); var expectedResult = GetDateTimeForTest().ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture);
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -187,11 +197,12 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")] [DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")]
[DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")] [DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")]
[DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")] [DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")]
[DataRow("Date and time in filename-compatible format", "yyyy-MM-dd_HH-mm-ss")]
public void UtcFormatsWithShortTimeAndLongDate(string formatLabel, string expectedFormat) public void UtcFormatsWithShortTimeAndLongDate(string formatLabel, string expectedFormat)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, false, true, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, false, true, GetDateTimeForTest());
var expectedResult = new DateTime(2022, 03, 02, 10, 30, 45).ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture); var expectedResult = GetDateTimeForTest().ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture);
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -206,11 +217,12 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")] [DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")]
[DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")] [DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")]
[DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")] [DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")]
[DataRow("Date and time in filename-compatible format", "yyyy-MM-dd_HH-mm-ss")]
public void UtcFormatsWithLongTimeAndShortDate(string formatLabel, string expectedFormat) public void UtcFormatsWithLongTimeAndShortDate(string formatLabel, string expectedFormat)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, true, false, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, true, false, GetDateTimeForTest());
var expectedResult = new DateTime(2022, 03, 02, 10, 30, 45).ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture); var expectedResult = GetDateTimeForTest().ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture);
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));
@@ -225,11 +237,12 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
[DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")] [DataRow("ISO 8601 UTC", "yyyy-MM-ddTHH:mm:ss")]
[DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")] [DataRow("ISO 8601 UTC with time zone", "yyyy-MM-ddTHH:mm:ss'Z'")]
[DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")] [DataRow("Universal time format: YYYY-MM-DD hh:mm:ss", "u")]
[DataRow("Date and time in filename-compatible format", "yyyy-MM-dd_HH-mm-ss")]
public void UtcFormatsWithLongTimeAndLongDate(string formatLabel, string expectedFormat) public void UtcFormatsWithLongTimeAndLongDate(string formatLabel, string expectedFormat)
{ {
// Setup // Setup
var helperResults = AvailableResultsList.GetList(true, true, true, new DateTime(2022, 03, 02, 10, 30, 45)); var helperResults = AvailableResultsList.GetList(true, true, true, GetDateTimeForTest());
var expectedResult = new DateTime(2022, 03, 02, 10, 30, 45).ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture); var expectedResult = GetDateTimeForTest().ToUniversalTime().ToString(expectedFormat, CultureInfo.CurrentCulture);
// Act // Act
var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase)); var result = helperResults.FirstOrDefault(x => x.Label.Equals(formatLabel, StringComparison.OrdinalIgnoreCase));

View File

@@ -256,6 +256,13 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.Components
AlternativeSearchTag = ResultHelper.SelectStringFromResources(isSystemDateTime, "Microsoft_plugin_timedate_SearchTagFormat"), AlternativeSearchTag = ResultHelper.SelectStringFromResources(isSystemDateTime, "Microsoft_plugin_timedate_SearchTagFormat"),
IconType = ResultIconType.DateTime, IconType = ResultIconType.DateTime,
}, },
new AvailableResult()
{
Value = dateTimeNow.ToString("yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture),
Label = Resources.Microsoft_plugin_timedate_filename_compatible,
AlternativeSearchTag = ResultHelper.SelectStringFromResources(isSystemDateTime, "Microsoft_plugin_timedate_SearchTagFormat"),
IconType = ResultIconType.DateTime,
},
}); });
} }

View File

@@ -177,6 +177,15 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Date and time in filename-compatible format.
/// </summary>
internal static string Microsoft_plugin_timedate_filename_compatible {
get {
return ResourceManager.GetString("Microsoft_plugin_timedate_filename_compatible", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Hour. /// Looks up a localized string similar to Hour.
/// </summary> /// </summary>

View File

@@ -175,6 +175,10 @@
<value>ISO 8601 UTC with time zone</value> <value>ISO 8601 UTC with time zone</value>
<comment>'UTC' means here 'Universal Time Convention'</comment> <comment>'UTC' means here 'Universal Time Convention'</comment>
</data> </data>
<data name="Microsoft_plugin_timedate_filename_compatible" xml:space="preserve">
<value>Date and time in filename-compatible format</value>
<comment>The format allows for embedding in filenames</comment>
</data>
<data name="Microsoft_plugin_timedate_Millisecond" xml:space="preserve"> <data name="Microsoft_plugin_timedate_Millisecond" xml:space="preserve">
<value>Millisecond</value> <value>Millisecond</value>
</data> </data>