How to Convert ISO 8601 Duration to TimeSpan in VB.Net?

前端 未结 3 1880
死守一世寂寞
死守一世寂寞 2020-12-30 04:38

Is there a standard library method that converts a string that has duration in the standard ISO 8601 Duration (also used in XSD for its duration type) format in

相关标签:
3条回答
  • 2020-12-30 04:39

    One minor word of caution - XmlConvert.ToTimeSpan() is a little funny when working with months and years. The TimeSpan class does not have month or year members, probably because their length varies. However, ToTimeSpan() will happily accept a duration string with month or year values in it and guess at a duration, instead of throwing an exception. Observe:

    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 讨论(0)
  • 2020-12-30 04:54

    This will convert from xs:duration to TimeSpan:

    System.Xml.XmlConvert.ToTimeSpan("P0DT1H0M0S")
    

    See http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.totimespan.aspx

    0 讨论(0)
  • 2020-12-30 05:02

    As @ima dirty troll said TimeSpan translates always years as 365 days and months as 30 days.

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

    To address it you should add each field individually rather than using 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 讨论(0)
提交回复
热议问题