1

たとえば、日付をstring.formatし、文字列「または」をフォーマットパターンで使用すると、それを日付の序数値に変換したいとします。

すなわち

string.Format("{0:ddor MMM yyyy}.", DateTime.Now)

出力する必要があります

1st Jan 2010

序数の導出方法については、以下を参照してください。

.NET で数字の末尾を "st"、"nd"、"rd"、"th" にする簡単な方法はありますか?

4

2 に答える 2

2

みたいなものはないようです。

それを行うための最も推奨される方法:

var d = DateTime.Now;
var result2 = String.Format("{0:dd}{1} {2:MMM yyyy}", d, Ordinal(d.Day), d);

それを達成するための非常にハックな方法は、カスタムを作成することですIFormatProvider。IMOそれは大変な問題ですが、別の方法を示すだけです...(私はこれについてあまり経験がありません。あまり「正しい」とは言えないかもしれません)

using System;

namespace Test
{
    class Program
    {
        public static string Ordinal(int number)
        {
            string suffix = String.Empty;

            int ones = number % 10;
            int tens = (int)Math.Floor(number / 10M) % 10;

            if (tens == 1)
            {
                suffix = @"\t\h";
            }
            else
            {
                switch (ones)
                {
                    case 1:
                        suffix = @"\s\t";
                        break;

                    case 2:
                        suffix = @"\n\d";
                        break;

                    case 3:
                        suffix = @"\r\d";
                        break;

                    default:
                        suffix = @"\t\h";
                        break;
                }
            }
            return suffix;
        }

        public class MyFormat : IFormatProvider, ICustomFormatter
        {
            public object GetFormat(Type formatType)
            {
                return (formatType == typeof(ICustomFormatter)) ? this : null;

            }

            public string Format(string format, object arg, IFormatProvider formatProvider)
            {
                var d = (DateTime)arg;

                var or = Ordinal(d.Day);

                format = format.Replace("or", or);

                return d.ToString(format);
            }
        }
        static void Main(string[] args)
        {
            var result = String.Format(new MyFormat(), "{0:ddor MMM yyyy}.", DateTime.Now);

            return;
        }
    }
}

カスタム IFormatProvider の詳細

于 2010-10-13T01:43:31.847 に答える
1

フォーマット プロバイダーはプラグ可能ですが、私の知る限り、特定のタイプの既定のフォーマット プロバイダーを設定することはできません。通常、慣例によりフォーマット文字列を受け取るメソッドには、IFormatProvider を受け取るオーバーロードもあります。MyFormatProvider : IFormatProviderと MyCustomFormatter : ICustomFormatterなどの 2 つのクラスを実装できます。

「{0:dd}{0:or} {0:MMM} {0:yyyy}」などのフォーマット文字列が処理されると、ICustomFormatter は「dd」、「or」、「MMM」を使用して 4 回呼び出されます。 "、および "yyyy" をパラメーターとして使用して、各部分を個別にフォーマットできるようにします。「or」ケースを処理し、残りをデフォルトのフォーマット プロバイダーに渡すだけです。

ただし、呼び出し元は、フォーマット時にカスタム フォーマット プロバイダーのインスタンスを渡す必要があります。例えば:

string str = String.Format(MyFormatProvider.Default, "{0:dd}{0:or} {0:MMM} {0:yyyy}", date);

私の知る限り、その要件を逃れることはできません。「1時間前」、「3日前」などのDateTimeを表示する「相対」DateTimeフォーマット文字列を作成したとき、しばらく前にもっと良い方法を探しました。カスタム IFormatProvider を渡します。

于 2010-10-13T02:10:26.447 に答える