Pergunta

Eu preciso ser capaz de comparar alguns nomes de meses que eu tenho em uma matriz.

Seria bom se houvesse alguma maneira direta como:

Month.toInt("January") > Month.toInt("May")

My Google pesquisa parece sugerir a única maneira é escrever seu próprio método, mas este parece ser um problema bastante comum que eu acho que já teria sido implementado em .Net, ninguém fez isso antes?

Foi útil?

Solução

DateTime.ParseExact(monthName, "MMMM", CultureInfo.CurrentCulture ).Month

Embora, para suas finalidades, você provavelmente vai ser melhor fora apenas a criação de um Dictionary<string, int> mapeando o nome do mês para o seu valor.

Outras dicas

Você poderia fazer algo parecido com isto:

Convert.ToDate(month + " 01, 1900").Month

Se você usar o DateTime.ParseExact()-método que várias pessoas têm sugerido, você deve considerar cuidadosamente o que você quer que aconteça quando o aplicativo é executado em um ambiente não-Inglês!

Na Dinamarca, o que ParseExact("Januar", ...) e ParseExact("January", ...) deve trabalhar e que deve falhar?

Essa será a diferença entre CultureInfo.CurrentCulture e CultureInfo.InvariantCulture.

Você pode usar o método DateTime.Parse para obter um objeto DateTime e, em seguida, verificar a sua propriedade mês. Fazer algo como isto:

int month = DateTime.Parse("1." + monthName + " 2008").Month;

O truque é construir uma data válida para criar um objeto DateTime.

Você pode usar uma enumeração de meses:

public enum Month
{
    January,
    February,
    // (...)
    December,
}    

public Month ToInt(Month Input)
{
    return (int)Enum.Parse(typeof(Month), Input, true));
}

Não estou 100% certo sobre a sintaxe para Enum.Parse (), no entanto.

Você não tem que criar uma instância de DateTime para fazer isso. É tão simples como isto:

public static class Month
{
    public static int ToInt(this string month)
    {
        return Array.IndexOf(
            CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
            month.ToLower(CultureInfo.CurrentCulture))
            + 1;
    }
}

Estou correndo na cultura da-DK, de modo que este teste de unidade passa:

[Theory]
[InlineData("Januar", 1)]
[InlineData("Februar", 2)]
[InlineData("Marts", 3)]
[InlineData("April", 4)]
[InlineData("Maj", 5)]
[InlineData("Juni", 6)]
[InlineData("Juli", 7)]
[InlineData("August", 8)]
[InlineData("September", 9)]
[InlineData("Oktober", 10)]
[InlineData("November", 11)]
[InlineData("December", 12)]
public void Test(string monthName, int expected)
{
    var actual = monthName.ToInt();
    Assert.Equal(expected, actual);
}

Vou deixar isso como um exercício para o leitor a criar uma sobrecarga onde você pode passar um CultureInfo explícito.

Uma solução simples seria criar um dicionário com nomes e valores. Em seguida, usando Contém () você pode encontrar o valor correto.

Dictionary<string, string> months = new Dictionary<string, string>()
{
                { "january", "01"},
                { "february", "02"},
                { "march", "03"},
                { "april", "04"},
                { "may", "05"},
                { "june", "06"},
                { "july", "07"},
                { "august", "08"},
                { "september", "09"},
                { "october", "10"},
                { "november", "11"},
                { "december", "12"},
};
foreach (var month in months)
{
    if (StringThatContainsMonth.ToLower().Contains(month.Key))
    {
        string thisMonth = month.Value;
    }
}

E responder a esta sete anos após a pergunta foi feita, é possível fazer esta comparação usando built-in métodos:

Month.toInt("January") > Month.toInt("May")

se torna

Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
                 t => t.Equals("January", StringComparison.CurrentCultureIgnoreCase)) >
Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
                 t => t.Equals("May", StringComparison.CurrentCultureIgnoreCase))

O que pode ser reformulado em um método de extensão para simplificar. O seguinte é um exemplo LINQPad (daí as chamadas de método Dump()):

void Main()
{
    ("January".GetMonthIndex() > "May".GetMonthIndex()).Dump();
    ("January".GetMonthIndex() == "january".GetMonthIndex()).Dump();
    ("January".GetMonthIndex() < "May".GetMonthIndex()).Dump();
}

public static class Extension {
    public static int GetMonthIndex(this string month) {
        return Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
                         t => t.Equals(month, StringComparison.CurrentCultureIgnoreCase));
    }
}

Com saída:

False
True
True

Se você estiver usando c # 3.0 (ou superior) você pode usar extensores

Eu traduzi-lo em código C # na versão em espanhol, diz respeito:

public string ObtenerNumeroMes(string NombreMes){

       string NumeroMes;   

       switch(NombreMes) {

        case ("ENERO") :
            NumeroMes = "01";
            return NumeroMes;

        case ("FEBRERO") :
            NumeroMes = "02";
            return NumeroMes;

        case ("MARZO") :
            NumeroMes = "03";
            return NumeroMes;

        case ("ABRIL") :
            NumeroMes = "04";
            return NumeroMes;

        case ("MAYO") :
            NumeroMes = "05";
            return NumeroMes;

        case ("JUNIO") :
            NumeroMes = "06";
            return NumeroMes;

        case ("JULIO") :
            NumeroMes = "07";
            return NumeroMes;

        case ("AGOSTO") :
            NumeroMes = "08";
            return NumeroMes;

        case ("SEPTIEMBRE") :
            NumeroMes = "09";
            return NumeroMes;

        case ("OCTUBRE") :
            NumeroMes = "10";
            return NumeroMes;

        case ("NOVIEMBRE") :
            NumeroMes = "11";
            return NumeroMes;

        case ("DICIEMBRE") :
            NumeroMes = "12";
            return NumeroMes;

            default:
            Console.WriteLine("Error");
            return "ERROR";

        }

   }
Public Function returnMonthNumber(ByVal monthName As String) As Integer
    Select Case monthName.ToLower
        Case Is = "january"
            Return 1
        Case Is = "february"
            Return 2
        Case Is = "march"
            Return 3
        Case Is = "april"
            Return 4
        Case Is = "may"
            Return 5
        Case Is = "june"
            Return 6
        Case Is = "july"
            Return 7
        Case Is = "august"
            Return 8
        Case Is = "september"
            Return 9
        Case Is = "october"
            Return 10
        Case Is = "november"
            Return 11
        Case Is = "december"
            Return 12
        Case Else
            Return 0
    End Select
End Function

código de cautela é a versão Beta.

O que eu fiz foi usar SimpleDateFormat para criar uma seqüência de formato, e analisar o texto para uma data, e depois recuperar o mês a partir daí. O código está abaixo:

int year = 2012 \\or any other year
String monthName = "January" \\or any other month
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
int monthNumber = format.parse("01-" + monthName + "-" + year).getMonth();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top