C# 将一串工作日缩写(包括范围)转换为列表<;星期一>;

C# 将一串工作日缩写(包括范围)转换为列表<;星期一>;,c#,string,parsing,datetime,dayofweek,C#,String,Parsing,Datetime,Dayofweek,我有字符串“Mon-Thu,Sun” 我需要将其转换为新列表{DayOfWeek.周一,DayOfWeek.周二,DayOfWeek.周三,DayOfWeek.周四,DayOfWeek.Sunday} 我考虑将该字符串拆分为字符串数组,然后使用dateformat“ddd”将字符串解析为DateTime。但我需要以某种方式检测“-”符号和“,”符号的位置 但下一个代码失败了 var str = "Mon-Thu, Sun"; var split = str.Spl

我有字符串“
Mon-Thu,Sun

我需要将其转换为
新列表{DayOfWeek.周一,DayOfWeek.周二,DayOfWeek.周三,DayOfWeek.周四,DayOfWeek.Sunday}

我考虑将该字符串拆分为字符串数组,然后使用dateformat“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());
        }

出现错误“字符串未被识别为有效的日期时间,因为星期几不正确。”

Mon
不是C#的标准日期输入。首先,您必须根据希望支持的所有格式手动将其转换为
DayOfWeek
enum中的正确等效日值。比如Mon应该是Monday等。一旦你有了正确的等价物,你可以很容易地将它映射到
DayOfWeek
Enum。

这是因为当你在解析时只指定星期几时,它默认为
DateTime。现在
就像你运行程序的那天一样。因此,如果你度过了与今天不同的一天,你会得到一个错误。您必须自己解析它,例如

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);
}
Dictionary days=新字典
{
[“Mon”]=星期一,星期一,
星期二,星期二,
星期三,星期三,
星期四,星期四,
星期五,星期五,
[星期六]=星期六,
[“Sun”]=DayOfWeek.Sunday
};
//通过计算模7得到一周中的第二天
DayOfWeek NextDay(DayOfWeek day)=>(DayOfWeek)(((int)day+1)%7);
列表GetDays(字符串输入)
{
var ranges=input.Split(',');
var daysList=新列表();
foreach(范围中的var范围)
{
var bounds=range.Split('-')。选择(s=>s.Trim()).ToList();
如果(bounds.Count==1)
{
if(天TryGetValue(界限[0],超出var天))
daysList.Add(天);
其他的
抛出新FormatException(“找不到日期”);
}
else if(bounds.Count==2)
{
if(days.TryGetValue(界限[0],out-var-begin)和&days.TryGetValue(界限[1],out-var-end))
{
if(begin==NextDay(end))//一个范围内的整个星期
{
daysList.AddRange(天值);
打破
}
对于(变量i=begin;i!=NextDay(end);i=NextDay(i))
{
daysList.Add(i);
}
}
其他的
抛出新FormatException(“找不到日期”);
}
其他的
抛出新FormatException(“一个范围内的连字符太多”);
}
var set=new SortedSet(daysList);//删除重复项并进行排序
返回set.ToList();
}
var input=“周一至周四,周日”;
foreach(以GetDays为单位的var日(输入))
{
控制台写入线(天);
}


编辑:添加答案:)

以下代码适用于您提到的格式

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;
    }
}
输入:“周一至周四,周日”
输出:周一、周二、周三、周四、周日
输入:“周一、周三、周四、周日”
输出:周一、周三、周四、周日
日期列表()
{
var str=“Mon-Thu,Sun”;
string[]split=str.split(',');
var days=新列表();
foreach(拆分中的var项目)
{
if(item.IndexOf('-')小于0)
{
days.Add(GetDayOfWeek(item.Trim());
继续;
}
var ConcertiveDays=item.Split('-');
DayOfWeek startDay=GetDayOfWeek(连续的[0].Trim());
DayOfWeek-endDay=GetDayOfWeek(连续天数[1].Trim());

对于(DayOfWeek day=startDay;day一种方法是首先将字符串拆分为“块”,我将其定义为一个或多个天的范围,用逗号分隔。然后,对于每个块,抓取开始日期,将其添加到列表中,然后递增,直到到达结束日期

我们可以将代码写入天数的增量中,这样它们将“环绕”一周。例如,如果我们表示从“Fri-Mon”开始的某个假期时间,那么这些天将是星期五、星期六、星期日和星期一。仅递增一次将导致无效值,因为星期日是
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();
}
static void Main(字符串[]args)
{
var input=“星期五至星期四,星期日”;
var consutivechunks=input.Split(新[]{',},
StringSplitOptions.RemoveEmptyEntries);
var输出=新列表();
var daysOfWeek=Enum.GetValues(typeof(DayOfWeek)).Cast();
foreach(连续块中的变量块)
{
var chunkRange=chunk.Split('-')。选择(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]))
:当前日期;
输出。添加(当前日期);
//如果我们有一个天数范围,那么把剩下的天数加起来
while(currentDay!=lastDay)
{
//增加到第二天
如果(currentDay==星期六的DayOfWeek)
{
currentDay=星期天,星期日;
}
其他的
{
currentDay++;
}
输出。添加(当前日期);
}
}
//输出我们的结果:
WriteLine($”范围,\“{input}\”解析为:”;
output.ForEach(i=>Console.WriteLine(i.ToString());
控制台。写入(“\n完成!\n按任意键退出…”);
Console.ReadKey();
}
输出

事实证明,C#库确实保存了一个日期缩写列表,如果您
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;
}