I need all the weekdays between two days.
我需要两天之间的所有工作日。
Example:
例:
Wednesday - Friday = Wednesday, Thursday, Friday 3 - 5 = 3, 4, 5 Saturday - Tuesday = Saturday, Sunday, Monday, Tuesday 6 - 2 = 6, 7, 1, 2
I'm pretty sure there is a clever algorithm out there to solve this. The only algorithms I can think of use either a loop or an if
statement.
我很确定有一个聪明的算法来解决这个问题。我能想到的唯一算法是使用循环或if语句。
There has to be an elegant way to solve this. I use the numbers 1-7 for the weekdays, but 0-6 is fine too.
必须有一种优雅的方法来解决这个问题。我在工作日使用数字1-7,但0-6也很好。
The best I could come up with:
我能想到的最好的:
def between(d1, d2):
alldays = [0,1,2,3,4,5,6,0,1,2,3,4,5,6] # or range(7) * 2
offset = 8 if d1 > d2 else 1
return alldays[d1:d2 + offset]
between(0, 4)
# [0,1,2,3,4]
between(5,2)
# [5,6,0,1,2]
7 个解决方案
#1
8
>>> def weekdays_between(s, e):
... return [n % 7 for n in range(s, e + (1 if e > s else 8))]
...
>>> weekdays_between(2, 4)
[2, 3, 4]
>>> weekdays_between(5, 1)
[5, 6, 0, 1]
It's a bit more complex if you have to convert from/to actual days.
如果你必须转换/到实际天数,它会更复杂一些。
>>> days = 'Mon Tue Wed Thu Fri Sat Sun'.split()
>>> days_1 = {d: n for n, d in enumerate(days)}
>>> def weekdays_between(s, e):
... s, e = days_1[s], days_1[e]
... return [days[n % 7] for n in range(s, e + (1 if e > s else 8))]
...
>>> weekdays_between('Wed', 'Fri')
['Wed', 'Thu', 'Fri']
>>> weekdays_between('Sat', 'Tue')
['Sat', 'Sun', 'Mon', 'Tue']
#2
9
How about (in pseudo code):
怎么样(伪代码):
weekday[] = {"Mon" .. "Sun"}
for(i = wkday_start; (i % 7) != wkday_end; i = (i+1) % 7)
printf("%s ", weekday[i]);
It works like a circular buffer, wkday_start being the index to start at (0-based), wkday_end being the end index.
它的工作方式类似于循环缓冲区,wkday_start是从(从0开始)开始的索引,wkday_end是结束索引。
Hope this helps
希望这可以帮助
George.
乔治。
#3
2
Building on the excellent answer from Stephan202, you can generalize the concept of a circular slice.
基于Stephan202的优秀答案,您可以概括圆形切片的概念。
>>> def circular_slice(r, s, e):
... return [r[n % len(r)] for n in range(s, e + (1 if e>s else len(r)+1))]
...
>>> circular_slice(range(0,7), 2, 4)
[2, 3, 4]
>>> circular_slice(range(0,7), 5, 1)
[5, 6, 0, 1]
>>> circular_slice('Mon Tue Wed Thu Fri Sat Sun'.split(), 5, 1)
['Sat', 'Sun', 'Mon', 'Tue']
#4
1
The solutions provided already answer the question, but I want to suggest something extra. I don't know what you're doing, but maybe you want the actual dates instead?
提供的解决方案已经回答了问题,但我想提出一些额外的建议。我不知道你在做什么,但也许你想要实际日期呢?
>>> from datetime import timedelta, date
>>> from dateutil.rrule import rrule, DAILY
>>> today = date(2009, 10, 13) # A tuesday
>>> week = today - timedelta(days=6)
>>> list(rrule(DAILY, byweekday=xrange(5), dtstart=week, until=today))
[datetime.datetime(2009, 10, 7, 0, 0),
datetime.datetime(2009, 10, 8, 0, 0),
datetime.datetime(2009, 10, 9, 0, 0),
datetime.datetime(2009, 10, 12, 0, 0),
datetime.datetime(2009, 10, 13, 0, 0)]
That uses the excellent python-dateutil module.
它使用了优秀的python-dateutil模块。
#5
1
Use the calendar module for your list of day names:
使用日历模块作为日期名称列表:
import calendar
def intervening_days(day1, day2):
weektest = list(calendar.day_name)*2
d1 = weektest.index(day1)
d2 = weektest.index(day2,d1+1)
return weektest[d1:d2+1]
print intervening_days("Monday","Sunday")
print intervening_days("Monday","Tuesday")
print intervening_days("Thursday","Tuesday")
print intervening_days("Monday","Monday")
Prints:
打印:
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
['Monday', 'Tuesday']
['Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday']
If you don't want Monday-to-Monday to return a full week of days, change the determination of d2 to d2 = weektest.index(day2,d1)
.
如果您不希望星期一到星期一返回整整一周的天数,请将d2的确定更改为d2 = weektest.index(day2,d1)。
#6
0
You asked for an algorithm, and I understand that should be language independent; however, following code works using C# and LINQ expressions:
你问了一个算法,我明白这应该是语言独立的;但是,以下代码使用C#和LINQ表达式:
DayOfWeek start = DayOfWeek.Wednesday;
DayOfWeek end = DayOfWeek.Friday;
IEnumerable<DayOfWeek> interval =
Enum.GetValues(typeof(DayOfWeek)).OfType<DayOfWeek>()
.Where(d => d >= start && d <= end);
Console.WriteLine(
String.Join(", ",
interval.Select(d => d.ToString()).ToArray()));
Probably, using any language, your should attribute values to each day (Sunday=0
and so on) and look for all values which matches your desired interval.
也许,使用任何语言,您应该将值归因于每一天(星期日= 0等等),并查找符合您所需间隔的所有值。
#7
0
The following code returns 1 for Monday - Monday.
以下代码在星期一 - 星期一返回1。
bool isWeekday(int d) {
return d >= 1 && d <= 5;
}
int f(int d1, int d2) {
int res = isWeekday(d1) ? 1 : 0;
return d1 == d2 ?
res :
res + f(d1 % 7 + 1, d2);
}
#1
8
>>> def weekdays_between(s, e):
... return [n % 7 for n in range(s, e + (1 if e > s else 8))]
...
>>> weekdays_between(2, 4)
[2, 3, 4]
>>> weekdays_between(5, 1)
[5, 6, 0, 1]
It's a bit more complex if you have to convert from/to actual days.
如果你必须转换/到实际天数,它会更复杂一些。
>>> days = 'Mon Tue Wed Thu Fri Sat Sun'.split()
>>> days_1 = {d: n for n, d in enumerate(days)}
>>> def weekdays_between(s, e):
... s, e = days_1[s], days_1[e]
... return [days[n % 7] for n in range(s, e + (1 if e > s else 8))]
...
>>> weekdays_between('Wed', 'Fri')
['Wed', 'Thu', 'Fri']
>>> weekdays_between('Sat', 'Tue')
['Sat', 'Sun', 'Mon', 'Tue']
#2
9
How about (in pseudo code):
怎么样(伪代码):
weekday[] = {"Mon" .. "Sun"}
for(i = wkday_start; (i % 7) != wkday_end; i = (i+1) % 7)
printf("%s ", weekday[i]);
It works like a circular buffer, wkday_start being the index to start at (0-based), wkday_end being the end index.
它的工作方式类似于循环缓冲区,wkday_start是从(从0开始)开始的索引,wkday_end是结束索引。
Hope this helps
希望这可以帮助
George.
乔治。
#3
2
Building on the excellent answer from Stephan202, you can generalize the concept of a circular slice.
基于Stephan202的优秀答案,您可以概括圆形切片的概念。
>>> def circular_slice(r, s, e):
... return [r[n % len(r)] for n in range(s, e + (1 if e>s else len(r)+1))]
...
>>> circular_slice(range(0,7), 2, 4)
[2, 3, 4]
>>> circular_slice(range(0,7), 5, 1)
[5, 6, 0, 1]
>>> circular_slice('Mon Tue Wed Thu Fri Sat Sun'.split(), 5, 1)
['Sat', 'Sun', 'Mon', 'Tue']
#4
1
The solutions provided already answer the question, but I want to suggest something extra. I don't know what you're doing, but maybe you want the actual dates instead?
提供的解决方案已经回答了问题,但我想提出一些额外的建议。我不知道你在做什么,但也许你想要实际日期呢?
>>> from datetime import timedelta, date
>>> from dateutil.rrule import rrule, DAILY
>>> today = date(2009, 10, 13) # A tuesday
>>> week = today - timedelta(days=6)
>>> list(rrule(DAILY, byweekday=xrange(5), dtstart=week, until=today))
[datetime.datetime(2009, 10, 7, 0, 0),
datetime.datetime(2009, 10, 8, 0, 0),
datetime.datetime(2009, 10, 9, 0, 0),
datetime.datetime(2009, 10, 12, 0, 0),
datetime.datetime(2009, 10, 13, 0, 0)]
That uses the excellent python-dateutil module.
它使用了优秀的python-dateutil模块。
#5
1
Use the calendar module for your list of day names:
使用日历模块作为日期名称列表:
import calendar
def intervening_days(day1, day2):
weektest = list(calendar.day_name)*2
d1 = weektest.index(day1)
d2 = weektest.index(day2,d1+1)
return weektest[d1:d2+1]
print intervening_days("Monday","Sunday")
print intervening_days("Monday","Tuesday")
print intervening_days("Thursday","Tuesday")
print intervening_days("Monday","Monday")
Prints:
打印:
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
['Monday', 'Tuesday']
['Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday']
If you don't want Monday-to-Monday to return a full week of days, change the determination of d2 to d2 = weektest.index(day2,d1)
.
如果您不希望星期一到星期一返回整整一周的天数,请将d2的确定更改为d2 = weektest.index(day2,d1)。
#6
0
You asked for an algorithm, and I understand that should be language independent; however, following code works using C# and LINQ expressions:
你问了一个算法,我明白这应该是语言独立的;但是,以下代码使用C#和LINQ表达式:
DayOfWeek start = DayOfWeek.Wednesday;
DayOfWeek end = DayOfWeek.Friday;
IEnumerable<DayOfWeek> interval =
Enum.GetValues(typeof(DayOfWeek)).OfType<DayOfWeek>()
.Where(d => d >= start && d <= end);
Console.WriteLine(
String.Join(", ",
interval.Select(d => d.ToString()).ToArray()));
Probably, using any language, your should attribute values to each day (Sunday=0
and so on) and look for all values which matches your desired interval.
也许,使用任何语言,您应该将值归因于每一天(星期日= 0等等),并查找符合您所需间隔的所有值。
#7
0
The following code returns 1 for Monday - Monday.
以下代码在星期一 - 星期一返回1。
bool isWeekday(int d) {
return d >= 1 && d <= 5;
}
int f(int d1, int d2) {
int res = isWeekday(d1) ? 1 : 0;
return d1 == d2 ?
res :
res + f(d1 % 7 + 1, d2);
}