53

AM/PM 指定子を含むカスタム DateTime 形式を取得する予定ですが、残りの文字を小文字にせずに「AM」または「PM」を小文字にしたいです。

これは、正規表現を使用せずに単一の形式を使用して可能ですか?

これが私が今持っているものです:

item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mmtt")

現在の出力の例は、2009 年 1 月 31 日土曜日の午後 1 時 34 分です。

4

5 に答える 5

65

個人的には、午前/午後以外の部分と、ToLower を使用した午前/午後の部分の 2 つの部分にフォーマットします。

string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mm") +
                   item.PostedOn.ToString("tt").ToLower();

もう 1 つのオプション (後で調べます) は、現在の DateTimeFormatInfo を取得し、コピーを作成して、午前/午後指定子を小文字バージョンに設定することです。次に、そのフォーマット情報を通常のフォーマットに使用します。明らかに、DateTimeFormatInfo をキャッシュしたいでしょう...

編集:私のコメントにもかかわらず、とにかくキャッシングビットを書きました。おそらく上記のコードよりも高速ではありませんが(ロックと辞書検索が必要なため)、呼び出しコードはより単純になります。

string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mmtt",
                                          GetLowerCaseInfo());

デモ用の完全なプログラムを次に示します。

using System;
using System.Collections.Generic;
using System.Globalization;

public class Test
{
    static void Main()
    {
        Console.WriteLine(DateTime.Now.ToString("dddd, MMMM d, yyyy a\\t h:mmtt",
                                                GetLowerCaseInfo());
    }

    private static readonly Dictionary<DateTimeFormatInfo,DateTimeFormatInfo> cache =
        new Dictionary<DateTimeFormatInfo,DateTimeFormatInfo>();

    private static object cacheLock = new object();

    public static DateTimeFormatInfo GetLowerCaseInfo()
    {
        DateTimeFormatInfo current = CultureInfo.CurrentCulture.DateTimeFormat;
        lock (cacheLock)
        {
            DateTimeFormatInfo ret;
            if (!cache.TryGetValue(current, out ret))
            {
                ret = (DateTimeFormatInfo) current.Clone();
                ret.AMDesignator = ret.AMDesignator.ToLower();
                ret.PMDesignator = ret.PMDesignator.ToLower();
                cache[current] = ret;
            }
            return ret;
        }
    }
}
于 2009-01-31T19:39:40.403 に答える
26

次のように、書式文字列を 2 つの部分に分割し、AM/PM の部分を小文字にすることができます。

DateTime now = DateTime.Now;
string nowString = now.ToString("dddd, MMMM d, yyyy a\\t h:mm");
nowString = nowString + now.ToString("tt").ToLower();

ただし、より洗練された解決策は、作成したDateTimeFormatInfoインスタンスAMDesignatorを使用し、プロパティとPMDesignatorプロパティをそれぞれ「am」と「pm」に置き換えることだと思います。

DateTimeFormatInfo fi = new DateTimeFormatInfo();

fi.AMDesignator = "am";
fi.PMDesignator = "pm";

string nowString = now.ToString("dddd, MMMM d, yyyy a\\t h:mmtt", fi);

インスタンスを使用して、から へDateTimeFormatInfoの変換の他の多くの側面をカスタマイズできます。DateTimestring

于 2009-01-31T19:49:44.440 に答える
1

上記のアプローチの問題は、フォーマット文字列を使用する主な理由はローカリゼーションを有効にすることであり、これまでに示したアプローチは、最終的な午前または午後を含めたくない国や文化では機能しないことです。だから私がやったことは、小文字の午前/午後を意味する追加のフォーマットシーケンス「TT」を理解する拡張メソッドを書き出すことです。以下のコードは私の場合のためにデバッグされていますが、まだ完全ではない可能性があります。

    /// <summary>
    /// Converts the value of the current System.DateTime object to its equivalent string representation using the specified format.  The format has extensions over C#s ordinary format string
    /// </summary>
    /// <param name="dt">this DateTime object</param>
    /// <param name="formatex">A DateTime format string, with special new abilities, such as TT being a lowercase version of 'tt'</param>
    /// <returns>A string representation of value of the current System.DateTime object as specified by format.</returns>
    public static string ToStringEx(this DateTime dt, string formatex)
    {
        string ret;
        if (!String.IsNullOrEmpty(formatex))
        {
            ret = "";
            string[] formatParts = formatex.Split(new[] { "TT" }, StringSplitOptions.None);
            for (int i = 0; i < formatParts.Length; i++)
            {
                if (i > 0)
                {
                    //since 'TT' is being used as the seperator sequence, insert lowercase AM or PM as appropriate
                    ret += dt.ToString("tt").ToLower();
                }
                string formatPart = formatParts[i];
                if (!String.IsNullOrEmpty(formatPart))
                {
                    ret += dt.ToString(formatPart);
                }
            }
        }
        else
        {
            ret = dt.ToString(formatex);
        }
        return ret;
    }
于 2011-12-19T18:47:37.780 に答える
1

編集:Jonの例ははるかに優れていますが、拡張メソッドはまだ進むべき道だと思うので、コードをどこでも繰り返す必要はありません。置換を削除し、Jon の最初の例を拡張メソッドに置き換えました。私のアプリは通常イントラネット アプリであり、米国以外の文化について心配する必要はありません。

これを行う拡張メソッドを追加します。

public static class DateTimeExtensions
{
    public static string MyDateFormat( this DateTime dateTime )
    {
       return dateTime.ToString("dddd, MMMM d, yyyy a\\t h:mm") +
              dateTime.ToString("tt").ToLower();
    }
}

...

item.PostedOn.MyDateFormat();

EDIT : How to format a DateTime like "Oct. 10, 2008 10:43am CST" in C# でこれを行う方法に関するその他のアイデア。

于 2009-01-31T19:33:35.407 に答える
0

これは、これらすべてのオプションの中で最もパフォーマンスが高いはずです。しかし残念なことに、DateTime 形式の小文字オプションでは機能しませんでした (TT の反対の tt?)。

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }
于 2013-03-14T21:54:58.677 に答える