wake-up-neo.com

Holen Sie sich AM/PM für eine Datumszeit in Kleinbuchstaben und verwenden Sie nur ein Datumsformat

Ich möchte ein benutzerdefiniertes DateTime-Format erhalten, das den AM/PM-Bezeichner enthält, aber "AM" oder "PM" soll sein, ohne dass den Rest der Zeichen zu Kleinbuchstaben macht.

Ist dies mit einem einzigen Format und ohne Regex möglich?

Hier ist was ich gerade habe:

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

Ein Beispiel für die Ausgabe im Moment wäre Samstag, 31. Januar 2009, 13:34 Uhr

44
Daniel Schaffer

Ich würde es persönlich in zwei Teile formatieren: den Nicht-am/pm-Teil und den am/pm-Teil mit ToLower:

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

Eine andere Option (die ich in einer Sekunde untersuchen werde) ist das aktuelle DateTimeFormatInfo zu nehmen, eine Kopie zu erstellen und die am/pm-Bezeichner auf die Kleinbuchstabenversion zu setzen. Verwenden Sie dann diese Formatinformationen für die normale Formatierung. Sie möchten DateTimeFormatInfo zwischenspeichern, natürlich ...

EDIT: Trotz meines Kommentars habe ich sowieso das Caching-Bit geschrieben. Es ist wahrscheinlich nicht schneller als der obige Code (da dies eine Sperre und eine Wörterbuchsuche nach sich zieht), aber der aufrufende Code wird dadurch einfacher:

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

Hier ist ein komplettes Programm zur Demonstration:

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;
        }
    }
}
60
Jon Skeet

Sie können die Formatzeichenfolge in zwei Teile aufteilen und dann den AM/PM-Teil wie folgt kleinschreiben:

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

Ich denke jedoch, die elegantere Lösung ist die Verwendung einer DateTimeFormatInfo-Instanz , die Sie erstellen und die AMDesignator - und /PMDesignator - Eigenschaften durch "am" bzw. "pm" ersetzen:

DateTimeFormatInfo fi = new DateTimeFormatInfo();

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

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

Sie können die DateTimeFormatInfo-Instanz verwenden, um viele andere Aspekte der Transformation einer DateTime in eine string anzupassen.

20
casperOne

Das Problem bei den oben genannten Ansätzen ist, dass der Hauptgrund für die Verwendung einer Formatzeichenfolge darin besteht, die Lokalisierung zu aktivieren, und die bisher angegebenen Ansätze würden für jedes Land oder jede Kultur, die kein abschließendes AM oder PM enthalten möchte, brechen. Was ich also getan habe, ist eine Erweiterungsmethode, die eine zusätzliche Formatsequenz 'TT' versteht, die ein Kleinbuchstabe am/pm bedeutet. Der folgende Code wurde für meine Fälle debuggt, ist aber möglicherweise noch nicht perfekt:

    /// <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;
    }
1
Adam Wise

EDIT: Jons Beispiel ist viel besser, obwohl ich denke, dass die Erweiterungsmethode immer noch der Weg ist, so dass Sie den Code nicht überall wiederholen müssen. Ich habe das Ersetzen entfernt und Jons erstes Beispiel in der Erweiterungsmethode ersetzt. Meine Apps sind normalerweise Intranet-Apps, und ich muss mir keine Sorgen um Kulturen außerhalb der USA machen.

Fügen Sie eine Erweiterungsmethode hinzu, um dies für Sie durchzuführen.

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: Weitere Ideen dazu finden Sie unter Formatieren einer DateTime wie "10. Oktober 2008, 10:43 Uhr CST" in C # .

1
tvanfosson

Dies sollte die leistungsfähigste aller Optionen sein. Zu schade, dass sie nicht in Kleinbuchstaben in das DateTime-Format (TT gegenüber TT?) Passen konnten.

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }
0