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

时间:2014-04-03 02:44:14

标签: c# .net

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

基本上,在我的剃刀视图中,我正在做这样的事情:

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

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

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

4 个答案:

答案 0 :(得分:2)

设置每种文化的月和日模式是个坏消息。在这种情况下,DRY principle表示要利用每种文化的日期时间格式,而不是使用自定义MonthDayPattern重复(并可能与之相矛盾)。

相反,利用Short Date ("d") format specifier以正确的顺序获取月份和日期,并针对相关文化进行适当分隔,然后敲打年份(及其分隔符)。

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

答案 1 :(得分:1)

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

Custom culture aware date format in .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;

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

答案 2 :(得分:0)

您可以自己更改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,您可以将其自定义为数字。

答案 3 :(得分:0)

我创建了一个Extension方法,仅根据文化信息显示月份和日期,希望对您有所帮助:

    /// <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());