[英]Convert a string of weekday abbreviations, including ranges, into a List<DayOfWeek>
我有字符串“ Mon-Thu, Sun
”。
我需要將其轉換為new List<DayOfWeek>{DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Sunday}
我考慮將此字符串拆分為字符串數組,然后將其解析為日期格式為“ ddd”的DateTime。 但是我需要以某種方式檢測“-”符號在哪里以及“,”在哪里。
但是下一個代碼失敗
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”。
事實證明,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;
}
編輯
如上所述,如果您不喜歡特定文化所使用的日期縮寫,則可以臨時更改它們。 若要查看操作方法,請查看以下堆棧溢出問題: 如何更改DateTimeFormatInfo.CurrentInfo AbbreviatedDayNames集合 。
以下代碼適用於您提到的格式。
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
,僅增加就將導致一個無效值。
我們可以結合使用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();
}
產量
這是因為當您在解析時僅指定星期幾時,它默認為DateTime.Now
。現在與運行程序的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);
}
編輯:添加的答案:)
Mon
不是C#的標准日期輸入。 首先,您必須根據要支持的所有格式手動將其轉換為DayOfWeek
枚舉中的正確的等效日值。 像星期一應該是星期一,等等。一旦有了正確的等值,就可以輕松地將其映射到DayOfWeek
枚舉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.