2010-04-28 46 views
22

Cách phân tích cú pháp chuỗi như 30:15 thành TimeSpan trong C#? 30:15 nghĩa là 30 giờ và 15 phút.Làm thế nào để phân tích cú pháp chuỗi với giờ lớn hơn 24 đến TimeSpan?

string span = "30:15"; 
TimeSpan ts = TimeSpan.FromHours(
    Convert.ToDouble(span.Split(':')[0])). 
    Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1])))); 

Điều này có vẻ không quá thanh lịch.

+0

hiện nó cần phải hỗ trợ nội địa hóa? (ví dụ: 30,15 theo cài đặt ngôn ngữ) –

+0

Định dạng sẽ luôn là hh: mm nhưng hh có thể xảy ra> 24. – jlp

+0

Xem [câu hỏi này] (http://stackoverflow.com/questions/26760/c-parse-string -to-timespan) (trùng lặp). – Ando

Trả lời

24

Nếu bạn chắc chắn rằng định dạng sẽ luôn luôn được "HH: mm" sau đó thử một cái gì đó như thế này:

string span = "35:15"; 
TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]), // hours 
          int.Parse(span.Split(':')[1]), // minutes 
          0);        // seconds 
+0

xấu xí, nhưng tôi đoán đó là cách để làm điều đó. cảm ơn – invalidusername

+2

điều này không hoạt động với một khoảng thời gian tiêu cực (-35: 15 sẽ dẫn đến -34: 45) – fubo

+0

cũng C# TimeSpan hoạt động nhưng làm cách nào bạn lưu trữ giá trị này trong MSSQL? Thời gian (7) không làm việc và chuỗi sẽ không được tốt đẹp. – MaxW

0

Thông thường người ta sẽ sử dụng TimeSpan.ParseExact nơi một định dạng cụ thể là bắt buộc. Nhưng các định dạng giờ duy nhất có thể được chỉ định là các phần của ngày (xem Custom TimeSpan Format Strings).

Vì vậy, bạn sẽ cần phải làm công việc bản thân:

string input = "30:24"; 
var parts = input.Split(':'); 
var hours = Int32.Parse(parts[0]); 
var minutes = Int32.Parse(parts[1]); 
var result = new TimeSpan(hours, minutes, 0); 

(Nhưng với một số kiểm tra lỗi.)

Ba nguyên constructor của khoảng thời gian cho phép giờ> = 24 tràn vào đếm ngày.

4

Tương tự như câu trả lời của Luke:

String span = "123:45"; 
Int32 colon = span.IndexOf(':'); 
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon - 1)), 
           Int32.Parse(span.Substring(colon + 1)), 0); 

Rõ ràng nó giả định chuỗi ban đầu là tốt được hình thành (gồm có hai phần tách ra bởi ruột và được phân tách để một số nguyên).

+0

Tôi nghĩ một tay cầm của Luke> 99 phải không? – jlp

+0

@Erik, @jlp: Có, tôi xử lý giờ lớn hơn 99 chỉ tốt, mặc dù câu trả lời ban đầu của tôi không (trước khi tôi chỉnh sửa nó nửa giờ trước). Có lẽ Erik đang nhìn vào câu trả lời cũ. – LukeH

+0

@Luke: Yup!Chính xác như bạn đã trả lời ở đây;) –

3

Tôi đang sử dụng một phương pháp đơn giản mà tôi nghĩ ra một thời gian dài trước đây và chỉ đăng tải ngày hôm nay để blog của tôi:

public static class TimeSpanExtensions 
{ 
    static int[] weights = { 60 * 60 * 1000, 60 * 1000, 1000, 1 }; 

    public static TimeSpan ToTimeSpan(this string s) 
    { 
     string[] parts = s.Split('.', ':'); 
     long ms = 0; 
     for (int i = 0; i < parts.Length && i < weights.Length; i++) 
      ms += Convert.ToInt64(parts[i]) * weights[i]; 
     return TimeSpan.FromMilliseconds(ms); 
    } 
} 

này có thể xử lý tình huống rất nhiều so với các giải pháp đơn giản hơn được cung cấp trước đó, nhưng có của nó thiếu sót riêng. Tôi thảo luận thêm về nó here.

Bây giờ, nếu bạn đang ở trong .NET 4 bạn có thể rút ngắn thời thực hiện ToTimeSpan tới:

public static TimeSpan ToTimeSpan(this string s) 
{ 
    return TimeSpan.FromMilliseconds(s.Split('.', ':') 
     .Zip(weights, (d, w) => Convert.ToInt64(d) * w).Sum()); 
} 

Bạn thậm chí có thể làm cho nó một one-liner nếu bạn không nhớ sử dụng trạng thái màn hình ngang .. .

+0

Giải pháp là OK nếu vấn đề chính xác như được mô tả trong câu hỏi. Nhưng nếu giá trị chuỗi TimeSpan giống như "1.06: 00: 00", giải pháp này không thành công. Thật không may, liên kết giải thích những thiếu sót không hoạt động. Meybe vấn đề này được thảo luận ở đó. – Florian

+0

@Florian Tôi đang chuyển blog của mình sang một máy chủ lưu trữ mới (và tốt hơn), đó là lý do tại sao ngoại tuyến của nó ngay bây giờ! Nó không hỗ trợ ngày, chỉ vài giờ. Vì vậy, nếu bạn muốn 24 + 6 giờ, bạn sẽ phải sử dụng 30:00:00. Ý tưởng là để tránh sử dụng ngày hoàn toàn. Những thiếu sót có liên quan nhiều hơn đến việc không hỗ trợ các giá trị âm ... – Loudenvier

1

Tương tự như câu trả lời của Lukes, với nhiều mã và phòng hơn để cải thiện. NHƯNG nó đề với tiêu cực Giờ ("-30: 15") là tốt, vì vậy có lẽ nó có thể giúp một ai đó.

public static double GetTotalHours(String s) 
    { 
     bool isNegative = false; 
     if (s.StartsWith("-")) 
      isNegative = true; 

     String[] splitted = s.Split(':'); 
     int hours = GetNumbersAsInt(splitted[0]); 
     int minutes = GetNumbersAsInt(splitted[1]); 

     if (isNegative) 
     { 
      hours = hours * (-1); 
      minutes = minutes * (-1); 
     } 
     TimeSpan t = new TimeSpan(hours, minutes, 0); 
     return t.TotalHours; 
    } 

public static int GetNumbersAsInt(String input) 
     { 
      String output = String.Empty; 
      Char[] chars = input.ToCharArray(0, input.Length); 
      for (int i = 0; i < chars.Length; i++) 
      { 
       if (Char.IsNumber(chars[i]) == true) 
        output = output + chars[i]; 
      } 
      return int.Parse(output); 
     } 

sử dụng

double result = GetTotalHours("30:15"); 
double result2 = GetTotalHours("-30:15"); 
Các vấn đề liên quan