Pregunta

¿Existe un método de biblioteca estándar que convierta una cadena que tiene una duración en la duración estándar ISO 8601 (también utilizada en XSD para su duration tipo) formato en el objeto .NET TimeSpan?

Por ejemplo, P0DT1H0M0S, que representa una duración de una hora, se convierte en New TimeSpan(0,1,0,0,0).

Existe un convertidor inverso que funciona de la siguiente manera:Xml.xmlconvert.ToString (New Timespan (0,1,0,0,0)) La expresión anterior devolverá P0DT1H0M0S.

¿Fue útil?

Solución

Esto convertirá de xs:duración a TimeSpan:

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

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

Otros consejos

Una pequeña advertencia: XmlConvert.ToTimeSpan() es un poco divertido cuando se trabaja con meses y años.La clase TimeSpan no tiene miembros de mes o año, probablemente porque su duración varía.Sin embargo, ToTimeSpan() aceptará gustosamente una cadena de duración con valores de mes o año y adivinar en una duración, en lugar de lanzar una excepción.Observar:

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>

Como dijo @ima dirty troll, TimeSpan siempre traduce años como 365 días y meses como 30 días.

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

Para abordarlo, debe agregar cada campo individualmente en lugar de usar 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top