c++qtdatetime

How can you determine whether a point in time is within a time period?


Sorry about my bad english. Iam programming a game with a fantasy date. Every month has exactly 30 days for example. Does not matter. Every day has 24 hours like in our world, every hour 60 minutes and every minute 60 seconds.

So. I want to determine if a shop has open or not. The values in the database looks like this: open from 8 to 18 (e.g. daytime), open from 20 to 2 (e.g. in the night), open from ... ... The day is not the problem, but the early morning hours are because they are the next day.

AventurienDate from, to;

int HourFrom = 18;  // shop open from
int HourTo = 8; // shop open to
bool hasopen = false;

AventurienDate now;
now.set(1025, 4, 26, 1);    // Year, month, day, hour

from.set(1025, 4, now.Day, HourFrom);
to.set(1025, 4, now.Day, HourTo);

if(from < to || from == to)
   hasopen = (from < now || from == now) && (to > now || to == now);
else {
   to.addHours(24);
   if(now.Hours >= HourFrom && now.Hours <= HourTo)
      hasopen = true;
   if(hasopen == false)
      hasopen = (from < now || from == now) && (to > now || to == now);
}
qDebug() << "now:       " << now.toStringDateTime();
qDebug() << "open from: " << from.toStringDateTime();
qDebug() << "open to:   " <<to.toStringDateTime();
qDebug() << hasopen;
        now:        "26. TRA 1025 BF, 01:00:00"
    open from:  "26. TRA 1025 BF, 18:00:00"
        open to:    "27. TRA 1025 BF, 08:00:00"
        false
        

The output in the example should read "true"! I can't figure out the solution. Does anyone?


Solution

  • The daytime case, ignoring dates and only looking at times, is trivial (from <= now <= to). In C++, this is done with a AND boolean operation, i.e. from <= now && now <= to

    The nighttime case is the same but uses an OR instead of AND.
    The reason for OR appearing here is because:

    1. It in fact consists in 2 cases, each of which are built on the same pattern as above:
      from <= now <= midnight (24:00)
      midnight (00:00) <= now <= from.
    2. now <= midnight (24:00) and midnight (00:00) <= now are always true and can be simplified out.

    This results in the complete boolean expression:

    bool hasOpen = (from <= to /* daytime */ && (from <= now && now <= to)) 
                || (from >  to /*nighttime*/ && (from <= now || now <= to));