Получите только час дня из DateTime, используя 12- или 24-часовой формат, как определено текущей культурой.
-
26-09-2019 - |
Вопрос
.Net имеет встроенную функцию ToShortTimeString() для DateTime, которая использует формат CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Он возвращает что-то вроде этого для en-US:"5:00 вечера".Для 24-часового формата, такого как de-DE, возвращается «17:00».
Мне нужен способ просто вернуть только час (то есть «5 часов вечера» и «17» в приведенных выше случаях), который работает в каждой культуре.Какой лучший/самый чистый способ сделать это?
Спасибо!
Решение
// 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);
}
}
Другие советы
Я бы проверил, содержит ли CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern «h», «hh», «H», «HH», «t» или «tt» и в каком порядке, а затем создал свой собственный формат. строка из тех.
например
- ru-США:сопоставьте "h:mm tt" с "h tt"
- ja-JP:сопоставьте "H:mm" с "H"
- а как:сопоставьте "ЧЧ:мм" с "ЧЧ"
Затем используйте .ToString(), передав созданную вами строку.
Пример кода. По сути, он удаляет все, кроме t, T, h, H и нескольких пробелов.Но, как указано ниже, просто строка «H» может дать сбой...
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);
}
Использовать это:
bool use2fHour =
CultureInfo
.CurrentCulture
.DateTimeFormat
.ShortTimePattern.Contains("H");
вы можете использовать DateTime.ToString() и указать нужный вам формат в качестве аргумента.
Ух, я не хотел интересоваться, но теперь заинтересовался!Вот код, который учитывает все культуры и отображает обозначения AM/PM в правильном положении, а также распознает 24-часовой формат, все в зависимости от культуры.
По сути, этот статический метод расширения перегружен для использования текущего языка и региональных параметров (без параметров) или указанного языка и региональных параметров.
DateTime.Now.ToTimeString()
DateTime.Now.ToTimeString(someCultureInfo)
Код ниже, включает пример программы:
public static class DateTimeStaticExtensions
{
private static int GetDesignatorIndex(CultureInfo info)
{
if (info.DateTimeFormat
.ShortTimePattern.StartsWith("tt"))
{
return 0;
}
else if (info.DateTimeFormat
.ShortTimePattern.EndsWith("tt"))
{
return 1;
}
else
{
return -1;
}
}
private static string GetFormattedString(int hour,
CultureInfo info)
{
string designator = (hour > 12 ?
info.DateTimeFormat.PMDesignator :
info.DateTimeFormat.AMDesignator);
if (designator != "")
{
switch (GetDesignatorIndex(info))
{
case 0:
return string.Format("{0} {1}",
designator,
(hour > 12 ?
(hour - 12).ToString() :
hour.ToString()));
case 1:
return string.Format("{0} {1}",
(hour > 12 ?
(hour - 12).ToString() :
hour.ToString()),
designator);
default:
return hour.ToString();
}
}
else
{
return hour.ToString();
}
}
public static string ToTimeString(this DateTime target,
CultureInfo info)
{
return GetFormattedString(target.Hour, info);
}
public static string ToTimeString(this DateTime target)
{
return GetFormattedString(target.Hour,
CultureInfo.CurrentCulture);
}
}
class Program
{
static void Main(string[] args)
{
var dt = new DateTime(2010, 6, 10, 6, 0, 0, 0);
CultureInfo[] cultures =
CultureInfo.GetCultures(CultureTypes.SpecificCultures);
foreach (CultureInfo culture in cultures)
{
Console.WriteLine(
"{0}: {1} ({2}, {3}) [Sample AM: {4} / Sample PM: {5}",
culture.Name, culture.DateTimeFormat.ShortTimePattern,
(culture.DateTimeFormat.AMDesignator == "" ?
"[No AM]":
culture.DateTimeFormat.AMDesignator),
(culture.DateTimeFormat.PMDesignator == "" ?
"[No PM]":
culture.DateTimeFormat.PMDesignator),
dt.ToTimeString(culture), // AM sample
dt.AddHours(12).ToTimeString(culture) // PM sample
);
}
// pause program execution to review results...
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
var culture = CultureInfo.CurrentCulture; bool uses24HourClock = string.IsNullOrEmpty(culture.DateTimeFormat.AMDesignator); var dt = DateTime.Now; string formatString = uses24HourClock ? "HH" : "h tt"; Console.WriteLine(dt.ToString(formatString, culture));
Редактирование Сэма:
Вот код, доказывающий, что это не работает.
var date = new DateTime(2010, 1, 1, 16, 0, 0);
foreach (CultureInfo cultureInfo in CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures))
{
bool amMethod = String.IsNullOrEmpty(cultureInfo.DateTimeFormat.AMDesignator);
bool formatMethod = cultureInfo.DateTimeFormat.ShortTimePattern.Contains("H");
if (amMethod != formatMethod)
{
Console.WriteLine("**** {0} AM: {1} Format: {2} Designator: {3} Time: {4}",
cultureInfo.Name,
amMethod,
formatMethod,
cultureInfo.DateTimeFormat.AMDesignator,
date.ToString("t", cultureInfo.DateTimeFormat));
}
}
Попробуйте использовать свойство DateTime.Hour.