Получить AM / PM для даты и времени в нижнем регистре, используя только формат даты и времени - PullRequest
46 голосов
/ 31 января 2009

Мне нужно получить пользовательский формат DateTime, включая обозначение AM / PM, но я хочу, чтобы «AM» или «PM» были строчными без , чтобы остальные символы были строчными.

Возможно ли это с использованием одного формата и без использования регулярных выражений?

Вот что у меня сейчас есть:

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

Примером выходных данных сейчас может быть Суббота, 31 января 2009 г., в 13:34 * * 011 * * 10101

Ответы [ 5 ]

61 голосов
/ 31 января 2009

Я бы лично отформатировал его в двух частях: часть не-am / pm и часть am / pm с ToLower:

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

Другой вариант (который я расскажу через секунду) - захват текущего DateTimeFormatInfo, создание копии и установка указателей am / pm в строчную версию. Затем используйте эту информацию о формате для нормального форматирования. Вы бы хотели кэшировать 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;
        }
    }
}
20 голосов
/ 31 января 2009

Вы можете разделить строку формата на две части, а затем прописать строчную часть 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, чтобы настроить многие другие аспекты преобразования DateTime в string.

1 голос
/ 19 декабря 2011

Проблема с вышеупомянутыми подходами состоит в том, что основная причина, по которой вы используете строку формата, заключается в том, чтобы включить локализацию, и приведенные выше подходы будут нарушены для любой страны или культуры, которые не хотят включать в себя окончание утра или вечера. Итак, я написал метод расширения, который понимает дополнительную последовательность форматов 'TT', которая обозначает строчную букву am / pm. Приведенный ниже код отлажен для моих случаев, но, возможно, еще не идеален:

    /// <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 голос
/ 31 января 2009

РЕДАКТИРОВАТЬ : пример Джона гораздо лучше, хотя я думаю, что метод расширения все еще не решен, поэтому вам не нужно повторять код везде. Я удалил замену и заменил первый пример Джона на место в методе расширения. Мои приложения, как правило, являются приложениями для внутренней сети, и мне не нужно беспокоиться о неамериканских культурах.

Добавьте метод расширения, чтобы сделать это для вас.

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

РЕДАКТИРОВАТЬ : Другие идеи о том, как сделать это в Как отформатировать DateTime, например "10 октября 2008 г. 10:43 CST" в C # .

0 голосов
/ 15 марта 2013

Это должен быть самый производительный из всех этих вариантов. Но очень жаль, что они не могли работать в строчном варианте в формате DateTime (тт напротив TT?).

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