web-dev-qa-db-fra.com

Comment analyser un nom de mois (chaîne) en un entier pour comparaison en C #?

Je dois pouvoir comparer certains noms de mois que j'ai dans un tableau.

Ce serait bien s'il y avait un moyen direct comme:

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

Ma recherche sur Google semble suggérer que le seul moyen est d'écrire votre propre méthode, mais cela me semble être un problème assez commun pour que je pense qu'elle aurait déjà été implémentée dans .Net. Quelqu'un l'a déjà fait auparavant?

89
spilliton

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

Bien que, pour vos besoins, vous feriez probablement mieux de créer un Dictionary<string, int> mappant le nom du mois sur sa valeur.

167
James Curran

Vous pouvez faire quelque chose comme ça:

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

Si vous utilisez la méthode DateTime.ParseExact()- suggérée par plusieurs personnes, vous devez envisager avec soin ce que vous voulez qu'il se passe lorsque l'application s'exécute dans un environnement non anglais!

Au Danemark, lequel de ParseExact("Januar", ...) et ParseExact("January", ...) devrait fonctionner et lequel devrait échouer?

Ce sera la différence entre CultureInfo.CurrentCulture et CultureInfo.InvariantCulture.

19
Rasmus Faber

Vous pouvez utiliser la méthode DateTime.Parse pour obtenir un objet DateTime, puis vérifier sa propriété Month. Faites quelque chose comme ça:

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

L'astuce consiste à créer une date valide pour créer un objet DateTime.

8
Rune Grimstad

Vous pouvez utiliser un enum de mois:

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

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

Je ne suis pas sûr à 100% de la syntaxe de enum.Parse (), cependant.

7
Treb

Une solution simple serait de créer un dictionnaire avec des noms et des valeurs. Ensuite, en utilisant Contains (), vous pouvez trouver la bonne valeur.

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;
    }
}
7
Carlos A. Ortiz

Il n'est pas nécessaire de créer une instance DateTime pour cela. C'est aussi simple que cela:

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

Je cours sur le da-DK culture, donc ce test unitaire passe:

[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);
}

Je laisserai au lecteur le soin de créer une surcharge dans laquelle vous pourrez transmettre un CultureInfo explicite.

7
Mark Seemann

Et répondant à cette question sept ans après que la question a été posée, il est possible de faire cette comparaison en utilisant des méthodes intégrées:

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

devient

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

Ce qui peut être refactorisé dans une méthode d'extension pour plus de simplicité. Voici un exemple LINQPad (d'où les appels de méthode 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));
    }
}

Avec sortie:

False
True
True
2
David Clarke

Je le traduis en code C # en version espagnole, en ce qui concerne:

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";

        }

   }
1

Si vous utilisez c # 3.0 (ou supérieur), vous pouvez utiliser des extensions.

1
Adam Naylor
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

le code de précaution est en version bêta.

0
Thabiso

Ce que j'ai fait est d'utiliser SimpleDateFormat pour créer une chaîne de format, analyser le texte avec une date, puis extraire le mois à partir de cette date. Le code est ci-dessous:

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();
0
Ebenezer Ampiah