.net How do I know 12/24 hour format when I know the culture Info

643 views Asked by At

In .net, when I know the culture info, how do I know the time format of 12/24 hours? Is there an easy way to detect the culuter info specified time format?

What I need to know is just if the culture should use 12/24 hour time format. I know some cultures could use both 12/24 hour time format. But what's the default time format when we use DateTime.ToShortTimeString()? How do we know the default time format is 12 or 24?

2

There are 2 answers

8
Luaan On

One way would be to have a look at the format string:

CultureInfo.GetCultureInfo("cs-CZ").DateTimeFormat.ShortTimePattern.Contains("H")

If the format string contains H, it means it's using 24-hour. If it contains h or tt, though - it's 12-hour.

This is more of a dirty hack than a proper solution, though (and I'm not sure it will work for all cultures - you might need to handle escaping). The question is - why are you even trying to determine the 12/24-hourness? Just use the proper format for the given culture and be done with it.

0
Jon Hanna On

It could be both, as there's nothing to prevent a culture using 12 for ToShortTimeString() and 24 for ToLongTimeString() or vice versa.

However, considering that calling ToShortTimeString() is the same as calling DateTimeFormat.Format(this, "t", DateTimeFormatInfo.CurrentInfo), the we can then use this with the method from this answer:

[Flags]
public enum HourRepType
{
  None = 0,
  Twelve = 1,
  TwentyFour = 2,
  Both = Twelve | TwentyFour
}
public static HourRepType FormatStringHourType(string format, CultureInfo culture = null)
{
  if(string.IsNullOrEmpty(format))
    format = "G";//null or empty is treated as general, long time.
  if(culture == null)
    culture = CultureInfo.CurrentCulture;//allow null as a shortcut for this
  if(format.Length == 1)
    switch(format)
    {
      case "O": case "o": case "R": case "r": case "s": case "u":
        return HourRepType.TwentyFour;//always the case for these formats.
      case "m": case "M": case "y": case "Y":
        return HourRepType.None;//always the case for these formats.
      case "d":
          return CustomFormatStringHourType(culture.DateTimeFormat.ShortDatePattern);
      case "D":
        return CustomFormatStringHourType(culture.DateTimeFormat.LongDatePattern);
      case "f":
        return CustomFormatStringHourType(culture.DateTimeFormat.LongDatePattern + " " + culture.DateTimeFormat.ShortTimePattern);
      case "F":
        return CustomFormatStringHourType(culture.DateTimeFormat.FullDateTimePattern);
      case "g":
        return CustomFormatStringHourType(culture.DateTimeFormat.ShortDatePattern + " " + culture.DateTimeFormat.ShortTimePattern);
      case "G":
        return CustomFormatStringHourType(culture.DateTimeFormat.ShortDatePattern + " " + culture.DateTimeFormat.LongTimePattern);
      case "t":
        return CustomFormatStringHourType(culture.DateTimeFormat.ShortTimePattern);
      case "T":
        return CustomFormatStringHourType(culture.DateTimeFormat.LongTimePattern);
      default:
        throw new FormatException();
    }
  return CustomFormatStringHourType(format);
}
private static HourRepType CustomFormatStringHourType(string format)
{
  format = new Regex(@"('.*')|("".*"")|(\\.)").Replace(format, "");//remove literals
  if(format.Contains("H"))
    return format.Contains("h") ? HourRepType.Both : HourRepType.TwentyFour;
  return  format.Contains("h") ? HourRepType.Twelve : HourRepType.None;
}

And call FormatStringHourType("t") to find out whether it's 12 or 24 hours (or possibly neither or both, but that would be strange).

Likewise FormatStringHourType("T") would tell us about the long time string.