我正在尝试根据每天工作指定的小时数计算两个日期之间的天数。我无法确定在1天内选择了多少完整和半天,例如如果在日历上选择了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;
}
}
答案 0 :(得分:1)
试试这个。这段代码不是用VS编写的,所以它可能并不完美......只使用其中的逻辑。
int htot = 0, dtot = 0;
while (date2>date1) {
int h1 = date1.Hour < work_start ? work_start : date1.Hour;
int h2 = date1.Hour > work_end ? work_end : date1.Hour;
htot += (h2-h1);
dtot++;
date1 = date1.AddDays(1);
}