2008-11-03 31 views
84

Tôi cần để có thể so sánh một số tháng tên tôi có trong một mảng.Làm cách nào để phân tích một tên tháng (chuỗi) thành một số nguyên để so sánh trong C#?

Nó sẽ được tốt đẹp nếu có một số cách trực tiếp như:

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

tìm kiếm Google của tôi dường như gợi ý cách duy nhất là viết phương pháp riêng của mình, nhưng điều này có vẻ như một vấn đề đủ phổ biến mà tôi sẽ nghĩ rằng nó đã được thực hiện trong. Net, bất cứ ai đã làm điều này trước đây?

Trả lời

142

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

Mặc dù, đối với mục đích của bạn, có thể bạn sẽ được tốt hơn off chỉ cần tạo một Dictionary<string, int> lập bản đồ tên của tháng với giá trị của nó.

+11

Hãy chắc chắn xem xét http://stackoverflow.com/questions/258793/how-to-parse-a-month-name-string-to-an-integer-for-comparison-in-c#258895 khi quyết định xem có nên sử dụng CultureInfo.CurrentCulture hoặc CultureInfo.InvariantCulture –

1

Nếu bạn đang sử dụng C# 3.0 (hoặc cao hơn), bạn có thể sử dụng chất độn

+0

Tôi đang sử dụng .net 2.0 – spilliton

+0

Sau đó, vâng, tiếc là tôi nghĩ rằng phương pháp riêng của bạn sẽ là giải pháp thanh lịch nhất. –

18

Bạn có thể làm một cái gì đó như thế này:

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

Bạn có thể sử dụng phương pháp DateTime.Parse để có được một đối tượng DateTime và sau đó kiểm tra tài sản theo tháng của nó. Làm điều gì đó như sau:

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

Bí quyết là tạo ngày hợp lệ để tạo đối tượng DateTime.

7

Bạn có thể sử dụng một enum tháng:

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

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

Tôi không chắc chắn 100% về cú pháp cho Enum.Parse(), mặc dù.

+1

Nó sẽ cần phải là "tháng công cộng ToInt (chuỗi đầu vào) {...}" nhưng nếu không nó là chính xác. –

+1

Tôi biết đây là một nhận xét cũ nhưng tôi nghĩ bạn nên bắt đầu enum của mình từ 1, ví dụ: 'public enum Month {January = 1, Feburary}' và cũng chuyển thành int thay vì Month. – eth0

+0

@ eth0: Rất tiếc ... bạn đã đúng. Sửa chữa nó, nhờ chỉ nó ra ;-) – Treb

18

Nếu bạn sử dụng phương pháp DateTime.ParseExact() mà một số người đã đề xuất, bạn nên cẩn thận xem xét những gì bạn muốn xảy ra khi ứng dụng chạy trong môi trường không phải tiếng Anh!

Ở Đan Mạch, trong đó ParseExact("Januar", ...)ParseExact("January", ...) sẽ hoạt động và điều gì sẽ thất bại?

Đó sẽ là sự khác biệt giữa CultureInfo.CurrentCultureCultureInfo.InvariantCulture.

0
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 

mã cảnh báo là trong phiên bản Beta.

+0

câu trả lời được chấp nhận là tốt hơn nhiều. –

0

Điều tôi đã làm là sử dụng SimpleDateFormat để tạo chuỗi định dạng và phân tích văn bản thành ngày, sau đó truy lục tháng từ đó. Mã bên dưới:

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(); 
+1

Mã này không phải là C#. Đó là Java. – Indian

5

Bạn không phải tạo phiên bản DateTime để thực hiện việc này. Nó cũng đơn giản như thế này:

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

Tôi đang chạy trên nền văn hóa da-DK, vì vậy kiểm tra đơn vị này đi:

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

tôi sẽ để nó như một bài tập cho người đọc để tạo ra một tình trạng quá tải nơi bạn có thể vượt qua trong một CultureInfo rõ ràng.

+0

Sử dụng tốt 'ToLower()' - Tôi không biết một trong những quá tải chuyển đổi chuỗi 'bằng cách sử dụng các quy tắc vỏ của văn hóa được chỉ định' mặc dù công bằng không rõ ràng từ tên phương thức mà nó có thể đủ khả năng. –

+0

Ok, vì vậy tôi đã thử nghiệm điều này bằng cách sử dụng LINQPad và tôi không thể làm cho nó hoạt động trong 'CurrentCulture' của tôi. Cả hai '" Tháng Giêng ".ToLower (CultureInfo.CurrentCulture) .Dump();' và '" Tháng Giêng ".Lên (mới CultureInfo (" en-NZ ")). Dump();' output 'january' nhưng tên tháng là được viết hoa trong 'CurrentCulture.DateTimeFormat.MonthNames'. –

+1

@DavidClarke Vâng, vâng, bạn * đang * gọi một hàm có tên là 'ToLower' :) Trên thực tế, có một lỗ hổng hợp lý nhỏ trong mã của tôi, vì tên tháng * được * cho dưới dạng tất cả chữ thường trong da-DK. Vì vậy, một trong hai không nên thấp hơn trường hợp đầu vào, hoặc người nào khác cũng nên thấp hơn trường hợp tất cả các tên tháng - tùy thuộc vào việc một trận đấu không phân biệt dạng chữ là mong muốn hay không. –

1

tôi dịch nó thành mã C# trong phiên bản tiếng Tây Ban Nha, liên quan:

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

     } 

    } 
5

Một cách đơn giản giải pháp sẽ được tạo ra một từ điển với tên và giá trị. Sau đó sử dụng Contains(), bạn có thể tìm thấy giá trị phù hợp.

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; 
    } 
} 
1

Và trả lời này bảy năm sau khi câu hỏi được hỏi, người ta có thể làm sự so sánh này sử dụng phương pháp built-in:

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

trở thành

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

Mà có thể được refactored vào một phương pháp mở rộng để đơn giản. Sau đây là một ví dụ LINQPad (vì thế các cuộc gọi Dump() phương pháp):

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

Với đầu ra:

False 
True 
True 
Các vấn đề liên quan