Подтвердить что ты не робот

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

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

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

Вот что я получил прямо сейчас:

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

Пример выхода прямо сейчас будет Суббота, 31 января 2009 года в 1:34 вечера

4b9b3361

Ответ 1

Я бы лично отформатировал его в двух частях: часть non-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;
        }
    }
}

Ответ 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 для настройки многих других аспектов преобразования DateTime в string.

Ответ 3

РЕДАКТИРОВАТЬ: пример 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: другие идеи о том, как это сделать при Как форматировать DateTime like " 10, 2008 10:43 утра КНТ " в С#.

Ответ 4

Проблема с вышеприведенными подходами заключается в том, что основная причина, по которой вы используете строку формата, - это включить локализацию, а подходы, данные до сих пор, будут ломаться для любой страны или культуры, которые не хотят включать в себя окончательный am или pm. Итак, что я сделал, выписан метод расширения, который понимает дополнительную последовательность форматирования "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;
    }

Ответ 5

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

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