【问题标题】:How can i format 07/03/2012 to March 7th,2012 in c# [duplicate]我如何在 c# 中格式化 07/03/2012 到 2012 年 3 月 7 日 [重复]
【发布时间】:2012-03-24 23:42:12
【问题描述】:

请大家帮忙 我需要将日期 03/03/2012 显示为 March 3rd,2012 等

【问题讨论】:

  • 一定要在“3rd”中做“rd”吗?查看可用的标准和自定义格式字符串,它们都不会为您做到这一点......虽然没有,但它相对容易。 :)

标签: c# datetime formatting


【解决方案1】:

这里是 Ordinalize() 扩展的另一个版本,简短而实用:

public static string Ordinalize(this int x)
{
    var xString = x.ToString();
    var xLength = xString.Length;
    var xLastTwoCharacters = xString.Substring(Math.Max(0, xLength - 2));
    return xString + 
        ((x % 10 == 1 && xLastTwoCharacters != "11") 
            ? "st"
        : (x % 10 == 2 && xLastTwoCharacters != "12") 
            ? "nd"
        : (x % 10 == 3 && xLastTwoCharacters != "13") 
            ? "rd"
        : "th");
    }

然后像这样调用那个扩展

myDate.Day.Ordinalize()

myAnyNumber.Ordinalize() 

【讨论】:

  • 211呢?
  • @Kristopher 很好 - 我想我这次修好了。这是 .NetFiddle 上的测试人员:dotnetfiddle.net/hy3OoI
【解决方案2】:

您可以创建自己的自定义格式提供程序来执行此操作:

public class MyCustomDateProvider: IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;

        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        if (!(arg is DateTime)) throw new NotSupportedException();

        var dt = (DateTime) arg;

        string suffix;

        if (new[] {11, 12, 13}.Contains(dt.Day))
        {
            suffix = "th";
        }
        else if (dt.Day % 10 == 1)
        {
            suffix = "st";
        }
        else if (dt.Day % 10 == 2)
        {
            suffix = "nd";
        }
        else if (dt.Day % 10 == 3)
        {
            suffix = "rd";
        }
        else
        {
            suffix = "th";
        }

        return string.Format("{0:MMMM} {1}{2}, {0:yyyy}", arg, dt.Day, suffix);
    }
}

然后可以这样调用:

var formattedDate = string.Format(new MyCustomDateProvider(), "{0}", date);

导致(例如):

2012 年 3 月 3 日

【讨论】:

  • 嗨,它工作得很好,谢谢 Rob
  • 但需要检查 if (dt.Day == 11 || dt.Day == 12 || dt.Day == 13) { suffix = "th"; return string.Format("{0:MMMM} {1}{2}, {0:yyyy}", arg, dt.Day, suffix); }
  • 哦,是的 - 您必须在其他检查之前将它们添加为特殊情况。
  • 此答案的简短版本在这里stackoverflow.com/a/2050854/581414
【解决方案3】:

Humanizer 满足您对 .NET 操作和显示字符串、枚举、日期、时间、时间跨度、数字和数量的所有需求

要安装 Humanizer,请在包管理器控制台中运行以下命令

PM> Install-Package Humanizer

Ordinalize 将数字转换为序号字符串,用于表示有序序列中的位置,例如 1st、2nd、3rd、4th:

1.Ordinalize() => "1st"
5.Ordinalize() => "5th"

那么你可以使用:

String.Format("{0} {1:MMMM yyyy}", date.Day.Ordinalize(), date)

【讨论】:

  • +1 - 我使用了 String.Format("{0} {1}", d.Day.Ordinalize(), d.ToString("MMMM yyyy"))
  • +1 Humanizer 很棒。顺便说一句,你可以写: string.Format("{0} {1:MMMM yyyy}", date.Day.Ordinalize(), date)
  • 好一个@BritishDeveloper,我会更新示例
  • 有没有办法用 Humanizer 解析英国日期?就像将“2012 年 11 月 8 日”解析为适当的 DateTime 对象。
【解决方案4】:

基于 Rob Levine 的答案和该答案的 cmets...我已将其改编为 DateTime 的扩展方法,因此您只需调用:

var formattedDate = date.Friendly();

扩展方法如下:

public static class DateFormatter
{
  public static string Friendly(this DateTime dt)
  {
    string suffix;

    switch (dt.Day)
    {
      case 1:
      case 21:
      case 31:
        suffix = "st";
        break;
      case 2:
      case 22:
        suffix = "nd";
        break;
      case 3:
      case 23:
        suffix = "rd";
        break;
      default:
        suffix = "th";
        break;
    }

    return string.Format("{0:MMMM} {1}{2}, {0:yyyy}", dt, dt.Day, suffix);
  }
}

