【问题标题】:Getting current culture day names in .NET在 .NET 中获取当前文化日名称
【发布时间】:2010-05-25 00:13:01
【问题描述】:

是否可以从 DateTimeFormatInfo 获取 CurrentCulture 的工作日,但返回 Monday 作为一周的第一天而不是 Sunday。而且,如果当前的文化不是英语(即 ISO 代码不是“en”),则将其保留为默认值。

默认CultureInfo.CurrentCulture.DateTimeFormat.DayNames返回:

[0]: "Sunday"
[1]: "Monday"
[2]: "Tuesday"
[3]: "Wednesday"
[4]: "Thursday"
[5]: "Friday"
[6]: "Saturday" 

但我需要:

[0]: "Monday"
[1]: "Tuesday"
[2]: "Wednesday"
[3]: "Thursday"
[4]: "Friday"
[5]: "Saturday" 
[6]: "Sunday"

【问题讨论】:

  • 这个问题有点令人困惑,原因如下:您希望从星期一开始返回英文日期名称,但您希望保留任何其他文化的默认顺序 - 所以,您实际上并不想要想知道哪个字符串代表非英语文化中的哪一天?

标签: c# .net datetime


【解决方案1】:

您可以克隆获取 CultureInfo 对象的可写副本的当前文化。然后您可以将 DateTimeFormat.FirstDayOfWeek 设置为星期一。

CultureInfo current = CultureInfo.Current;
CultureInfo clone = (CultureInfo)current.Clone();

clone.DateTimeFormat.FirstDayOfWeek = DayOfWeek.Monday;

上述clone 现在将星期一视为一周的第一天。

编辑

重新阅读您的问题后,我认为这不会达到您的预期。无论FirstDayOfWeek 设置如何,DayNames 仍将以相同的顺序返回。

但我会将这个答案保留为社区 wiki,以防将来有人遇到这个问题。

【讨论】:

  • 哇,没想到这么简单!
  • 感谢您的回答,我已经尝试过了,但很失望仍然以相同的顺序恢复了日子。好主意。
【解决方案2】:

另一个简单的解决方案:

var dayNames = Thread.CurrentThread.CurrentCulture.DateTimeFormat.DayNames.ToList();

if (Culture.DateTimeFormat.FirstDayOfWeek == DayOfWeek.Monday)
{
    dayNames.Add(dayNames[0]);
    dayNames.RemoveAt(0);
}

【讨论】:

    【解决方案3】:

    您可以使用custom cultures 在现有文化的基础上创建一种新文化。不过,老实说,我想说这可能有点粗暴。 “最简单”的解决方案可能是这样的:

    public string[] GetDayNames()
    {
        if (CultureInfo.CurrentCulture.Name.StartsWith("en-"))
        {
            return new [] { "Monday", "Tuesday", "Wednesday", "Thursday",
                            "Friday", "Saturday", "Sunday" };
        }
        else
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.DayNames;
        }
    }
    

    【讨论】:

    • 同意,我认为这可能是最简单的。我最终使用if (CurrentCulture.TwoLetterISOLanguageName == "en") 来检查英语。
    【解决方案4】:

    DatetimeFormatInfo.GetDayName 显然,在每个 DayOfWeek 上按照您想要的顺序进行 foreach。 :) 无需破解,简单有效

    【讨论】:

      【解决方案5】:

      另一个想法,受 Josh 的回答启发,使用队列而不是移动数组。

      var days = CultureInfo.CurrentCulture.DateTimeFormat.DayNames;
      if (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "en")
      {
          var q = new Queue<string>(days);
          q.Enqueue(q.Dequeue());
          days = q.ToArray();
      }
      

      【讨论】:

      • 聪明!它肯定比直接操作数组更容易。
      【解决方案6】:

      如果您根据日期获取日期名称,则一周从哪一天开始并不重要; DateTimeFormat.DayNames 将星期日标识为 0,DateTime 也是如此,无论星期是从星期四开始还是你有什么。 :)

      从日期中获取英文日期名称:

      string GetDayName(DateTime dt)
      {
          return CultureInfo.InvariantCulture.DateTimeFormat.DayNames[(int)dt.DayOfWeek];
      }
      

      如果出于某种原因您绝对想要处理支持 DayOfWeek 枚举的(神奇值!)整数,只需移动索引并取模,因此映射 0 => 6、1 => 0 等等:

      string GetDayName(int dayIndex)
      {
          return CultureInfo.InvariantCulture.DateTimeFormat.DayNames[(dayIndex + 6) % 7]; 
      }
      

      【讨论】:

      • "DateTimeFormat.DayNames 将星期日标识为 0" - 此语句似乎是错误的。 docs on DayNames 状态:“第一个元素(索引为零的元素)表示 Calendar 属性定义的日历中一周的第一天。”
      【解决方案7】:

      我将其作为一个单独的答案发布,因为它与我的其他答案实际上无关(这可能对将来在另一种情况下的其他人有用。)

      作为 codeka 解决方案的替代方案,您还可以执行类似的操作(这样可以避免对 en-us 日期名称进行硬编码。)

      string[] dayNamesNormal = culture.DateTimeFormat.DayNames;
      string[] dayNamesShifted = Shift(dayNamesNormal, (int)DayOfWeek.Monday);
      
      // you probably wanna add some error checking here.
      // this method shifts array left by a specified number
      // of positions, wrapping the shifted elements back to
      // end of the array
      private static T[] Shift<T>(T[] array, int positions) {
          T[] copy = new T[array.Length];
          Array.Copy(array, 0, copy, array.Length-positions, positions);
          Array.Copy(array, positions, copy, 0, array.Length-positions);
          return copy;
      }
      

      我本来打算早点发布这个,但我正在与一个垂死的外置硬盘作斗争......

      【讨论】:

      • 不错的解决方案,我喜欢 Shift 方法,可以方便地保存在库中。
      【解决方案8】:

      由于只搬了一天,我这样解决了这个问题:

      'the list is from Sunday to Saturday
      'we need Monday to Sunday
      'so add a Sunday on the end and then remove the first position
      dayNames.AddRange(DateTimeFormatInfo.CurrentInfo.DayNames)
      dayNames.Add(DateTimeFormatInfo.CurrentInfo.GetDayName(DayOfWeek.Sunday))
      dayNames.RemoveAt(0)
      

      【讨论】:

        【解决方案9】:

        这也应该很好用。

            public static List<String> Days
            {
                var abbDayNames = CultureInfo.CurrentCulture.DateTimeFormat.AbbreviatedDayNames;
        
                var days = new string[7];
                var firstDayOfWeek = (int)DayOfWeek.Monday;
                for (int i = 6; i>= 0; i--)
                {
                    days[i] = abbDayNames[(firstDayOfWeek + i) % 7];
                }
        
                return new List<string>(days);
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-20
          • 1970-01-01
          • 2012-10-30
          • 2014-01-15
          相关资源
          最近更新 更多