I would personally format it in two parts: the non-am/pm part, and the am/pm part with ToLower:
string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mm") +
item.PostedOn.ToString("tt").ToLower();
Another option (which I'll investigate in a sec) is to grab the current DateTimeFormatInfo, create a copy, and set the am/pm designators to the lower case version. Then use that format info for the normal formatting. You'd want to cache the DateTimeFormatInfo, obviously...
EDIT: Despite my comment, I've written the caching bit anyway. It probably won't be faster than the code above (as it involves a lock and a dictionary lookup) but it does make the calling code simpler:
string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mmtt",
GetLowerCaseInfo());
Here's a complete program to demonstrate:
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;
}
}
}