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

StackOverflow https://stackoverflow.com/questions/499393

Вопрос

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

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

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

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

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

Это было полезно?

Решение

Я бы лично разделил его на две части:часть, не относящаяся к am / pm, и часть am / pm с меньшим:

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

Другие советы

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

Редактировать:Пример Джона намного лучше, хотя я думаю, что метод расширения по-прежнему является правильным решением, поэтому вам не нужно повторять код повсюду.Я удалил replace и заменил первый пример Джона на место в методе extension.Мои приложения, как правило, являются приложениями для внутренней сети, и мне не нужно беспокоиться о культуре других стран.

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

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

Редактировать:Другие идеи о том, как это сделать, на Как отформатировать дату и время типа "Окт.10, 2008 10:43 утра по восточному времени" в C#.

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

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

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top