For example. I have some mixed date and time format strings..
"date1": "dd/MM/yyyy",
"date2": "yyyy MM yyyy",
"date3": "h:mmtt",
"date4": "h:mmtt"
I need to check whether each of these is a time or date format. I know I can do some wizardry with string checking if it contains 'yyyy' etc. but that just feels wrong and would be open to error. Is there any way to check if a given DateTime format results in just the time being displayed or just the date?
Just to be clear I'm not interested in verifying a given date against a format or that a given date is actually a date, I'm only interested in identifying if a string DateTime format would result in just the time portion being displayed or just the date portion being displayed, if it was applied to any DateTime value.
Many thanks
Stewart
I would go with something along the lines of:
[Flags]
public enum DateFormatStringKind
{
HasNone = 0,
HasDate = 1 << 0,
HasTime = 1 << 1,
HasBoth = HasDate | HasTime
}
public static DateFormatStringKind DescribeFormatString(string s, IFormatProvider provider)
{
DateTime d = new DateTime(2, 2, 2, 1, 1, 1, 1); // DateTime will all non-default values
DateTime d2 = DateTime.ParseExact(d.ToString(s, provider), s, provider, System.Globalization.DateTimeStyles.NoCurrentDateDefault);
DateFormatStringKind result = DateFormatStringKind.HasNone;
if (d2.Date.Ticks != 0)
result |= DateFormatStringKind.HasDate;
if (d2.TimeOfDay != TimeSpan.Zero)
result |= DateFormatStringKind.HasTime;
return result;
}
var culture = System.Globalization.CultureInfo.InvariantCulture;
Console.WriteLine(DescribeFormatString("dd/MM/yyyy", culture));
Console.WriteLine(DescribeFormatString("yyyy MM yyyy", culture));
Console.WriteLine(DescribeFormatString("h:mmtt", culture));
Console.WriteLine(DescribeFormatString("dd h:mmtt", culture));
Console.WriteLine(DescribeFormatString("'literal'", culture));
HasDate
HasDate
HasTime
HasBoth
HasNone
It converts a date with all non-default fields into a string using the format string and then back using the same format string, and then checks what fields survived the conversion.
If there was no date component in the pattern, the "date" part will be 0001-01-01, which is the zero date (zero ticks from the point 0). The NoCurrentDateDefault flag ensures that the current date is not used instead.
If there was no time component in the pattern, the time will reset to midnight (TimeSpan.Zero from midnight).
If there was at least one component of the date pattern (either year, month or day), the respective field will become 2, which is greater than the default 1 for the date fields, so it will be detected regardless of what component that was.
If there was at least one component in the time pattern (hours, minutes, seconds, milliseconds), it will become 1, which is greater than the default 0 for the time fields, so it will again be detected regardless of what component it was.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With