我正在尝试计算基于每天工作指定小时数的两个日期之间的天数。我无法确定在一天内选择了多少个全天和半天,例如如果在日历上选择了1天,那么这实际上是1整天。根据工作日中的小时计算小时数
如果09:00当天选择了一个,并在第2天说出13:00,那么这将是大约12个工作小时和1.5天。
编辑:最后,希望最后的更新,这说明最终的结果代码,以使这一问题在未来
还需加银行假日检查等更具有可读性,但它大致有)
//Validate working day rules are available
List<DayOfWeek> lDaysValidated = new List<DayOfWeek>();
double dTotalDays = 0;
//loop though the days between the two dates
for (var day = dtStartDate; day <= dtEndTime; day = day.AddDays((1)))
{
//Only perform validation if the day of week has not already been validated
if (!lDaysValidated.Contains(day.DayOfWeek))
{
//Look for working day rules for the user
List<UserTimeRule> lWorkingDayRules = UserTimeRule.GetUserTimeRules(
this.CurrentHolidayRequest.RequestedByID,
day.DayOfWeek,
false,
Settings.Instance.CostingModule,
TimeRuleRecordTypeEnum.DayRule);
//If the user has no rules, check the defaults
if (lWorkingDayRules.Count == 0)
{
//Get default rules for the day of week
lWorkingDayRules = UserTimeRule.GetDefaultUserTimeRules(
day.DayOfWeek);
//If there is still no day rule, show error message and return
if (lWorkingDayRules.Count == 0)
{
//Show error message
lblWorkingDaysError.Text =
String.Format(
"* The current user has no working day rules set up, and there is no default day rule for '{0}'",
day.DayOfWeek);
return;
}
else
{
//Calculate the working days
this.CalculateWorkingDays(
ref dtStartDate,
ref dtEndTime,
day,
lWorkingDayRules,
ref dTotalDays
);
//Add the day of week to the list of already validated days
lDaysValidated.Add(day.DayOfWeek);
}
}
else
{
//Calculate the working days
this.CalculateWorkingDays(
ref dtStartDate,
ref dtEndTime,
day,
lWorkingDayRules,
ref dTotalDays
);
//Add the day of week to the list of already validated days
lDaysValidated.Add(day.DayOfWeek);
}
}
}
#endregion Validate
#region Update Details
//Set the Dates
this.CurrentHolidayRequestLine.StartTime = dtStartDate;
this.CurrentHolidayRequestLine.EndTime = dtEndTime;
//Set the number of Days
this.CurrentHolidayRequestLine.Days = Convert.ToDecimal(dTotalDays);
而且计算总天数的方法:
/// <summary>
/// Calculates the number of working days for a specified day
/// </summary>
/// <param name="dtHolidayStartTime">The start time of the holiday request</param>
/// <param name="dtHolidayEndTime">The end time of the holiday request</param>
/// <param name="dtCurrentDay">The current day being evaluated</param>
/// <param name="lWorkingDayRules">The current set of working day rules</param>
/// <param name="dTotalDays">A reference to the total days on the request</param>
[VersionChange("7.3.88.271", "10/04/2011", "Method added to calculate No days on a request")]
private void CalculateWorkingDays(ref DateTime dtHolidayStartTime, ref DateTime dtHolidayEndTime, DateTime dtCurrentDay, List<UserTimeRule> lWorkingDayRules, ref double dTotalDays)
{
try
{
//Check whether Holiday start time is before the start time of the working day
if (dtHolidayStartTime.TimeOfDay < lWorkingDayRules[ 0 ].StartTime.TimeOfDay)
{
dtHolidayStartTime = new DateTime(
dtHolidayStartTime.Year,
dtHolidayStartTime.Month,
dtHolidayStartTime.Day,
lWorkingDayRules[ 0 ].StartTime.Hour,
lWorkingDayRules[ 0 ].StartTime.Minute,
lWorkingDayRules[ 0 ].StartTime.Minute);
}
//Check whether the holiday end time is after the end time of a nomal working day
if (dtHolidayEndTime.TimeOfDay > lWorkingDayRules[ 0 ].EndTime.TimeOfDay)
{
dtHolidayEndTime = new DateTime(
dtHolidayEndTime.Year,
dtHolidayEndTime.Month,
dtHolidayEndTime.Day,
lWorkingDayRules[ 0 ].EndTime.Hour,
lWorkingDayRules[ 0 ].EndTime.Minute,
lWorkingDayRules[ 0 ].EndTime.Minute);
}
//Check whether the holiday end time is after lunch time, but before the end of the day
if (dtHolidayEndTime.TimeOfDay > lWorkingDayRules[ 0 ].LunchEndTime.TimeOfDay
&& dtHolidayEndTime.TimeOfDay < lWorkingDayRules[ 0 ].EndTime.TimeOfDay)
{
dtHolidayEndTime = new DateTime(
dtHolidayEndTime.Year,
dtHolidayEndTime.Month,
dtHolidayEndTime.Day,
lWorkingDayRules[ 0 ].LunchEndTime.Hour,
lWorkingDayRules[ 0 ].LunchEndTime.Minute,
lWorkingDayRules[ 0 ].LunchEndTime.Minute);
}
//Create a date time object for the end current working day
DateTime dtWorkingDayEndTime = new DateTime(
dtCurrentDay.Year,
dtCurrentDay.Month,
dtCurrentDay.Day,
lWorkingDayRules[ 0 ].EndTime.Hour,
lWorkingDayRules[ 0 ].EndTime.Minute,
lWorkingDayRules[ 0 ].EndTime.Second);
//Create a date time object for the end of lunch
DateTime dtWorkingDayLunchTime = new DateTime(
dtCurrentDay.Year,
dtCurrentDay.Month,
dtCurrentDay.Day,
lWorkingDayRules[ 0 ].LunchEndTime.Hour,
lWorkingDayRules[ 0 ].LunchEndTime.Minute,
lWorkingDayRules[ 0 ].LunchEndTime.Second);
//Create a date time object for the start of the current day
DateTime dtWorkingDayStartTime = new DateTime(
dtCurrentDay.Year,
dtCurrentDay.Month,
dtCurrentDay.Day,
lWorkingDayRules[ 0 ].StartTime.Hour,
lWorkingDayRules[ 0 ].StartTime.Minute,
lWorkingDayRules[ 0 ].StartTime.Second);
//Check whether to add the first half of the day
if (dtHolidayEndTime >= dtWorkingDayLunchTime)
{
dTotalDays += 0.5f;
}
//Check whether to add the second half of the day
if (dtHolidayEndTime >= dtWorkingDayEndTime)
{
dTotalDays += 0.5f;
}
}
catch (Exception)
{
throw;
}
}
不要忘记考虑夏令时。 – 2011-04-10 12:59:27
我已经写了一个库,可以很容易地执行这种计算。一年多以来,它已经在一家客户的全天候生产中使用了一年多,用于各种复杂的全球日历计算。如果您对许可产品感兴趣,请告诉我。 (我没有它的网站) – 2011-04-10 13:07:42
@uosɐs:我不认为你正在回应他的答案或帮助他解决他的问题... – Marco 2011-04-10 14:47:39