【讨论】:

    【解决方案5】:
    public static class IntegerExtensions
    {
        /// <summary>
        /// converts an integer to its ordinal representation
        /// </summary>
        public static String AsOrdinal(this Int32 number)
        {
            if (number < 0)
                throw new ArgumentOutOfRangeException("number");
    
            var work = number.ToString("n0");
    
            var modOf100 = number % 100;
    
            if (modOf100 == 11 || modOf100 == 12 || modOf100 == 13)
                return work + "th";
    
            switch (number % 10)
            {
                case 1:
                    work += "st"; break;
                case 2:
                    work += "nd"; break;
                case 3:
                    work += "rd"; break;
               default:
                    work += "th"; break;
            }
    
            return work;
        }
    }
    

    证明:

    [TestFixture]
    class IntegerExtensionTests
    {
        [Test]
        public void TestCases_1s_10s_100s_1000s()
        {
            Assert.AreEqual("1st", 1.AsOrdinal());
            Assert.AreEqual("2nd", 2.AsOrdinal());
            Assert.AreEqual("3rd", 3.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(4, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("11th", 11.AsOrdinal());
            Assert.AreEqual("12th", 12.AsOrdinal());
            Assert.AreEqual("13th", 13.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(14, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("21st", 21.AsOrdinal());
            Assert.AreEqual("22nd", 22.AsOrdinal());
            Assert.AreEqual("23rd", 23.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(24, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("31st", 31.AsOrdinal());
            Assert.AreEqual("32nd", 32.AsOrdinal());
            Assert.AreEqual("33rd", 33.AsOrdinal());
    
            //then just jump to 100
    
            Assert.AreEqual("101st", 101.AsOrdinal());
            Assert.AreEqual("102nd", 102.AsOrdinal());
            Assert.AreEqual("103rd", 103.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(104, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("111th", 111.AsOrdinal());
            Assert.AreEqual("112th", 112.AsOrdinal());
            Assert.AreEqual("113th", 113.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(114, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("121st", 121.AsOrdinal());
            Assert.AreEqual("122nd", 122.AsOrdinal());
            Assert.AreEqual("123rd", 123.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(124, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            //then just jump to 1000
    
            Assert.AreEqual("1,001st", 1001.AsOrdinal());
            Assert.AreEqual("1,002nd", 1002.AsOrdinal());
            Assert.AreEqual("1,003rd", 1003.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(1004, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("1,011th", 1011.AsOrdinal());
            Assert.AreEqual("1,012th", 1012.AsOrdinal());
            Assert.AreEqual("1,013th", 1013.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(1014, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
    
            Assert.AreEqual("1,021st", 1021.AsOrdinal());
            Assert.AreEqual("1,022nd", 1022.AsOrdinal());
            Assert.AreEqual("1,023rd", 1023.AsOrdinal());
    
            foreach (var integer in Enumerable.Range(1024, 6))
                Assert.AreEqual(String.Format("{0:n0}th", integer), integer.AsOrdinal());
        }
    }
    

    【讨论】:

      【解决方案6】:

      Custom Date and Time Format Strings

      date.ToString("MMMM d, yyyy")
      

      或者如果你也需要“rd”:

      string.Format("{0} {1}, {2}", date.ToString("MMMM"), date.Day.Ordinal(), date.ToString("yyyy"))
      
      • Ordinal()方法可以找到here

      【讨论】:

      • 由于原始规范中的“rd”,这并不能完全给出正确的格式。
      【解决方案7】:

      不,string.Format() 中没有任何内容可以为您提供序数(第 1、第 2、第 3、第 4 等等)。

      您可以将其他答案中建议的日期格式与本答案中建议的您自己的序数结合起来

      Is there an easy way to create ordinals in C#?

      string Format(DateTime date)
      {
          int dayNo = date.Day;
          return string.Format("{0} {1}{2}, {3}", 
                      date.ToString("MMMM"), dayNo, AddOrdinal(dayNo), date.Year); 
      }
      

      【讨论】:

        【解决方案8】:
        DateTime dt = new DateTime(args);
        String.Format("{0:ddd, MMM d, yyyy}", dt); 
        

        //“2008 年 3 月 9 日,星期日”

        【讨论】:

          【解决方案9】:

          使用以下代码:

          DateTime thisDate1 = new DateTime(2011, 6, 10);
          Console.WriteLine("Today is " + thisDate1.ToString("MMMM dd, yyyy") + ".");
          
          DateTimeOffset thisDate2 = new DateTimeOffset(2011, 6, 10, 15, 24, 16, 
                                                        TimeSpan.Zero);
          Console.WriteLine("The current date and time: {0:MM/dd/yy H:mm:ss zzz}", 
                             thisDate2); 
          // The example displays the following output:
          //    Today is June 10, 2011.
          //    The current date and time: 06/10/11 15:24:16 +00:00
          

          【讨论】:

          • 这不是被问到的......
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多