Математическая функция для часов в месяц - PullRequest
0 голосов
/ 07 февраля 2020

Есть ли математическая функция для расчета часов в месяце без учета выходных?

Допустим, я получаю дни в месяце с MomentJS. Рабочий день имеет 7:36 часов, и вам нужно работать 5 дней в неделю (исключая выходные).

Если, например, месяц имеет 30 дней , и я знаю, что есть 7: 36 часов в день (7 часов и 36 минут) , но мне нужно исключать каждые выходные в месяце, как будет выглядеть подобная функция / возможно ли ее иметь такая функция? Мне нужно, чтобы он работал в React Native, поэтому JavaScript.

Ответы [ 3 ]

1 голос
/ 07 февраля 2020

Подсчет рабочих дней

const pad = num => ("0" + num).slice(-2);
const minutesPerDay = 7 * 60 + 36; // or 7.6 hours
const isWorkingDay = d => d.getDay() !== 0 && d.getDay() !== 6;
const getHHMM = m => `${Math.floor(m / 60)}:${pad(m % 60)}`;

const getHours = (year, month) => {
  const startDate = new Date(year, month - 1, 1, 15, 0, 0); // we need a date object
  const endDay = new Date(year, month, 0).getDate(); // and number of days in the month
  console.log("start", new Date(startDate), "end", "+" + endDay)

  let workingDays = 0;
  for (let i = 1; i <= endDay; i++) { // count from 1 to and including last day of month
    startDate.setDate(i); // reuse startdate object
    workingDays += isWorkingDay(startDate) ? 1 : 0; // if 0 or 6, ignore
  }
  return getHHMM(workingDays * minutesPerDay); // format to HH:MM
};
console.log(getHours(2020, 1)); // jan
console.log(getHours(2020, 2)); // feb
0 голосов
/ 07 февраля 2020

Вам нужно будет перевести функцию щелчка, чтобы отреагировать, но функции могут работать на вас:)

Вам нужно знать месяц, а также год :). Я использую селектор даты, чтобы было легче выбрать месяц и попробовать. Но важные данные за месяц и за год.

function getDaysMonth(m, y) {
   return 32 - new Date(y, m, 32).getDate();
}

function checkWorkingDay(y, m, d) {
    let day = new Date(y, m, d).getDay();
    return day !=0 && day !=6;
}

function getHoursInMonth(month, year) {
   let days = getDaysMonth(month, year);
   let weekdays = 0;
   for(var i=0; i< days; i++) {
       if (checkWorkingDay(year, month, i+1)) weekdays++;
   }
   
   let minutes = (weekdays * ((7 * 60) + 36));

   return Math.floor(minutes / 60) + ':' + (minutes % 60);
}

  
document.getElementById("dateInput").addEventListener("change", function() {
    let input = this.value;
    let myDate = new Date(input);
    let hours = getHoursInMonth(myDate.getMonth(), myDate.getYear()); 
    document.getElementById("dateOutput").innerHTML = hours;
});
<input type="date" id="dateInput" />
<p id="dateOutput"></p>
0 голосов
/ 07 февраля 2020

Я определил итератор для дней месяца плюс предикат для проверки, который не является концом недели.

Примечания

  • Число месяцев начинается в 0. Итак, январь = 0. Я заставил итератор взять смещение номера месяца на единицу, сделав январь = 1.
  • Дни недели. Итак, воскресенье = 0 и суббота = 6.

function isNotWeekEnd(date)
{
    let dayOfTheWeek = date.getDay();
    return dayOfTheWeek != 0 && dayOfTheWeek != 6;
}

function* daysOfTheMonth(year, month)
{
    let monthEnd = new Date(year, month, 1);
    let dayOfTheMonth = 1;
    let dayStart = new Date(year, month - 1, dayOfTheMonth);
    while(monthEnd - dayStart > 0)
    {
        yield dayStart;
        dayOfTheMonth++;
        dayStart = new Date(year, month - 1, dayOfTheMonth);
    }
}

const workHoursPerDay = 7.6; // 7 hours plus 36 minutes
let nonWeekEnds = Array.from(daysOfTheMonth(2020, 1 /* January*/)).filter(isNotWeekEnd);
let workHours = nonWeekEnds.length * workHoursPerDay;

console.log({workHours});

Вывод:

{
    "workHours": 174.79999999999998
}

Я должен быть в состоянии избежать объектов даты, объединив предикат в итераторе. На самом деле, мне не нужен итератор, просто количество дней.

const millisecondsPerSecond = 1000;
const secondsPerHour = 3600;
const hoursPerDay = 24;

const workHoursPerDay = 7.6; // 7 hours plus 36 minutes

const millisecondsPerDay = millisecondsPerSecond * secondsPerHour * hoursPerDay;

function daysInMonth(year, month)
{
    let monthEnd = new Date(year, month, 1);
    let monthStart = new Date(year, month - 1, 1);
    let millisecondsInMonth = monthEnd - monthStart;
    return millisecondsInMonth / millisecondsPerDay;
}

function notWeekEndsOfTheMonth(year, month)
{
    const daysPerWeek = 7;
    let daysOfTheMonth = daysInMonth(year, month);
    let dayOfTheMonth = 1;
    let dayStart = new Date(year, month - 1, dayOfTheMonth);
    let dayOfTheWeek = dayStart.getDay();
    let days = 0;
    while(daysOfTheMonth >= dayOfTheMonth)
    {
        if (dayOfTheWeek != 0 && dayOfTheWeek != 6)
        {
            days++;
        }
        dayOfTheMonth++;
        dayOfTheWeek = (dayOfTheWeek + 1) % daysPerWeek;
    }
    return days;
}

let workHours = notWeekEndsOfTheMonth(2020, 1 /* January */) * workHoursPerDay;

console.log({workHours});
...