例如:我在21:00 to 08:30上从Wednesday运行收银机,这意味着它在Wednesday 21:00上打开并在Thursday 08:30关闭我将收银机的工作时间存储为距0 - 1440的分钟:

"cashRegister" : {
        "Monday" : {
            "open" : 1260,
            "close" : 510
        },
        "Tuesday" : {
            "open" : 1140,
            "close" : 420
        },
        "Wednesday" : {
            "open" : 1260,
            "close" : 510
        },
        "Thursday" : {
            "open" : 1260,
            "close" : 510
        },
        "Friday" : {
            "open" : 1260,
            "close" : 510
        },
        "Saturday" : {
            "open" : 1260,
            "close" : 510
        },
        "Sunday" : {
            "open" : 1260,
            "close" : 510
        }
    }


现在,例如,我登录到我的系统:Thursday 01:00,并且我的收银机开始在Wednesday 21:00上工作,我想返回以下时间段:from: 2017-01-11T21:00:00 to: 2017-01-12T08:30:00
问题是,例如,如果我登录以下地址:2017-01-11T22:00:00。我可以检查是否在2017-01-11 (Wednesday)上的寄存器正在工作,并通过午夜open > close并添加1天才能获得:2017-01-12T08:30:00但是,如果我在2017-01-12T01:30:00上登录,我就在Thursday上,如果我这样做,我最终会带有:2017-01-12T21:00:00 - 2017-01-13T08:30:00,这是错误的,因为寄存器从以下位置运行:2017-01-11T21:00:00 to: 2017-01-12T08:30:00,而不是:2017-01-12T21:00:00 to: 2017-01-13T08:30:00,所以从根本上来说,我只需要了解寄存器是否通过午夜,而我们实际上现在就通过午夜了。 :



const cashRegister = {
            "Monday" : {
                "open" : 1260,
                "close" : 510
            },
            "Tuesday" : {
                "open" : 1140,
                "close" : 420
            },
            "Wednesday" : {
                "open" : 1260,
                "close" : 510
            },
            "Thursday" : {
                "open" : 1260,
                "close" : 510
            },
            "Friday" : {
                "open" : 1260,
                "close" : 510
            },
            "Saturday" : {
                "open" : 1260,
                "close" : 510
            },
            "Sunday" : {
                "open" : 1260,
                "close" : 510
            }
        };

const todayUTC      = moment.utc().startOf('day');
const day           = todayUTC.format('dddd');
const registerToday = cashRegister[day];
const openingAt     = moment.utc(registerToday.open * 60000);
const closingAt     = moment.utc(registerToday.close * 60000);
const result = {};

  result.openingAt = todayUTC.clone().set({
     hour: openingAt.hours(),
     minute: openingAt.minutes(),
     second: 0,
  })
  result.closingAt = todayUTC.clone().set({
     hour: closingAt.hours(),
     minute: closingAt.minutes(),
     second: 0,
  }).add(openingAt > closingAt ? 1 : 0, 'days')

console.log(result) // perfect results

// if we check 1 minute after 00:00. we return bad results...

const minuteAfterTodayUTC  = moment.utc().endOf('day').add(1, 'minute');
const day2                 = minuteAfterTodayUTC.format('dddd');
const registerToday2       = cashRegister[day2];
const openingAt2           = moment.utc(registerToday2.open * 60000);
const closingAt2           = moment.utc(registerToday2.close * 60000);
const result2              = {};

  result2.openingAt2 = minuteAfterTodayUTC.clone().set({
     hour: openingAt2.hours(),
     minute: openingAt2.minutes(),
     second: 0,
  })
  result2.closingAt2 = minuteAfterTodayUTC.clone().set({
     hour: closingAt2.hours(),
     minute: closingAt2.minutes(),
     second: 0,
  }).add(openingAt > closingAt ? 1 : 0, 'days')

console.log(result2) // bad results
  

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

最佳答案

我猜想“ cashRegister”是寄存器工作的时间,无论打开大于关闭,它都要经过午夜。

如果您在任何特定时间访问该寄存器,我想您要么希望当前的工作周期,要么是最近的工作周期。将打开和关闭时间存储为分钟,这样对于人类来说就很难计算出来,但是我想可以简化编码。

您的代码似乎过于复杂,因此我将发布替代方法。对于任何日期,以下内容都会返回其所在的会话或最近完成的会话。因此,如果它刚好在会话开始之前,它将返回上一个会话。



var sessions = {Monday    :{open: 1260, close: 510},
                Tuesday   :{open: 1140, close: 420},
                Wednesday :{open: 1260, close: 510},
                Thursday  :{open: 1260, close: 510},
                Friday    :{open: 1260, close: 510},
                Saturday  :{open: 1260, close: 510},
                Sunday    :{open: 1260, close: 510}};

function getDayName(date) {
  return 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' ')[date.getDay()];
}

function getSessionByDate(sessions, date) {

  // Get the day name
  var day = getDayName(date);

  // Create dates for start and end, adjust later
  var start = new Date(+date);
  var end; // set later when start worked out

  // Get the session for the current day
  var session = sessions[day];

  // If session start is after current time in minutes, then
  // session started yesterday so set start and session to yesterday
  var currentTimeInMinutes = date.getHours()*60 + date.getMinutes();

  if (currentTimeInMinutes < session['open']) {
    start.setDate(start.getDate() - 1);
    day = getDayName(start);
    session = sessions[day];
  }
  // Set start to session start
  start.setHours(0,session['open'],0,0);
  // For end, use start date and set hours to 24 and minutes to close
  end = new Date(+start);
  end.setHours(24, session['close'],0,0);

  return [start,end];
}

[new Date(2017,0,10, 2,12,53), // Wednesday 10 January at 02:12:53 (during session)
 new Date(2017,0,10, 9,12,53), // Wednesday 10 January at 09:12:53 (after session end)
 new Date(2017,0,10,23,12,53), // Wednesday 10 January at 23:12:53 (during session)
 new Date(2017,0,21,13,34,18)  // Saturday 21 January at 13:34:18 (after session end)

].forEach(function(d) {
  var session = getSessionByDate(sessions, d)
  var opts = {weekday:'short', day:'2-digit',month:'short',year:'numeric',hour:'numeric',minute:'numeric'};
  console.log('On ' + d.toLocaleString('en-GB', opts) + '\n' +
              'Session start: ' + session[0].toLocaleString('en-GB', opts) +
              '\nSession end  : ' + session[1].toLocaleString('en-GB', opts)
  );
});

08-26 17:17
查看更多