كيفية تحويل مدة ISO 8601 إلى TimeSpan في VB.Net؟
سؤال
هل هناك طريقة مكتبة قياسية تقوم بتحويل سلسلة لها مدة في مدة ISO 8601 القياسية (تُستخدم أيضًا في XSD لـ duration
type) في كائن .NET TimeSpan؟
على سبيل المثال، يتم تحويل P0DT1H0M0S الذي يمثل مدة ساعة واحدة، إلى New TimeSpan(0,1,0,0,0).
يوجد محول عكسي يعمل على النحو التالي:xml.xmlconvert.tostring (الزمن الجديد (0،1،0،0،0)) سيعود التعبير أعلاه p0dt1h0m0s.
المحلول
سيتم التحويل من xs:duration إلى TimeSpan:
System.Xml.XmlConvert.ToTimeSpan("P0DT1H0M0S")
يرى http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.totimespan.aspx
نصائح أخرى
كلمة تحذير بسيطة - يعد XmlConvert.ToTimeSpan() أمرًا مضحكًا بعض الشيء عند العمل مع الأشهر والسنوات.لا تحتوي فئة TimeSpan على أعضاء للشهر أو السنة، ربما بسبب اختلاف طولهم.ومع ذلك، سيقبل ToTimeSpan() بكل سرور سلسلة مدة تحتوي على قيم الشهر أو السنة و يخمن في مدة، بدلا من رمي استثناء.يراقب:
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>
كما قال @ima القزم القذر، فإن TimeSpan يترجم دائمًا السنوات إلى 365 يومًا والأشهر إلى 30 يومًا.
TimeSpan ts = System.Xml.XmlConvert.ToTimeSpan("P5Y");
DateTime now = new DateTime(2008,2,29);
Console.WriteLine(now + ts); // 27/02/2013 0:00:00
لمعالجته ، يجب عليك إضافة كل حقل بشكل فردي بدلاً من استخدام TimePan.
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