VB.Net で ISO 8601 期間を TimeSpan に変換するにはどうすればよいですか?
質問
標準 ISO 8601 持続時間 (XSD でも使用される持続時間) の持続時間を持つ文字列を変換する標準ライブラリ メソッドはありますか? duration
type) 形式を .NET TimeSpan オブジェクトに追加しますか?
たとえば、1 時間の期間を表す P0DT1H0M0S は、New TimeSpan(0,1,0,0,0) に変換されます。
次のように動作する逆コンバータが存在します。Xml.XmlConvert.ToString(新しい TimeSpan(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
他のヒント
ちょっとした注意点が 1 つあります。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
これに対処するには、各フィールドを個別に追加する必要があります 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
所属していません StackOverflow