Làm thế nào tôi có thể có được ngày thứ ba tiếp theo?
Trong PHP, nó đơn giản như strtotime('next tuesday');
.
Làm thế nào tôi có thể đạt được một cái gì đó tương tự trong .NET
Làm thế nào tôi có thể có được ngày thứ ba tiếp theo?
Trong PHP, nó đơn giản như strtotime('next tuesday');
.
Làm thế nào tôi có thể đạt được một cái gì đó tương tự trong .NET
Câu trả lời:
Như tôi đã đề cập trong các bình luận, có nhiều điều bạn có thể có nghĩa là "Thứ ba tiếp theo", nhưng mã này cung cấp cho bạn "thứ ba tiếp theo sẽ xảy ra hoặc hôm nay nếu đó là thứ ba":
DateTime today = DateTime.Today;
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilTuesday = ((int) DayOfWeek.Tuesday - (int) today.DayOfWeek + 7) % 7;
DateTime nextTuesday = today.AddDays(daysUntilTuesday);
Nếu bạn muốn đưa ra "thời gian một tuần" nếu đã là thứ ba, bạn có thể sử dụng:
// This finds the next Monday (or today if it's Monday) and then adds a day... so the
// result is in the range [1-7]
int daysUntilTuesday = (((int) DayOfWeek.Monday - (int) today.DayOfWeek + 7) % 7) + 1;
... Hoặc bạn có thể sử dụng công thức gốc, nhưng từ ngày mai:
DateTime tomorrow = DateTime.Today.AddDays(1);
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilTuesday = ((int) DayOfWeek.Tuesday - (int) tomorrow.DayOfWeek + 7) % 7;
DateTime nextTuesday = tomorrow.AddDays(daysUntilTuesday);
EDIT: Chỉ để làm cho điều này tốt đẹp và linh hoạt:
public static DateTime GetNextWeekday(DateTime start, DayOfWeek day)
{
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysToAdd = ((int) day - (int) start.DayOfWeek + 7) % 7;
return start.AddDays(daysToAdd);
}
Vì vậy, để có được giá trị cho "hôm nay hoặc trong 6 ngày tới":
DateTime nextTuesday = GetNextWeekday(DateTime.Today, DayOfWeek.Tuesday);
Để nhận giá trị cho "thứ ba tiếp theo trừ ngày hôm nay":
DateTime nextTuesday = GetNextWeekday(DateTime.Today.AddDays(1), DayOfWeek.Tuesday);
+7)%7
giải pháp là khá tốt mặc dù. Mặc dù lý do tôi không sử dụng là vì đó là một chút tối ưu hóa vi mô và quá dễ bị sai (cũng như hy sinh một số khả năng đọc), tất nhiên là imho.
Cái này cần phải dùng mẹo:
static DateTime GetNextWeekday(DayOfWeek day)
{
DateTime result = DateTime.Now.AddDays(1);
while( result.DayOfWeek != day )
result = result.AddDays(1);
return result;
}
.AddDays(1)
dòng đầu tiên, theo cách đó nó cũng sẽ DateTime.Now
tự kiểm tra .
Có ít giải pháp dài dòng hơn và thông minh hơn / giải pháp cho vấn đề này, nhưng hàm C # sau hoạt động thực sự tốt cho một số tình huống.
/// <summary>
/// Find the closest weekday to the given date
/// </summary>
/// <param name="includeStartDate">if the supplied date is on the specified day of the week, return that date or continue to the next date</param>
/// <param name="searchForward">search forward or backward from the supplied date. if a null parameter is given, the closest weekday (ie in either direction) is returned</param>
public static DateTime ClosestWeekDay(this DateTime date, DayOfWeek weekday, bool includeStartDate = true, bool? searchForward=true)
{
if (!searchForward.HasValue && !includeStartDate)
{
throw new ArgumentException("if searching in both directions, start date must be a valid result");
}
var day = date.DayOfWeek;
int add = ((int)weekday - (int)day);
if (searchForward.HasValue)
{
if (add < 0 && searchForward.Value)
{
add += 7;
}
else if (add > 0 && !searchForward.Value)
{
add -= 7;
}
else if (add == 0 && !includeStartDate)
{
add = searchForward.Value ? 7 : -7;
}
}
else if (add < -3)
{
add += 7;
}
else if (add > 3)
{
add -= 7;
}
return date.AddDays(add);
}
@Jon Skeet trả lời tốt.
Cho ngày trước:
private DateTime GetPrevWeekday(DateTime start, DayOfWeek day) {
// The (... - 7) % 7 ensures we end up with a value in the range [0, 6]
int daysToRemove = ((int) day - (int) start.DayOfWeek - 7) % 7;
return start.AddDays(daysToRemove);
}
Cảm ơn!!
DayOfWeek
giá trị như thế này:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Mẫu rất đơn giản để bao gồm hoặc loại trừ ngày hiện tại, bạn chỉ định ngày và ngày trong tuần bạn quan tâm.
public static class DateTimeExtensions
{
/// <summary>
/// Gets the next date.
/// </summary>
/// <param name="date">The date to inspected.</param>
/// <param name="dayOfWeek">The day of week you want to get.</param>
/// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>
/// <returns></returns>
public static DateTime GetNextDate(this DateTime date, DayOfWeek dayOfWeek, bool exclDate = true)
{
//note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today
//eg: date - Today = 0 - 1 = -1, so have to move it forward
var diff = dayOfWeek - date.DayOfWeek;
var ddiff = date.Date.Subtract(DateTime.Today).Days + diff;
//note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in
//note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on date
if (ddiff < 0 || ddiff >= (exclDate ? 6 : 7) && diff < 0)
diff += 7;
//note: now we can get safe values between 0 - 6, especially if past dates is being used
diff = diff % 7;
//note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
diff += diff == 0 & exclDate ? 7 : 0;
return date.AddDays(diff);
}
}
một số trường hợp thử nghiệm
[TestMethod]
public void TestNextDate()
{
var date = new DateTime(2013, 7, 15);
var start = date;
//testing same month - forwardOnly
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //16
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //17
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //18
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Friday)); //19
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Saturday)); //20
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Sunday)); //21
Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Monday)); //22
//testing same month - include date
Assert.AreEqual(start = date, date.GetNextDate(DayOfWeek.Monday, false)); //15
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday, false)); //16
Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday, false)); //17
//testing month change - forwardOnly
date = new DateTime(2013, 7, 29);
start = date;
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //30
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //31
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //2013/09/01-month increased
Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Friday)); //02
//testing year change
date = new DateTime(2013, 12, 30);
start = date;
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //31
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //2014/01/01 - year increased
Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //02
}
Nó cũng có thể là một phần mở rộng, tất cả phụ thuộc vào
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> Next(this DateTime date, DayOfWeek day)
{
// This loop feels expensive and useless, but the point is IEnumerable
while(true)
{
if (date.DayOfWeek == day)
{
yield return date;
}
date = date.AddDays(1);
}
}
}
Sử dụng
var today = DateTime.Today;
foreach(var monday in today.Next(DayOfWeek.Monday))
{
Console.WriteLine(monday);
Console.ReadKey();
}
Bây giờ trong hương vị oneliner - trong trường hợp bạn cần chuyển nó dưới dạng tham số vào một số cơ chế.
DateTime.Now.AddDays(((int)yourDate.DayOfWeek - (int)DateTime.Now.DayOfWeek + 7) % 7).Day
Trong trường hợp cụ thể này:
DateTime.Now.AddDays(((int)DayOfWeek.Tuesday - (int)DateTime.Now.DayOfWeek + 7) % 7).Day
Phiên bản mục tiêu C:
+(NSInteger) daysUntilNextWeekday: (NSDate*)startDate withTargetWeekday: (NSInteger) targetWeekday
{
NSInteger startWeekday = [[NSCalendar currentCalendar] component:NSCalendarUnitWeekday fromDate:startDate];
return (targetWeekday - startWeekday + 7) % 7;
}