2017-08-08 45 views
1

我有字符串「Mon-Thu, Sun」。將週日縮寫(包括範圍)的字符串轉換爲列表<DayOfWeek>

我需要將其轉換爲new List<DayOfWeek>{DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Sunday}

我想這劈裂字符串轉換成字符串數組,然後解析字符串到日期時間與日期格式「DDD」。但是我需要檢測出哪裏是「 - 」符號,哪裏是「,」。

但接下來的代碼失敗

 var str = "Mon-Thu, Sun"; 
     var split = str.Split(new []{',', '-'}); 

     foreach(var item in split){ 
      Console.WriteLine(item.Trim()); 
      var day = DateTime.ParseExact(item.Trim(), "ddd", CultureInfo.InvariantCulture); 
      Console.WriteLine(day.ToShortDateString()); 
     } 

有了錯誤「字符串未被識別爲有效的DateTime,因爲一週中的一天是不正確的。」

回答

1

一種方法字符串第一分割成「塊」,這我定義爲一個範圍的一個或多個天,由逗號分割。然後,對於每個塊,抓住開始日,將其添加到列表中,然後增加它,直到我們到達結束日。

我們可以將代碼寫入增量的日子中,這樣他們就會「環繞」一週。例如,如果我們代表我們要從「星期五」開始的一些休假時間,那麼這些日子就是星期五,星期六,星期天和星期一。由於星期天是0,單單增加會導致無效值。

我們可以使用Enum.GetValues與System.Linq的Cast方法相結合,得到的星期幾的字符串值,然後只是比較發現一週中的一天,我們的輸入開始。

static void Main(string[] args) 
{ 
    var input = "Fri-Thu, Sun"; 
    var consecutiveChunks = input.Split(new[] { ',' }, 
     StringSplitOptions.RemoveEmptyEntries); 

    var output = new List<DayOfWeek>(); 
    var daysOfWeek = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>(); 

    foreach (var chunk in consecutiveChunks) 
    { 
     var chunkRange = chunk.Split('-').Select(i => i.Trim()).ToList(); 

     DayOfWeek currentDay = daysOfWeek 
      .First(d => d.ToString().StartsWith(chunkRange[0])); 

     DayOfWeek lastDay = chunkRange.Count > 1 
      ? daysOfWeek.First(d => d.ToString().StartsWith(chunkRange[1])) 
      : currentDay; 

     output.Add(currentDay); 

     // If we have a range of days, add the rest of them 
     while (currentDay != lastDay) 
     { 
      // Increment to the next day 
      if (currentDay == DayOfWeek.Saturday) 
      { 
       currentDay = DayOfWeek.Sunday; 
      } 
      else 
      { 
       currentDay++; 
      } 

      output.Add(currentDay); 
     } 
    } 

    // Output our results: 
    Console.WriteLine($"The ranges, \"{input}\" resolve to:"); 
    output.ForEach(i => Console.WriteLine(i.ToString())); 

    Console.Write("\nDone!\nPress any key to exit..."); 
    Console.ReadKey(); 
} 

輸出

enter image description here

-2

Mon不是C#的標準日輸入。首先,您必須根據您希望支持的所有格式,手動將其轉換爲DayOfWeek enum中正確的當天值。像Mon應該是星期一等。一旦你有正確的等價物,你可以很容易地將它映射到DayOfWeek Enum。

+0

我懷疑它是downvoted,因爲你理論上解釋了要做什麼,沒有提供一個例子或僞代碼。 –

+1

我認爲這是必須的原因,在類別'無代碼'@我downvote因爲網站。雖然我想知道是否同樣的東西也適用於答案。有時指出解決方案應該就足夠了。無論如何,我會避免發佈無助於任何人的問題/答案。謝謝... –

-1

這是因爲當您僅在分析時指定星期幾時,它默認爲DateTime.Now,與您在運行程序的那一天相同。所以如果你今天通過一天不同於今天你會得到一個錯誤。你必須自己解析它,例如通過做

Dictionary<string, DayOfWeek> days = new Dictionary<string, DayOfWeek> 
{ 
    ["Mon"] = DayOfWeek.Monday, 
    ["Tue"] = DayOfWeek.Tuesday, 
    ["Wed"] = DayOfWeek.Wednesday, 
    ["Thu"] = DayOfWeek.Thursday, 
    ["Fri"] = DayOfWeek.Friday, 
    ["Sat"] = DayOfWeek.Saturday, 
    ["Sun"] = DayOfWeek.Sunday 
}; 

//Get the next day in the week by calculating modulo 7 
DayOfWeek NextDay(DayOfWeek day) => (DayOfWeek)(((int)day + 1) % 7); 

