如果不使用一些可怕的循环/计数器类型解决方案,我什至不确定如何做到这一点。这是问题所在:
我有两个日期,一个开始日期和一个结束日期,我需要在指定的时间间隔内采取一些行动。例如:对于从 2009 年 3 月 10 日到 2009 年 3 月 26 日的第三天之间的每个日期,我需要在列表中创建一个条目。所以我的输入是:
DateTime StartDate = "3/10/2009";
DateTime EndDate = "3/26/2009";
int DayInterval = 3;
我的输出将是一个包含以下日期的列表:
2009 年 3 月 13 日 2009 年 3 月 16 日 2009 年 3 月 19 日 2009 年 3 月 22 日 2009 年 3 月 25 日
那么我怎么会做这样的事情呢?我考虑过使用一个 for 循环,该循环将在范围内的每一天之间使用一个单独的计数器进行迭代,如下所示:
int count = 0;
for(int i = 0; i < n; i++)
{
count++;
if(count >= DayInterval)
{
//take action
count = 0;
}
}
但似乎有更好的方法?
好吧,您需要以一种或另一种方式循环它们。我更喜欢定义这样的方法:
public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for(var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
然后你可以像这样使用它:
foreach (DateTime day in EachDay(StartDate, EndDate))
// print it or whatever
通过这种方式,您可以每隔一天、每隔三天、仅在工作日等。例如,要从“开始”日期开始每隔三天返回一次,您可以在循环中调用 AddDays(3)
而不是 AddDays(1)
.
我在 MiscUtil 中有一个 Range
课程,您会发现它很有用。结合各种扩展方法,您可以:
foreach (DateTime date in StartDate.To(EndDate).ExcludeEnd()
.Step(DayInterval.Days())
{
// Do something with the date
}
(你可能想也可能不想排除结尾——我只是想我会提供它作为一个例子。)
这基本上是 mquander 解决方案的现成(和更通用)形式。
ExcludeEnd()
很可爱。
对于您的示例,您可以尝试
DateTime StartDate = new DateTime(2009, 3, 10);
DateTime EndDate = new DateTime(2009, 3, 26);
int DayInterval = 3;
List<DateTime> dateList = new List<DateTime>();
while (StartDate.AddDays(DayInterval) <= EndDate)
{
StartDate = StartDate.AddDays(DayInterval);
dateList.Add(StartDate);
}
来自@mquander 和@Yogurt The Wise 的代码在扩展中使用:
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
public static IEnumerable<DateTime> EachMonth(DateTime from, DateTime thru)
{
for (var month = from.Date; month.Date <= thru.Date || month.Month == thru.Month; month = month.AddMonths(1))
yield return month;
}
public static IEnumerable<DateTime> EachDayTo(this DateTime dateFrom, DateTime dateTo)
{
return EachDay(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachMonthTo(this DateTime dateFrom, DateTime dateTo)
{
return EachMonth(dateFrom, dateTo);
}
EachDayTo
和 EachMonthTo
有什么意义?我想我在这里错过了一些东西。
1年后,它可以帮助某人,
这个版本包括一个谓词,更加灵活。
用法
var today = DateTime.UtcNow;
var birthday = new DateTime(2018, 01, 01);
每天到我的生日
var toBirthday = today.RangeTo(birthday);
每月到我的生日,步骤 2 个月
var toBirthday = today.RangeTo(birthday, x => x.AddMonths(2));
每年到我的生日
var toBirthday = today.RangeTo(birthday, x => x.AddYears(1));
改用 RangeFrom
// same result
var fromToday = birthday.RangeFrom(today);
var toBirthday = today.RangeTo(birthday);
执行
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> RangeTo(this DateTime from, DateTime to, Func<DateTime, DateTime> step = null)
{
if (step == null)
{
step = x => x.AddDays(1);
}
while (from < to)
{
yield return from;
from = step(from);
}
}
public static IEnumerable<DateTime> RangeFrom(this DateTime to, DateTime from, Func<DateTime, DateTime> step = null)
{
return from.RangeTo(to, step);
}
}
附加功能
如果是 fromDate > toDate
,您可以抛出异常,但我更喜欢返回一个空范围而不是 []
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
for (DateTime dateTime=startDate;
dateTime < stopDate;
dateTime += TimeSpan.FromDays(interval))
{
}
DateTime begindate = Convert.ToDateTime("01/Jan/2018");
DateTime enddate = Convert.ToDateTime("12 Feb 2018");
while (begindate < enddate)
{
begindate= begindate.AddDays(1);
Console.WriteLine(begindate + " " + enddate);
}
根据问题你可以试试这个...
// looping between date range
while (startDate <= endDate)
{
//here will be your code block...
startDate = startDate.AddDays(1);
}
谢谢......
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
while ((startDate = startDate.AddDays(interval)) <= stopDate)
{
// do your thing
}
while
首次运行时添加一天。
这是我在 2020 年的 2 美分。
Enumerable.Range(0, (endDate - startDate).Days + 1)
.ToList()
.Select(a => startDate.AddDays(a));
您可能会考虑编写一个迭代器,它允许您使用普通的“for”循环语法,如“++”。我在 StackOverflow 上搜索并发现了一个类似的问题 answered,它提供了有关使 DateTime 可迭代的指针。
您可以使用 DateTime.AddDays()
函数将您的 DayInterval
添加到 StartDate
并检查以确保它小于 EndDate
。
您必须在这里小心,不要错过循环中更好的解决方案的日期。
这为您提供了 startdate 的第一个日期,并在增加它之前在循环中使用它,它将处理所有日期,包括 enddate 的最后日期,因此 <= enddate。
所以上面的答案是正确的。
while (startdate <= enddate)
{
// do something with the startdate
startdate = startdate.adddays(interval);
}
你可以用这个。
DateTime dt0 = new DateTime(2009, 3, 10);
DateTime dt1 = new DateTime(2009, 3, 26);
for (; dt0.Date <= dt1.Date; dt0=dt0.AddDays(3))
{
//Console.WriteLine(dt0.Date.ToString("yyyy-MM-dd"));
//take action
}
每 15 分钟迭代一次
DateTime startDate = DateTime.Parse("2018-06-24 06:00");
DateTime endDate = DateTime.Parse("2018-06-24 11:45");
while (startDate.AddMinutes(15) <= endDate)
{
Console.WriteLine(startDate.ToString("yyyy-MM-dd HH:mm"));
startDate = startDate.AddMinutes(15);
}
@jacob-sobus 和 @mquander 和 @Yogurt 不完全正确.. 如果我需要第二天我等待 00:00 时间
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.NextDay())
yield return day;
}
public static IEnumerable<DateTime> EachMonth(DateTime from, DateTime thru)
{
for (var month = from.Date; month.Date <= thru.Date || month.Year == thru.Year && month.Month == thru.Month; month = month.NextMonth())
yield return month;
}
public static IEnumerable<DateTime> EachYear(DateTime from, DateTime thru)
{
for (var year = from.Date; year.Date <= thru.Date || year.Year == thru.Year; year = year.NextYear())
yield return year;
}
public static DateTime NextDay(this DateTime date)
{
return date.AddTicks(TimeSpan.TicksPerDay - date.TimeOfDay.Ticks);
}
public static DateTime NextMonth(this DateTime date)
{
return date.AddTicks(TimeSpan.TicksPerDay * DateTime.DaysInMonth(date.Year, date.Month) - (date.TimeOfDay.Ticks + TimeSpan.TicksPerDay * (date.Day - 1)));
}
public static DateTime NextYear(this DateTime date)
{
var yearTicks = (new DateTime(date.Year + 1, 1, 1) - new DateTime(date.Year, 1, 1)).Ticks;
var ticks = (date - new DateTime(date.Year, 1, 1)).Ticks;
return date.AddTicks(yearTicks - ticks);
}
public static IEnumerable<DateTime> EachDayTo(this DateTime dateFrom, DateTime dateTo)
{
return EachDay(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachMonthTo(this DateTime dateFrom, DateTime dateTo)
{
return EachMonth(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachYearTo(this DateTime dateFrom, DateTime dateTo)
{
return EachYear(dateFrom, dateTo);
}
如果您将日期转换为 OADate,您可以像使用任何 double
数字一样循环它们。
DateTime startDate = new DateTime(2022, 1, 1);
DateTime endDate = new DateTime(2022, 12, 31);
for (double loopDate = startDate.ToOADate(); loopDate <= endDate.ToOADate(); loopDate++)
{
DateTime selectedDate;
selectedDate = DateTime.FromOADate(loopDate);
}
不定期副业成功案例分享