2个日期时刻之间的时差

时间:2016-11-15 20:29:21

标签: javascript datetime momentjs

我有2个日期时间对象。

now = Nov 15 4:00 PM
later = Nov 15 6:00PM

我的目标是在现在和以后的时间内获得(上午9点到下午5点)之间的总小时数。

结果回答是1小时。 (因为我只关心时间范围在上午9点到下午5点之间)

now =  Nov 15 6:00 AM
later = Nov 15 8:00 PM

结果答案应该是8小时。

是使用diff函数实现这一目标的最佳方法,它可以解决小时数并计算个别用例(当开始时间小于9 AM /开始时间大于9 AM时)。类似的结束时间(不到下午5点/下午5点以后)等?

如何处理这种情况,

now = Nov 15 9:00AM
later = Nov 18 2:00PM

结果回答不好,

8(nov 15)+8(nov 16)+8(nov 17)+5(nov 18)= 29hrs

4 个答案:

答案 0 :(得分:1)

这是工作解决方案

var now = moment("15 Nov 2016, 9:00:00 am", "DD MMM yyyy, h:mm:ss a").toDate();
var later = moment("18 Nov 2016, 2:00:00 pm", "DD MMM yyyy, h:mm:ss a").toDate();

function getWorkingHours(now, later) {
	var hoursToday = 0;

	var workingHourStart = 9;
	var workingHourEnd = 17;//5pm
	var workDuration = workingHourEnd - workingHourStart;
	
	if(workingHourEnd - getHours(now) > 0) {
		hoursToday = (workingHourEnd - getHours(now));
		hoursToday = (hoursToday > workDuration) ? workDuration : hoursToday;
	}

	var hoursLater = 0;

	if(getHours(later) - workingHourStart > 0) {
		hoursLater = (getHours(later) - workingHourStart);
		hoursLater = (hoursLater > workDuration) ? workDuration : hoursLater;
	}

	var actualDiffHours = (later.getTime() - now.getTime()) / (1000 * 60 * 60);
	var actualHoursInBetween = actualDiffHours - (24 - getHours(now)) - getHours(later);

	var workingHoursInBetween = (actualHoursInBetween / 24) * 8;
	
	return hoursToday + workingHoursInBetween + hoursLater;
}

function getHours(date) {
	var hours = date.getHours() + date.getMinutes() / 60 + date.getSeconds() / 3600 + date.getMilliseconds() / 3600/1000;
	return hours;
}

console.log(getWorkingHours(now, later));
<script src="http://momentjs.com/downloads/moment.min.js"></script>

答案 1 :(得分:1)

这应该做的工作:

&#13;
&#13;
const now = moment(new Date(2016, 11, 15, 9, 0, 0));
const then = moment(new Date(2016, 11, 18, 14, 0, 0));

function calDiff(now, then) {
  if (now.hour() < 9) {
    now.hour(9);
  }

  if (then.hour() > 17) {
    then.hour(17);
  }

  const total = then.diff(now, 'hours');

  const day = Math.floor(total / 24);
  
  return total - (16 * day);
}

console.log(calDiff(now, then));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

复杂...函数getActiveHours计算开始日期和结束日期之间的所有活动插槽(包括两者),然后删除开始日期开始时和结束日期结束时的缺失小时数。

var getDateObject = function (date) {
  if (date && date.constructor.name == "Array") {
    while (date.length < 7) {date.push(0);}
    date = new Date(date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
  } else if (typeof date == 'string' || typeof date == 'number') {
    date = new Date(date);
  }
  return date;
};

var trimDate = function (date, period) {
  var periods = ['second', 'minute', 'hour', 'day'];
  period = periods.indexOf(period);
  if (typeof date != 'number') {date = getDateObject(date).getTime();}
  date = Math.floor(date/1000);
  if (period > 0) {date = Math.floor(date/60);}
  if (period > 1) {date = Math.floor(date/60);}
  if (period > 2) {date = Math.floor(date/24);}
  return new Date(date*24*60*60*1000);
};

var getOffset = function (date) {return getDateObject(date).getTimezoneOffset()*60*1000;};

var addOffset = function (date) {
  date = getDateObject(date);
  return new Date(date.getTime()+getOffset(date));
};

var getActiveHours = function (iniDateTime, endDateTime, startHour, finishHour) {
  var hourMs = 60*60*1000; // Define daily active hours 0-24 (decimal 17.5 = 5:30pm):
  if (startHour == null) {startHour = 9;}
  if (finishHour == null) {finishHour = 17;}
  startHour *= hourMs; finishHour *= hourMs;
  iniDateTime = getDateObject(iniDateTime).getTime();
  endDateTime = getDateObject(endDateTime).getTime();
  var iniDayTime = addOffset(trimDate(iniDateTime, 'day')).getTime();
  var endDayTime = addOffset(trimDate(endDateTime, 'day')).getTime();
  var totalHoursMs = (endDayTime-iniDayTime+24*hourMs)*(finishHour-startHour)/hourMs/24;
  var iniHoursNotInMs = iniDateTime-iniDayTime-startHour;
  var endHoursNotInMs = endDayTime+finishHour-endDateTime;
  return (totalHoursMs-iniHoursNotInMs-endHoursNotInMs)/hourMs;
};

console.log(Math.round(getActiveHours('2016-09-13 11:45:38', '2016-09-15 15:30:25'))); // 20 // Use Math round or floor

答案 3 :(得分:0)

当我第一次看到这个问题时,我已经开始写这篇文章了,但却陷入了困境。我的答案与Khang的非常相似,但我们对它的某个部分的看法略有不同。

代码背后的基本思想是它需要两个时刻的对象。如果开始时间小于9,我们将它们设置为9,如果结束时间大于17(下午5点),我们将它们设置为17。

接下来,我们将在几天内得出两个对象之间的差异。对于每一天,我们都知道该人可以获得8小时的学分。然后我将开始日期的日期移动到结束日期,并在它们之间花费时间。

这背后的想法是,如果两个时间都在同一天内,那么将有0天的差异。如果是1,那么无论我们从哪天开始,我们总共可以获得8小时。我没有经过测试的唯一情况是开始时间大于结束时间的事情(如果我需要改变的话,我会尽快测试并进行编辑)

修改

如果开始时间在结束时间(小时)之后,确实存在问题。 通过添加一个if语句来解决这个问题。

&#13;
&#13;
$(function() {
  function getActiveHours(start, end) {
    if (start.hours() < 9) start.hours(9);
    if (end.hours() > 17) end.hours(17);
    //These two if's should remove most of the issues when we are doing basic work
    var days = end.diff(start, 'days');
    if (days == 0 && (end.date() - start.date()) == 1) days = 1;
    var hours = (days * 8); //gets the hours
    start.date(end.date());
    var diff = end.diff(start, 'hours');
    return hours + diff;
  }
  var start = moment([2016, 10, 15, 9, 0, 0]);
  var end = moment([2016, 10, 18, 14, 0, 0]);

  $('#results').html('Total hours worked from ' + start.format('MM-DD-YYYY @ hh:mm:ss') + ' to ' + end.format('MM-DD-YYYY @ hh:mm:ss') + ' is ' + getActiveHours(start, end))

});
&#13;
<div id="results"></div>
&#13;
&#13;
&#13;