List<DayOfWeek> GetDays(string input) 
{ 
    var ranges = input.Split(','); 
    var daysList = new List<DayOfWeek>(); 

    foreach(var range in ranges) 
    { 
     var bounds = range.Split('-').Select(s => s.Trim()).ToList(); 
     if(bounds.Count == 1) 
     { 
      if(days.TryGetValue(bounds[0], out var day)) 
       daysList.Add(day); 
      else 
       throw new FormatException("Couldn't find day"); 
     } 
     else if(bounds.Count == 2) 
     { 
      if(days.TryGetValue(bounds[0], out var begin) && days.TryGetValue(bounds[1], out var end)) 
      { 
       if(begin == NextDay(end)) // whole week in one range 
       { 
        daysList.AddRange(days.Values); 
        break; 
       } 

       for(var i = begin; i != NextDay(end); i = NextDay(i)) 
       { 
        daysList.Add(i); 
       } 
      } 
      else 
       throw new FormatException("Couldn't find day"); 
     } 
     else 
      throw new FormatException("Too many hyphens in one range"); 
    } 

    var set = new SortedSet<DayOfWeek>(daysList); //remove duplicates and sort 
    return set.ToList(); 
} 

var input = "Mon-Thu, Sun"; 
foreach(var day in GetDays(input)) 
{ 
    Console.WriteLine(day); 
} 

編輯:添加答案:)

+0

我沒有降低你的問題,但它不回答OP的問題,這可能是爲什麼它被低估。 – STLDeveloper

1

下面的代碼工作你提到的格式。要做到這一點是

Input : "Mon-Thu, Sun" 
OutPut: Monday, Tuesday, Wednesday, Thursday, Sunday 

Input : "Mon, Wed-Thu, Sun" 
OutPut: Monday, Wednesday, Thursday, Sunday 

List<DayOfWeek> ListOfDays() 
{ 
    var str = "Mon-Thu, Sun"; 
    string[] split = str.Split(','); 

    var days = new List<DayOfWeek>(); 
    foreach (var item in split) 
    { 
     if (item.IndexOf('-') < 0) 
     { 
      days.Add(GetDayOfWeek(item.Trim())); 
      continue; 
     } 

     var consecutiveDays = item.Split('-'); 
     DayOfWeek startDay = GetDayOfWeek(consecutiveDays[0].Trim()); 
     DayOfWeek endDay = GetDayOfWeek(consecutiveDays[1].Trim()); 

     for (DayOfWeek day = startDay; day <= endDay; day++) 
      days.Add(day); 
    } 

    return days; 
} 

DayOfWeek GetDayOfWeek(string day) 
{ 
    switch (day.ToUpper()) 
    { 
     case "MON": 
      return DayOfWeek.Monday; 
      break; 
     case "TUE": 
      return DayOfWeek.Tuesday; 
      break; 
     case "WED": 
      return DayOfWeek.Wednesday; 
      break; 
     case "THU": 
      return DayOfWeek.Thursday; 
      break; 
     case "FRI": 
      return DayOfWeek.Friday; 
      break; 
     case "SAT": 
      return DayOfWeek.Saturday; 
      break; 
     case "SUN": 
      return DayOfWeek.Sunday; 
      break; 
     default: 
      throw new ArgumentException("Invalid day"); 
      break; 
    } 
} 
0

事實證明,C#庫確實保持一天縮寫列表,如果你不喜歡他們,你甚至可以改變它們。具體來說,我指的是CultureInfo.[culture].DateTimeFormat.AbbreviatedDayNames

InvariantCulture對於您的問題中列出的星期一,星期四和星期日使用相同的縮寫。

給定日期名稱的縮寫,您應該能夠得出AbbreviatedDayNames數組中縮寫名稱的索引,該索引與DayOfWeek使用的索引相匹配。

對我而言,這種方法似乎比將文字字符串嵌入代碼更好。

public static void Main() 
{ 
    var dayList = new List<DayOfWeek>(); 
    var str = "Mon-Thu, Sun"; 

    str = str.Replace(" ", string.Empty); // remove spaces 

    // split groups by comma 
    var split = str.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 

    foreach (var item in split) // process each group 
    { 
     // split ranges by hyphen 
     var elements = item.Split(new[] {'-'}, StringSplitOptions.RemoveEmptyEntries); // split group into elements 
     switch (elements.Length) 
     { 
      case 1: 
       // add single element 
       dayList.Add((DayOfWeek) GetDayIndex(elements[0])); 
       break; 
      case 2: 
       // add range of elements 
       dayList.AddRange(GetDayRange(elements[0], elements[1])); 
       break; 
      default: 
       Console.WriteLine($"Input line does not match required format: \"{str}\""); 
       break; 
     } 
    } 
    // prove it works 
    Console.WriteLine(string.Join(", ", dayList)); 
} 

private static int GetDayIndex(string dayNameAbbreviation) 
{ 
    return Array.IndexOf(CultureInfo.InvariantCulture.DateTimeFormat.AbbreviatedDayNames, dayNameAbbreviation); 
} 

private static IEnumerable<DayOfWeek> GetDayRange(string beginDayNameAbbrev, string endDayNameAbbrev) 
{ 
    var dayRange = new List<DayOfWeek>(); 

    for (var i = GetDayIndex(beginDayNameAbbrev); i <= GetDayIndex(endDayNameAbbrev); i++) 
    { 
     dayRange.Add((DayOfWeek) i); 
    } 
    return dayRange; 
} 

編輯

如上所述,如果你不喜歡一個特定的文化中使用的縮寫一天,你可以暫時改變它們。要看看如何,看看這個堆棧溢出問題:How to change DateTimeFormatInfo.CurrentInfo AbbreviatedDayNames collection

+0

@RufusL當然!這就是我得到的匆忙!感謝您的建議,我會編輯答案。 – STLDeveloper