سؤال

هل هناك طريقة مكتبة قياسية تقوم بتحويل سلسلة لها مدة في مدة 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top