Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get AM/PM for a date time in lowercase using only a datetime format

I'm to get a custom DateTime format including the AM/PM designator, but I want the "AM" or "PM" to be lowercase without making the rest of of the characters lowercase.

Is this possible using a single format and without using a regex?

Here's what I've got right now:

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

An example of the output right now would be Saturday, January 31, 2009 at 1:34PM

like image 669
Daniel Schaffer Avatar asked Jan 31 '09 19:01

Daniel Schaffer


People also ask

How do I display AM PM in date format?

There are two patterns that we can use in SimpleDateFormat to display time. Pattern “hh:mm aa” and “HH:mm aa”, here HH is used for 24 hour format without AM/PM and the hh is used for 12 hour format with AM/PM. aa – AM/PM marker. In this example we are displaying current date and time with AM/PM marker.


2 Answers

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;         }     } } 
like image 113
Jon Skeet Avatar answered Sep 21 '22 16:09

Jon Skeet


You could split the format string into two parts, and then lowercase the AM/PM part, like so:

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

However, I think the more elegant solution is to use a DateTimeFormatInfo instance that you construct and replace the AMDesignator and PMDesignator properties with "am" and "pm" respectively:

DateTimeFormatInfo fi = new DateTimeFormatInfo();  fi.AMDesignator = "am"; fi.PMDesignator = "pm";  string nowString = now.ToString("dddd, MMMM d, yyyy a\\t h:mmtt", fi); 

You can use the DateTimeFormatInfo instance to customize many other aspects of transforming a DateTime to a string.

like image 30
casperOne Avatar answered Sep 21 '22 16:09

casperOne