1
\$\begingroup\$

I have piece metaled this code together from multiple google searches and thanks to the function from the site mentioned in the code. I am sure there are ways to optimize this for speed. What do you guys suggest?

using System;
using System.Globalization;

public class Program
{
    public static void Main()
    {
        string shortmonth = "Mar";
        string num = GetMonthNumberFromAbbreviation(shortmonth);
        string monthname = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(Convert.ToInt32(num));
        Console.WriteLine(monthname);
    }
    //https://blogs.msmvps.com/deborahk/converting-month-abbreviations-to-month-numbers/
    private static string GetMonthNumberFromAbbreviation(string mmm) 
    { 
       string[] monthAbbrev = 
          CultureInfo.CurrentCulture.DateTimeFormat.AbbreviatedMonthNames; 
       int index  = Array.IndexOf(monthAbbrev, mmm) + 1; 
       return index.ToString("0#"); 
    }
}
\$\endgroup\$
1
  • 4
    \$\begingroup\$ So you pass in the 3-letter English month abbreviation and expect the full name in the current locale. This mix of languages should be documented in the function's comment. \$\endgroup\$ Commented Mar 14, 2019 at 7:30

2 Answers 2

4
\$\begingroup\$

The following avoids assumptions about and/or the need to convert according to culture, by letting the tried-and-tested DateTime plumbing do the work. Creating a translation map once at first instantiation of the class (the static constructor) is the best I can think of to optimise performance.

If you use it, don't forget to do error-checking - specifically the result of TryParse.

using System;
using System.Collections.Generic;

public class Program
{
  private static readonly Dictionary<string, string> MonthNameMap;
  //  Static constructor to build the translation dictionary once
  static Program()
  {
    MonthNameMap = new Dictionary<string, string>();
    //var months = new List<string>() { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    //foreach (var shortMonthString in months)
    //{
    //  DateTime.TryParse($"1 {shortMonthString} 2000", out var dt);
    //  MonthNameMap.Add(shortMonthString, dt.ToString("MMMM"));
    //}
    for (int i = 1; i <= 12; i++)
    {
      DateTime.TryParse($"2000-{i}-25", out var dt);
      MonthNameMap.Add(dt.ToString("MMM"), dt.ToString("MMMM"));
    }
  }

  public static void Main()
  {
    foreach (var entry in MonthNameMap)
    {
      Console.WriteLine($"{entry.Key}: {entry.Value}");
    }
  }
}

Results:

Jan: January
Feb: February
Mar: March
Apr: April
May: May
Jun: June
Jul: July
Aug: August
Sep: September
Oct: October
Nov: November
Dec: December
\$\endgroup\$
0
0
\$\begingroup\$

You can speed up the program by changing the return type from string to int. If it's a number (of the kind you can do calculations with, not something like a phone number), it should be represented as an int, not as a string.

As long as you can ensure that the locale doesn't change, you can cache the full month names in an array.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.