英文:
C# DateTime validation: Handling activity shift periods that span across midnight
问题
I am trying to resolve an issue in regard to an activity status function for a specific condition. The function is trying to check if a signature on the activity falls within a validity period of two dates within a shift.
活动状态函数针对特定条件尝试解决问题,该函数试图检查活动上的签名是否在班次内的两个日期的有效期内。
The activity has a stored start and finish DateTime as follows:
活动具有存储的开始和结束日期时间,如下所示:
var startDate = activity.Start; // ex. new DateTime(2023, 05, 25, 18, 00, 00, DateTimeKind.Utc)
var finishDate = activity.Finish; // ex. new DateTime(2023, 06, 01, 04, 00, 00, DateTimeKind.Utc)
In this instance, shifts would be between 18:00 - 04:00 each day (i.e. 25/05 18:00 -> 26/05 04:00, 26/05 18:00 -> 27/05 04:00 etc) which are stored against a shift integer based on the working day (this will usually be in the range of 1-7). If the time that the signature is made is within the validity period then it will go to a "Live" status, otherwise it will go to an "Awaiting Start" status.
在这种情况下,每天的班次将在18:00 - 04:00之间(例如,25/05 18:00 -> 26/05 04:00,26/05 18:00 -> 27/05 04:00等),这些班次存储在基于工作日的班次整数中(通常在1-7范围内)。如果签名时间在有效期内,则状态将变为“Live”,否则将变为“Awaiting Start”。
Currently the logic in place is as follows. This will return Live
if now
is after midnight within the validity period of a shift but if the signature time is before midnight, then it will return Awaiting Start
.
目前的逻辑如下。如果“now”在班次的有效期内的午夜之后,则会返回“Live”,但如果签名时间在午夜之前,则会返回“Awaiting Start”。
public void SetStatus (T activity)
{
//....
if (startTime.Date <= DateTime.UtcNow.Date && finishTime.Date >= DateTime.UtcNow.Date)
{
if (finishTime.TimeOfDay < startTime.TimeOfDay)
activity.Status = SetStatusIfShiftCrossesMidnight(startTime, finishTime);
// ... other checks
}
}
private string SetStatusIfShiftCrossesMidnight(DateTime startDate, DateTime finishDate)
{
var now = DateTime.UtcNow;
var start = new DateTime(now.Year, now.Month, now.Day - 1 , startDate.Hour, startDate.Minute,
startDate.Second, DateTimeKind.Utc);
var finish = new DateTime(now.Year, now.Month, now.Day, finishDate.Hour, finishDate.Minute,
finishDate.Second, DateTimeKind.Utc);
if (start <= now && finish > now)
return "Live";
return "Awaiting Start";
}
Any recommendedations on the best way to tackle this?
有关解决此问题的最佳方法的任何建议?
英文:
I am trying to resolve an issue in regard to an activity status function for a specific condition. The function is trying to check if an signature on the activity falls within a validity period of two dates within a shift.
The activity has a stored start and finish DateTime as follows:
var startDate = activity.Start; // ex. new DateTime(2023, 05, 25, 18, 00, 00, DateTimeKind.Utc)
var finishDate = activity.Finish; // ex. new DateTime(2023, 06, 01, 04, 00, 00, DateTimeKind.Utc)
In this instance, shifts would be between 18:00 - 04:00 each day (i.e. 25/05 18:00 -> 26/05 04:00, 26/05 18:00 -> 27/05 04:00 etc) which are stored against a shift integer based on the working day (this will usually be in the range of 1-7). If the time that the signature is made is within the validity period then it will go to a "Live" status, otherwise it will go to a "Awaiting Start" status.
Currently the logic in place is as follows. This will return Live
if now
is after midnight within the validity period of a shift but if the signature time is before midnight, then it will return Awaiting Start
.
public void SetStatus (T activity)
{
//....
if (startTime.Date <= DateTime.UtcNow.Date && finishTime.Date >= DateTime.UtcNow.Date)
{
if (finishTime.TimeOfDay < startTime.TimeOfDay)
activity.Status = SetStatusIfShiftCrossesMidnight(startTime, finishTime);
// ... other checks
}
}
private string SetStatusIfShiftCrossesMidnight(DateTime startDate, DateTime finishDate)
{
var now = DateTime.UtcNow;
var start = new DateTime(now.Year, now.Month, now.Day - 1 , startDate.Hour, startDate.Minute,
startDate.Second, DateTimeKind.Utc);
var finish = new DateTime(now.Year, now.Month, now.Day, finishDate.Hour, finishDate.Minute,
finishDate.Second, DateTimeKind.Utc);
if (start <= now && finish > now)
return "Live";
return "Awaiting Start";
}
Any recommendedations on the best way to tackle this?
答案1
得分: 1
如果我理解正确,您有一个shift
,它是一个范围
18:00 - 04:00
您有一个时间,比如
23:00
您想要检查该时间是否在这个班次内。如果这是您的任务,那么
// 只有时间,日期部分被忽略
private static bool WithinShift((TimeOnly start, TimeOnly end) shift, TimeOnly time) =>
(shift.end >= shift.start)
? time >= shift.start && time <= shift.end
: time >= shift.start || time <= shift.end;
// 考虑日期组件
private static bool WithinShift((DateTime start, DateTime end) shift, DateTime time) =>
time >= shift.start && time <= shift.end;
例如
var shift = (start : new TimeOnly(18, 0, 0), end : new TimeOnly(4, 0, 0));
var tests = new TimeOnly[] {
new (23, 0, 0),
new ( 0, 0, 0),
new ( 3, 0, 0),
new ( 5, 0, 0),
new ( 9, 0, 0),
new (12, 0, 0),
new (17, 0, 0),
new (20, 0, 0)
};
var report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,9} : {(WithinShift(shift, test) ? "Live" : "Awaiting Start")}}"));
Console.WriteLine(report);
// 日期组件
var now = DateTime.Now;
var currentShift = (
now.Date + shift.start.ToTimeSpan(),
now.Date + shift.end.ToTimeSpan());
report =
$"time: {now:HH:mm} shift {currentShift} is {(WithinShift(currentShift, now) ? "Live" : "Awaiting Start")}";
Console.WriteLine();
Console.WriteLine(report);
输出:
11:00 PM : Live
12:00 AM : Live
3:00 AM : Live
5:00 AM : Awaiting Start
9:00 AM : Awaiting Start
12:00 PM : Awaiting Start
5:00 PM : Awaiting Start
8:00 PM : Live
time: 11:03 shift (5/26/2023 6:00:00 PM, 5/26/2023 4:00:00 AM) is Awaiting Start
英文:
If I understand you right, you have a shift
, which is a range
18:00 - 04:00
and you have a time, say
23:00
and you want to check if the time is within the shift. If it's your task then
// Just time, Date part is ignored
private static bool WithinShift((TimeOnly start, TimeOnly end) shift, TimeOnly time) =>
(shift.end >= shift.start)
? time >= shift.start && time <= shift.end
: time >= shift.start || time <= shift.end;
// Date component is taken in to account
private static bool WithinShift((DateTime start, DateTime end) shift, DateTime time) =>
time >= shift.start && time <= shift.end;
E.g.
var shift = (start : new TimeOnly(18, 0, 0), end : new TimeOnly(4, 0, 0));
var tests = new TimeOnly[] {
new (23, 0, 0),
new ( 0, 0, 0),
new ( 3, 0, 0),
new ( 5, 0, 0),
new ( 9, 0, 0),
new (12, 0, 0),
new (17, 0, 0),
new (20, 0, 0)
};
var report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,9} : {(WithinShift(shift, test) ? "Live" : "Awaiting Start")}"));
Console.WriteLine(report);
// Date Component
var now = DateTime.Now;
var currentShift = (
now.Date + shift.start.ToTimeSpan(),
now.Date + shift.end.ToTimeSpan());
report =
$"time: {now:HH:mm} shift {currentShift} is {(WithinShift(currentShift, now) ? "Live" : "Awaiting Start")}";
Console.WriteLine();
Console.WriteLine(report);
Output:
11:00 PM : Live
12:00 AM : Live
3:00 AM : Live
5:00 AM : Awaiting Start
9:00 AM : Awaiting Start
12:00 PM : Awaiting Start
5:00 PM : Awaiting Start
8:00 PM : Live
time: 11:03 shift (5/26/2023 6:00:00 PM, 5/26/2023 4:00:00 AM) is Awaiting Start
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论