2008-09-15 31 views
13

Có phương pháp thư viện chuẩn nào chuyển đổi chuỗi có thời lượng trong khoảng thời gian chuẩn ISO 8601 (cũng được sử dụng trong XSD cho định dạng loại duration) của nó vào đối tượng .NET TimeSpan không?Làm thế nào để chuyển đổi ISO 8601 Thời gian để TimeSpan trong VB.Net?

Ví dụ: P0DT1H0M0S đại diện cho thời lượng một giờ, được chuyển đổi thành TimeSpan mới (0,1,0,0,0).

Trình biến đổi ngược tồn tại hoạt động như sau: Xml.XmlConvert.ToString (New TimeSpan (0,1,0,0,0)) Biểu thức trên sẽ trả về P0DT1H0M0S.

Trả lời

17

Một từ nhỏ của thận trọng - XmlConvert.ToTimeSpan() là một chút hài hước khi làm việc với tháng và năm. Lớp TimeSpan không có thành viên tháng hoặc năm, có lẽ vì độ dài của chúng thay đổi. Tuy nhiên, ToTimeSpan() sẽ vui vẻ chấp nhận chuỗi thời lượng có giá trị tháng hoặc năm trong đó và đoán trong một khoảng thời gian, thay vì ném một ngoại lệ. Quan sát:

PS C:\Users\troll> [Reflection.Assembly]::LoadWithPartialName("System.Xml") 

GAC Version  Location 
--- -------  -------- 
True v2.0.50727  C:\Windows\assembly\GAC_MSIL\System.Xml\2.0.0.0__b77a5c561934e089\System.Xml.dll 


PS C:\Users\troll> [System.Xml.XmlConvert]::ToTimeSpan("P1M") 


Days    : 30 
Hours    : 0 
Minutes   : 0 
Seconds   : 0 
Milliseconds  : 0 
Ticks    : 25920000000000 
TotalDays   : 30 
TotalHours  : 720 
TotalMinutes  : 43200 
TotalSeconds  : 2592000 
TotalMilliseconds : 2592000000 



PS C:\Users\troll> [System.Xml.XmlConvert]::ToTimeSpan("P1Y") 


Days    : 365 
Hours    : 0 
Minutes   : 0 
Seconds   : 0 
Milliseconds  : 0 
Ticks    : 315360000000000 
TotalDays   : 365 
TotalHours  : 8760 
TotalMinutes  : 525600 
TotalSeconds  : 31536000 
TotalMilliseconds : 31536000000 



PS C:\Users\troll> 
+0

Funfact: Tháng lạ. 'P11M' => 330 ngày nhưng' P12M' => 365 ngày – Trajan

0

Khi @ima bẩn troll cho biết TimeSpan dịch luôn là năm là 365 ngày và tháng là 30 ngày.

TimeSpan ts = System.Xml.XmlConvert.ToTimeSpan("P5Y"); 
DateTime now = new DateTime(2008,2,29); 
Console.WriteLine(now + ts); // 27/02/2013 0:00:00 

Để giải quyết, bạn nên thêm từng trường riêng lẻ thay vì so với sử dụng TimeSpan.

DateTime now = new DateTime (2008, 2, 29); 
string duration = "P1Y"; 
Regex expr = 
    new Regex (@"(-?)P((\d{1,4})Y)?((\d{1,4})M)?((\d{1,4})D)?(T((\d{1,4})H)?((\d{1,4})M)?((\d{1,4}(\.\d{1,3})?)S)?)?", RegexOptions.Compiled | RegexOptions.CultureInvariant); 
bool positiveDuration = false == (input [0] == '-'); 

MatchCollection matches = expr.Matches (duration); 
var g = matches [0]; 
Func<int,int> getNumber = x => { 
    if (g.Groups.Count < x || string.IsNullOrEmpty (g.Groups [x].ToString())) { 
     return 0; 
    } 

    int a = int.Parse (g.Groups [x].ToString()); 

    return PositiveDuration ? a : a * -1; 

}; 
now.AddYears (getNumber (3)); 
now.AddMonths (getNumber (5)); 
now.AddDays (getNumber (7)); 
now.AddHours (getNumber (10)); 
now.AddMinutes (getNumber (12)); 
now.AddSeconds (getNumber (14)); 
Console.WriteLine (now); // 28/02/2012 0:00:00 
+0

Không có quy tắc nào nói rằng các giá trị không được lớn hơn 4 chữ số, nhân tiện. P10000YT20000H là một thời hạn xs hoàn toàn hợp lệ, nhưng biểu thức chính quy của bạn sẽ không chấp nhận nó. – Alex

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