Domanda

Devo ottenere un formato DateTime personalizzato che includa il designatore AM / PM, ma voglio il " AM " oppure " PM " essere in minuscolo senza il resto dei caratteri in minuscolo.

È possibile usare un unico formato e senza usare una regex?

Ecco quello che ho in questo momento:

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

Un esempio dell'output in questo momento sarebbe sabato 31 gennaio 2009 alle 13:34

È stato utile?

Soluzione

Lo formatterei personalmente in due parti: la parte non am / pm e la parte am / pm con ToLower:

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

Un'altra opzione (che esaminerò tra un secondo) è quella di prendere l'attuale DateTimeFormatInfo, creare una copia e impostare i designatori am / pm sulla versione minuscola. Quindi utilizzare le informazioni sul formato per la normale formattazione. Dovresti memorizzare nella cache DateTimeFormatInfo, ovviamente ...

EDIT: nonostante il mio commento, ho comunque scritto la parte cache. Probabilmente non sarà più veloce del codice sopra (in quanto comporta un blocco e una ricerca nel dizionario) ma semplifica il codice chiamante:

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

Ecco un programma completo per dimostrare:

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;
        }
    }
}

Altri suggerimenti

È possibile dividere la stringa di formato in due parti, quindi minuscola la parte AM / PM, in questo modo:

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

Tuttavia, penso che la soluzione più elegante sia quella di utilizzare un DateTimeFormatInfo istanza che costruisci e sostituisci AMDesignator e PMDesignator proprietà con " am " e " pm " rispettivamente:

DateTimeFormatInfo fi = new DateTimeFormatInfo();

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

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

Puoi utilizzare l'istanza DateTime per personalizzare molti altri aspetti della trasformazione di string in <=>.

EDIT : l'esempio di Jon è molto migliore, anche se penso che il metodo di estensione sia ancora la strada da percorrere, quindi non è necessario ripetere il codice ovunque. Ho rimosso il primo esempio di Jon sostituito e sostituito sul metodo di estensione. Le mie app sono in genere app Intranet e non devo preoccuparmi delle culture non statunitensi.

Aggiungi un metodo di estensione per farlo per te.

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();

MODIFICA : altre idee su come farlo in Come formattare un DateTime come & Quot; Oct. 10, 2008 10:43 CST & Quot; in C # .

Il problema con gli approcci di cui sopra è che il motivo principale per cui si utilizza una stringa di formato è di abilitare la localizzazione e gli approcci forniti finora si spezzerebbero per qualsiasi paese o cultura che non desideri includere un am o pm finale. Quindi quello che ho fatto è stato scritto un metodo di estensione che comprende una sequenza di formato aggiuntiva 'TT' che indica una minuscola am / pm. Il codice seguente è sottoposto a debug per i miei casi, ma potrebbe non essere ancora perfetto:

    /// <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;
    }

Questo dovrebbe essere il più performante di tutte queste opzioni. Ma peccato che non potessero funzionare in un'opzione minuscola nel formato DateTime (tt opposto a TT?).

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top