2016-05-25 17 views
0

私は今日の私たちのジェンキンズビルドの時間リストを持っています。このリストを解析し、ビルドの日付時刻を返したいと思います。C#Parse String to Date Time

List (Time since build) 
----------------------- 
1 day 21 hr 
1 day 22 hr 
1 mo 14 days 
1 mo 14 days 
27 days 
1 day 6 hr 
1 mo 14 days 
6 min 13 sec 

例えば:1日21時間 - >今日から時間2016年5月22日午前九時00分00秒PM

は、私が一緒に、次の正規表現のバージョンを入れて返す必要があります...しかし、それは非常に感じていますハッキーと脆い。

このテキストをよりよく解析できますか。

using System; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string txt = "1 day 21 hr"; 

      string regexday = "(\\d\\s+day)"; // 1 day 
      string regexdaymultiple = "(\\d\\d\\s+day)"; //10 days 
      string regexhr = "(\\s+\\d\\s+hr)"; // 1 hr 
      string regexhrmultiple = "(\\s+\\d\\d\\s+hr)"; // 21 hr 


      Regex regexdaymatch = new Regex(regexday, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      Match matchday = regexdaymatch.Match(txt); 

      if (matchday.Success) 
      { 
       String d1 = matchday.Groups[1].ToString(); 
       DateTime now = DateTime.Now; 
       Console.Write("("+now.AddDays(-Convert.ToInt32(d1.Replace(" day", "")))+")" + "\n"); 
      } 

      Regex regexdaymutliplesmatch = new Regex(regexdaymultiple, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      Match matchdaymultiple = regexdaymutliplesmatch.Match(txt); 

      if (matchdaymultiple.Success) 
      { 
       String d1 = matchdaymultiple.Groups[1].ToString(); 
       DateTime now = DateTime.Now; 
       Console.Write("(" + now.AddDays(-Convert.ToInt32(d1.Replace(" day", ""))) + ")" + "\n"); 
      } 

      Regex regexhrmatch = new Regex(regexhr, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      Match matchhr = regexhrmatch.Match(txt); 

      if (matchhr.Success) 
      { 
       String d1 = matchhr.Groups[1].ToString(); 
       DateTime now = DateTime.Now; 
       Console.Write("(" + now.AddHours(-Convert.ToInt32(d1.Replace(" hr", ""))) + ")" + "\n"); 
      } 

      Regex regexhrmultiplematch = new Regex(regexhrmultiple, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      Match matchhrmultiple = regexhrmultiplematch.Match(txt); 

      if (matchhrmultiple.Success) 
      { 
       String d1 = matchhrmultiple.Groups[1].ToString(); 
       DateTime now = DateTime.Now; 
       Console.Write("(" + now.AddHours(-Convert.ToInt32(d1.Replace(" hr", ""))) + ")" + "\n"); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 
+1

:ここ

は修正Main方法であり、それらの内容に基づいて数時間に配列し、DateTime.Nowから減算します。 – mjw

答えて

1

これは、ビルド用に提示されたHTMLを解析して、時間に逆戻りしようとしているように聞こえます。私はこのアプローチに欠陥があると感じています。私はJenkins APIを研究し、そのようにデータを引き出すことをお勧めします。

https://media.readthedocs.org/pdf/jenkinsapi/latest/jenkinsapi.pdf

APIは、適切なタイムスタンプのデータを返すようです。

+0

jenkinsの結果を照会できるアカウントにアクセスできません。私は、しかし、ジェンキンスによって生成され、内部のWebサーバー上に掲載されているHTMLページにアクセスする必要があります。 私は実行可能なソリューションを持っています(上記のコードを参照してください)。 – IanC

1

ここにRegexを使用しないクラスがあります。あなたがRegexをよく知っていれば、あなたのソリューションは正常に動作します。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 

public class TimeSinceBuildsReader 
{ 
    public virtual IReadOnlyList<DateTime> TimesWhenBuildsOccurred(string timeSinceBuildsFilePath) 
    { 
     if (!File.Exists(timeSinceBuildsFilePath)) 
     { 
      return new List<DateTime>(); 
     } 

     var lines = File.ReadAllLines(timeSinceBuildsFilePath); 
     var list = new List<DateTime>(lines.Length); 
     var now = DateTime.Now; 
     foreach (var line in lines) 
     { 
      var split = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 
       .Select(l => l.Trim()).ToArray(); 
      if (split.Length % 2 != 0) 
      { 
       continue; 
      } 

      switch (split.Length) 
      { 
       case 2: 
        list.Add(now.Subtract(getTimePassed(now, split[0], split[1]))); 
        break; 
       case 4: 
        var firstDuration = getTimePassed(now, split[0], split[1]); 
        var secondDuration = getTimePassed(now, split[2], split[3]); 
        list.Add(now.Subtract(firstDuration).Subtract(secondDuration)); 
        break; 
      } 
     } 

     return list; 
    } 

    private static TimeSpan getTimePassed(DateTime now, string number, string durationType) 
    { 
     var num = int.Parse(number); 
     if (durationType.Contains("month") || durationType.Contains("mo")) 
     { 
      var numberOfDays = now.DayOfYear - now.AddMonths(num * -1).DayOfYear; 
      return TimeSpan.FromDays(numberOfDays); 
     } 

     if (durationType.Contains("day")) 
     { 
      return TimeSpan.FromDays(num); 
     } 

     if (durationType.Contains("hour") || durationType.Contains("hr")) 
     { 
      return TimeSpan.FromHours(num); 
     } 

     if (durationType.Contains("minute") || durationType.Contains("min")) 
     { 
      return TimeSpan.FromMinutes(num); 
     } 

     if (durationType.Contains("second") || durationType.Contains("sec")) 
     { 
      return TimeSpan.FromSeconds(num); 
     } 

     throw new NotImplementedException("Could not parse duration type from input " + durationType); 
    } 
} 

このクラスの仮説を作成することができます。 FakeItEasyで、別のクラスへの依存として注入されます(コンソールアプリケーションを拡張したい場合に備えて)。あなたはしかし、私はちょうどの要素を変換し、その後、4回ごとのスペースに文字列全体を分割する可能性がある、解決への正しい道のようなルックスを持っている何

private static void Main() 
{ 
    foreach (var timestamp in new TimeSinceBuildsReader().TimesWhenBuildsOccurred("time-since-builds.txt")) 
    { 
     Console.WriteLine(timestamp); 
    } 

    Console.ReadKey(); 
}