Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get just the hour of day from DateTime using either 12 or 24 hour format as defined by the current culture

.Net has the built in ToShortTimeString() function for DateTime that uses the CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern format. It returns something like this for en-US: "5:00 pm". For a 24 hour culture such as de-DE it would return "17:00".

What I want is a way to just return just the hour (So "5 pm" and "17" in the cases above) that works with every culture. What's the best/cleanest way to do this?

Thanks!

like image 299
InvisibleBacon Avatar asked Jun 10 '10 13:06

InvisibleBacon


3 Answers

// displays "15" because my current culture is en-GB
Console.WriteLine(DateTime.Now.ToHourString());

// displays "3 pm"
Console.WriteLine(DateTime.Now.ToHourString(new CultureInfo("en-US")));

// displays "15"
Console.WriteLine(DateTime.Now.ToHourString(new CultureInfo("de-DE")));

// ...

public static class DateTimeExtensions
{
    public static string ToHourString(this DateTime dt)
    {
        return dt.ToHourString(null);
    }

    public static string ToHourString(this DateTime dt, IFormatProvider provider)
    {
        DateTimeFormatInfo dtfi = DateTimeFormatInfo.GetInstance(provider);

        string format = Regex.Replace(dtfi.ShortTimePattern, @"[^hHt\s]", "");
        format = Regex.Replace(format, @"\s+", " ").Trim();

        if (format.Length == 0)
            return "";

        if (format.Length == 1)
            format = '%' + format;

        return dt.ToString(format, dtfi);
    }
}
like image 107
LukeH Avatar answered Oct 09 '22 01:10

LukeH


I would check to see whether CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern contains "h", "hh", "H", "HH", "t" or "tt", and in what order, and then build your own custom format string from those.

e.g.

  • en-US: map "h:mm tt" to "h tt"
  • ja-JP: map "H:mm" to "H"
  • fr-FR: map "HH:mm" to "HH"

Then use .ToString(), passing in the string you built.

Example code - this basically strips out everything that's not t, T, h, H, and multiple spaces. But, as pointed out below, just a string of "H" could fail...

string full = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern;
string sh = String.Empty;
for (int k = 0; k < full.Length; k++)
{
    char i = full[k];
    if (i == 'h' || i == 'H' || i == 't' || i == 'T' || (i == ' ' && (sh.Length == 0 || sh[sh.Length - 1] != ' ')))
    {
        sh = sh + i;
    }
}
if (sh.Length == 1)
{
  sh = sh + ' ';
  string rtnVal = DateTime.Now.ToString(sh);
  return rtnVal.Substring(0, rtnVal.Length - 1);
{
else
{
    return DateTime.Now.ToString(sh);
}
like image 23
Rawling Avatar answered Oct 09 '22 02:10

Rawling


Use this:

bool use2fHour =
    CultureInfo
        .CurrentCulture
        .DateTimeFormat
        .ShortTimePattern.Contains("H");
like image 38
Samuel Neff Avatar answered Oct 09 '22 00:10

Samuel Neff