繁体   English   中英

获取文化特定日期的日和月部分

[英]Get Day And Month portion of culture specific date

当使用 CultureInfo.CurrentCulture.DateTimeFormat 获取本地日期格式时,是否有内置的方法来获取本地 ShortTimePattern 返回的日期的日和月部分? 例如日/月

基本上,在我的剃刀看来,我正在做这样的事情:

@someObject.Date.ToString("dd/MM")

但是现在需要让它与当前文化一起工作,所以我希望找到一种方法来提供基于当前文化的动态格式掩码。 想象一下:

@someObject.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePatternNoYear)

为每种文化设置月和日模式是个坏消息。 在这种情况下, DRY 原则说要利用每个文化的日期时间格式,而不是用自定义的MonthDayPattern重复(并且可能矛盾)它。

而是利用短日期 ("d") 格式说明符以正确的顺序获取月份和日期,并为相关文化正确分隔,然后重击年份(及其分隔符)。

var de = CultureInfo.CreateSpecificCulture("de-DE").DateTimeFormat;
var uk = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
var us = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;

var now = DateTime.Now;
var yearNow = now.Year.ToString(CultureInfo.InvariantCulture);
const string yearPattern = "(^{0}{1}|{1}{0}$)"; // {0} = year, {1} = date separator

var deDate = now.ToString("d", de);
var deYearlessDate =
    Regex.Replace(
        deDate,
        String.Format(yearPattern, yearNow, de.DateSeparator),
        "");
// or a double String.Replace instead of a Regex.Replace
//var deYearlessDate =
//    deDate.Replace(de.DateSeparator + yearNow, "").Replace(yearNow + de.DateSeparator, "");

var ukDate = now.ToString("d", uk);
var ukYearlessDate =
    Regex.Replace(
        ukDate,
        String.Format(yearPattern, yearNow, uk.DateSeparator),
        "");
// or a double String.Replace instead of a Regex.Replace
//var ukYearlessDate =
//    ukDate.Replace(uk.DateSeparator + yearNow, "").Replace(yearNow + uk.DateSeparator, "");

var usDate = now.ToString("d", us);
var usYearlessDate =
    Regex.Replace(
        usDate,
        String.Format(yearPattern, yearNow, us.DateSeparator),
        "");
// or a double String.Replace instead of a Regex.Replace
//var usYearlessDate =
//    usDate.Replace(us.DateSeparator + nowYear, "").Replace(nowYear + us.DateSeparator, "");

Console.WriteLine(deYearlessDate); // 02.04
Console.WriteLine(ukYearlessDate); // 02/04
Console.WriteLine(usYearlessDate); // 4/2

解决方案是找到您当前的文化并更新 DateTimeFormat.MonthDayPattern。

.NET 中的自定义文化感知日期格式表示 ShortDatePattern ("d") 不可靠并建议使用以下方法:

private static string FindMonthDayOnly(System.Globalization.CultureInfo ci)
{
  string shortPattern = ci.DateTimeFormat.ShortDatePattern;
  while(shortPattern[0] != 'd' && shortPattern[0] != 'M')
  {
    shortPattern = shortPattern.Substring(1);
    if(shortPattern.Length == 0)
      return ci.DateTimeFormat.ShortDatePattern;
  }
  while(shortPattern[shortPattern.Length - 1] != 'd' && shortPattern[shortPattern.Length - 1] != 'M')
  {
    shortPattern = shortPattern.Substring(0, shortPattern.Length - 1);
    if(shortPattern.Length == 0)
      return ci.DateTimeFormat.ShortDatePattern;
  }
  return shortPattern;
}

然后你所要做的就是找到一个方便的地方来运行这样的东西(仔细考虑后台线程等,因为它只适用于当前线程):

var culture = new CultureInfo(CultureInfo.CurrentCulture.IetfLanguageTag);

var newMonthDayString = FindMonthDayOnly(culture);

culture.DateTimeFormat.MonthDayPattern = newMonthDayString;

Thread.CurrentThread.CurrentCulture = culture;

感谢大家的投入。 这似乎有效,但如果您发现解决方案有任何明显问题,请发表评论。

您可以自己更改MonthDayPattern 有点像这样:

var uk = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
uk.MonthDayPattern = "dd/MM";

var us = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;
us.MonthDayPattern = "MM/dd";

Console.WriteLine(DateTime.Now.ToString("m", uk)); // 03/04
Console.WriteLine(DateTime.Now.ToString("m", us)); // 04/03

默认情况下,英国的输出为3 April ,美国的输出为April 3 通过更改MonthDayPattern您可以将其自定义为数字。

我创建了一个扩展方法来根据 CultureInfo 仅显示月和日,希望它有所帮助:

    /// <summary>
    /// Return a date formatted MonthDay depending of the current application cutlure
    /// </summary>
    /// <param name="datetime">The datetime to parse</param>
    /// <returns>A Month day string representation</returns>
    public static string ToMonthDay(this DateTime datetime)
    {
        // Get the current culture of the application
        var culture = new CultureInfo(Thread.CurrentThread.CurrentCulture.Name);

        // Get the format depending of the culture of the application
        var output = culture.DateTimeFormat.ShortDatePattern;

        // Remove the Year from from the date format
        var format = output.Replace("Y", "").Replace("y", "");

        // Remove any character before or after in the text string which is not a number
        Regex rgx = new Regex("^[^a-zA-Z0-9]|[^a-zA-Z0-9]$");
        format = rgx.Replace(format, "");

        return datetime.ToString(format);
    }

以及用法:

DateTime dateToDisplay = new DateTime(2009, 01, 31);


Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(dateToDisplay.ToMonthDay());

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine(dateToDisplay.ToMonthDay());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM