Is there a way in DateTime format strings to have include just the first letter of the month?
new DateTime(2015, 1, 12).ToString("M-dd-yy") // "1-12-15",  but I want "J-02-15"
new DateTime(2000, 11, 7).ToString("M-dd-yy") // "11-07-00", but I want "N-17-00"
If not, is there some way to add a new, custom format to the system-wide IFormatProvider to handle this?
Note for the "why are you trying to do it that way?" people: This is for a vendor's chart control, which only accepts a format string. We are trying to make these dates as short as possible, and they are for international users, so numbers for the month won't work. I can't pass in a new IFormatProvider, so I would have to somehow modify the existing IFormatProvider (hopefully without breaking it).
To do this, you use the "MM/yyyy" format string. The format string uses the current culture's date separator. Getting a string that contains the date and time in a specific format. For example, the "MM/dd/yyyyHH:mm" format string displays the date and time string in a fixed format such as "19//03//2013 18:06".
Terrestrial Time (TT) is a modern astronomical time standard defined by the International Astronomical Union, primarily for time-measurements of astronomical observations made from the surface of Earth.
Use datetime. strftime(format) to convert a datetime object into a string as per the corresponding format . The format codes are standard directives for mentioning in which format you want to represent datetime. For example, the %d-%m-%Y %H:%M:%S codes convert date to dd-mm-yyyy hh:mm:ss format.
The "fff" custom format specifier represents the three most significant digits of the seconds fraction; that is, it represents the milliseconds in a date and time value.
Let's dig a bit into DateTime.ToString() implementation. When no IFormatProvider object is passed to it, it will use System.Globalization.DateTimeFormatInfo.CurrentInfo as the DateTimeFormatInfo object to get information on how to build string representation. CurrentInfo, in turn, gets it from Thread.CurrentThread.CurrentCulture.
So you'd want to set up current thread culture in a way, that it has one character month names (or abbreviations as in example below), then use regular format string. One way to achieve this is the following:
using System;
using System.Globalization;
using System.Threading;
namespace DTFTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var dt = DateTime.Now;
            Thread.CurrentThread.CurrentCulture = new CultureInfo("EN-US", true);
            var ci = Thread.CurrentThread.CurrentCulture;
            var monthNames = new[] { "J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D", string.Empty };
            ci.DateTimeFormat.AbbreviatedMonthNames = monthNames;
            Console.WriteLine(dt.ToString("MMM-dd-yyyy"));
        }
    }
}
Here's a solution using a customized FormatProvider:
    public static class SingleLetterMonthNameFormatter
    {
        private static IFormatProvider _formatProvider;
        public static IFormatProvider FormatProvider
        {
            get
            {
                if (_formatProvider == null)
                {
                    var dtfi = new DateTimeFormatInfo();
                    dtfi.AbbreviatedMonthNames = dtfi.MonthNames.Select(x => x.FirstOrDefault().ToString()).ToArray();
                    _formatProvider = dtfi;
                }
                return _formatProvider;
            }
        }
    }
You can use it like this:
var monthName = DateTime.Now.ToString("MMM", SingleLetterMonthNameFormatter.FormatProvider) //First letter of month name
If there's no way to pass a FormatProvider to the method you want, there's a nasty way to do it, use with care!
    var currentCulture = Thread.CurrentThread.CurrentCulture.Clone() as CultureInfo;
    currentCulture.DateTimeFormat = SingleLetterMonthNameFormatter.FormatProvider as DateTimeFormatInfo;
    Thread.CurrentThread.CurrentCulture = currentCulture;
    Console.WriteLine(DateTime.Now.ToString("MMM"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With