检查给定的字符串是否是用于转换 DateTime 的有效格式字符串
Check if given string is valid format string for converting DateTime
TLDR;
我需要验证给定的输入字符串是否是用于解析 DateTime 的有效“格式字符串”。例如,
yy-mm-dd
有效
yy-aaaaaaa123
无效
我正在开发一个 program,它接受用户输入的日期格式。下面是我剥离的代码
private string datetimeFormat;
public Logger(string dateFormat)
{
datetimeFormat = dateFormat;
}
...
...
...
// Inside some function
string pretext = $"{DateTime.Now.ToString(datetimeFormat)},{logLevel},";
我需要为 dateFormat
字符串输入添加验证。
我正在考虑在一个数组中有许多可能的组合并且只接受那些字符串。但是还有其他方法可以验证吗?
更新:
我输入的字符串不包含任何日期。这不是 specified question.
的副本
This question 根本与日期时间无关。
这取决于您所说的 "valid" 的含义以及您认为 "only DateTime
, nothing else" 限制对您的重要性。
这里有一些我们可以用来测试格式字符串的规则,但有一些明确的限制:
必须适合传递给 DateTime.ToString(string format)
以将 DateTime
值转换为字符串。
必须可用于将规则 1 的输出解析为有效的 DateTime
值。
规则 2 的输出不得包含时间部分。
可选地,规则 2 的输出应在定义的精度范围内与输入相同。
只要您期望输出是完全指定的日期,这些就足以满足多种用途。必须指定年、月和日。下面是一些用于测试这些规则的代码:
static System.Globalization.CultureInfo DateTimeProvider = System.Globalization.CultureInfo.InvariantCulture;
const System.Globalization.DateTimeStyles ParseExactStyle = System.Globalization.DateTimeStyles.None;
static DateTime[] DateSamples = new[]
{
DateTime.Now,
DateTime.Today,
DateTime.Today.AddDays(1 - DateTime.Today.Day),
DateTime.Parse("10-Jan-2000"),
DateTime.Parse("01-Oct-1990"),
DateTime.Parse("13-Feb-1901")
};
public static bool IsValidDateFormat(string format, out string result)
{
var maxDifference = TimeSpan.FromDays(1);
foreach (var sample in DateSamples)
{
// Rule 1: Must be suitable for '.ToString(...)'
string sampleString;
try
{
sampleString = sample.ToString(format);
}
catch (FormatException e)
{
result = $"Failed rule 1: {e.Message}";
return false;
}
// Rule 2: Must be able to parse the produced string
if (!DateTime.TryParseExact(sampleString, format, DateTimeProvider, ParseExactStyle, out var parsed))
{
result = $"Failed rule 2: does not parse it's own output. '{sampleString}'";
return false;
}
// Rule 3: No time values.
if (parsed != parsed.Date)
{
result = $"Failed rule 3: No time values. '{sampleString}' => #{parsed}#";
return false;
}
// Rule 4: Difference must be less than maxDifference
TimeSpan difference = sample < parsed ? parsed - sample : sample - parsed;
if (difference >= maxDifference)
{
result = $"Failed rule 4: difference '{difference}' too large.";
return false;
}
}
result = "OK";
return true;
}
(这会将 result
out 参数设置为格式字符串失败原因的描述,如果通过则可以,但您可能更喜欢 return 一个简单的枚举值。)
这会验证各种奇怪的格式,包括那些带有额外 non-contextual - 或至少 non-time - 字符的格式。示例包括一些针对时间值、订单反转等的测试。
但是有一些限制:
TryParseExact
不适用于 standard format strings,如 d
、'F' 等
- 它也不适用于 3 位以上的年份格式 (
yyy
) 和其他拉伸格式。
- 示例包括防止使用 2 位数年份的测试。
总之,简单的工作就够用了。你可以trim它退一点。
TLDR;
我需要验证给定的输入字符串是否是用于解析 DateTime 的有效“格式字符串”。例如,
yy-mm-dd
有效yy-aaaaaaa123
无效
我正在开发一个 program,它接受用户输入的日期格式。下面是我剥离的代码
private string datetimeFormat;
public Logger(string dateFormat)
{
datetimeFormat = dateFormat;
}
...
...
...
// Inside some function
string pretext = $"{DateTime.Now.ToString(datetimeFormat)},{logLevel},";
我需要为 dateFormat
字符串输入添加验证。
我正在考虑在一个数组中有许多可能的组合并且只接受那些字符串。但是还有其他方法可以验证吗?
更新:
我输入的字符串不包含任何日期。这不是 specified question.
的副本This question 根本与日期时间无关。
这取决于您所说的 "valid" 的含义以及您认为 "only DateTime
, nothing else" 限制对您的重要性。
这里有一些我们可以用来测试格式字符串的规则,但有一些明确的限制:
必须适合传递给
DateTime.ToString(string format)
以将DateTime
值转换为字符串。必须可用于将规则 1 的输出解析为有效的
DateTime
值。规则 2 的输出不得包含时间部分。
可选地,规则 2 的输出应在定义的精度范围内与输入相同。
只要您期望输出是完全指定的日期,这些就足以满足多种用途。必须指定年、月和日。下面是一些用于测试这些规则的代码:
static System.Globalization.CultureInfo DateTimeProvider = System.Globalization.CultureInfo.InvariantCulture;
const System.Globalization.DateTimeStyles ParseExactStyle = System.Globalization.DateTimeStyles.None;
static DateTime[] DateSamples = new[]
{
DateTime.Now,
DateTime.Today,
DateTime.Today.AddDays(1 - DateTime.Today.Day),
DateTime.Parse("10-Jan-2000"),
DateTime.Parse("01-Oct-1990"),
DateTime.Parse("13-Feb-1901")
};
public static bool IsValidDateFormat(string format, out string result)
{
var maxDifference = TimeSpan.FromDays(1);
foreach (var sample in DateSamples)
{
// Rule 1: Must be suitable for '.ToString(...)'
string sampleString;
try
{
sampleString = sample.ToString(format);
}
catch (FormatException e)
{
result = $"Failed rule 1: {e.Message}";
return false;
}
// Rule 2: Must be able to parse the produced string
if (!DateTime.TryParseExact(sampleString, format, DateTimeProvider, ParseExactStyle, out var parsed))
{
result = $"Failed rule 2: does not parse it's own output. '{sampleString}'";
return false;
}
// Rule 3: No time values.
if (parsed != parsed.Date)
{
result = $"Failed rule 3: No time values. '{sampleString}' => #{parsed}#";
return false;
}
// Rule 4: Difference must be less than maxDifference
TimeSpan difference = sample < parsed ? parsed - sample : sample - parsed;
if (difference >= maxDifference)
{
result = $"Failed rule 4: difference '{difference}' too large.";
return false;
}
}
result = "OK";
return true;
}
(这会将 result
out 参数设置为格式字符串失败原因的描述,如果通过则可以,但您可能更喜欢 return 一个简单的枚举值。)
这会验证各种奇怪的格式,包括那些带有额外 non-contextual - 或至少 non-time - 字符的格式。示例包括一些针对时间值、订单反转等的测试。
但是有一些限制:
TryParseExact
不适用于 standard format strings,如d
、'F' 等- 它也不适用于 3 位以上的年份格式 (
yyy
) 和其他拉伸格式。 - 示例包括防止使用 2 位数年份的测试。
总之,简单的工作就够用了。你可以trim它退一点。