Herausfinden, ob Zahl im Bereich von-bis liegt (Uhrzeit)

Hi Leute,

könnt ihr mir in der folgenden Sache weiterhelfen (ich komme nicht auf die Lösung).

Angenommen, ich habe diese drei Werte:

int stunde=5; // wird per NTP ermittelt
int nacht_start=23;
int nacht_ende=4;

Nun möchte ich, dass geprüft wird, ob sich die aktuelle Stunde (z.B. 5 Uhr) im Bereich zwischen 23 Uhr und 4 Uhr befindet.

Da es hier ja bei der Uhrzeit einen Sprung von 23 auf 0 gibt kann ich ja nicht einfach sagen

if ((stunde >=nacht_start) && (stunde<= nacht_ende))

Wie macht man denn sowas am "smartesten" und performance-mäßig am besten?
Das geht doch bestimmt auch ohne eine Time-Library?

Ich bin dankbar für jeden Tipp und denke auch gerne weiter, wenn ihr mir einen Gedankenanstoß liefert.

Kann auch sein, dass ich grad viel u kompliziert denke oder auf dem Schlauch stehe ;-(

LG Daniel

const byte nachtStart = 20;
const byte nachtEnde = 5;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b=0; b<23; b++)
  {
    Serial.print(b);
    if (b>=nachtStart || b<nachtEnde)
    Serial.println(F(" Es ist Nacht!"));
    else
    Serial.println(F(" Es ist Tag!"));
    
  }
}

void loop()
{


}
1 Like

Hey, Saucool, Danke.

Warum komm ich da nur nicht selber drauf ;-(
Du musst diese Frage nicht beantworten :wink:

LG Daniel

1 Like

Ich hab für sowas mir ne Funktion geschrieben....
Die bekommt die Zeit übergeben und gibt einen Bool zurück.
Im Übrigen hab ich grad gesehen, das ich oben nur bis 22 zaehle - ich bin also auch nicht perfekt :wink:

Habs gesehen, hab ein b<=23 draus gemacht.
Danke. Perfekt ist ja Gottseidank niemand - außer Chuck Norris!

Wenn es nicht nur um Stunden geht, sondern auch um Minuten / Sekunden ist es besser die Zeit in Minuten bzw Sekunden umzurechnen und den Vergleich dann mit Minuten / Sekunden zu machen Dadurch erspart man sich aufwendige Verschachtelung der Abfrage mit Stunden Minuten und etwaig Sekunden.
Noch notwendiger wird das wenn man Zeiten summiert. Startzeit x stopzeit nach y Minuten.

Grüße Uwe

1 Like

in meinem Fall gehts tatsächlich nur um die Stunde, von daher ist die Antwort von @my_xy_projekt perfekt :wink: Danke nochmal dafür.

@my_xy_projekt

Sorry ;-( Hab leider doch noch ein Problem gefunden.
Wenn man die Grenzen so setzt:

const byte nachtStart = 0;
const byte nachtEnde = 4;

Ist es immer Nacht.

Hast du hier noch die Lösung, ich hoffe mal ich stehe nicht schon wieder auf dem Schlauch.

Habs:

const byte nachtStart = 0;
const byte nachtEnde = 4;

void setup()
{
  Serial.begin(115200);
  delay(2000);
  Serial.println(F("Start..."));
  for (byte b=0; b<23; b++)
  {
    Serial.print(b);
    if (nachtStart>nachtEnde) {
      if (b>=nachtStart || b<nachtEnde)
      Serial.println(F(" Es ist Nacht!"));
      else
      Serial.println(F(" Es ist Tag!"));
    } else {
      if ((b >=nachtStart) && (b<= nachtEnde))
      Serial.println(F(" Es ist Nacht!"));
      else
      Serial.println(F(" Es ist Tag!"));
    }
    
  }
}

void loop()
{


}

Ich auch :slight_smile:

const byte nachtStart = 20;
const byte nachtEnde = 5;
bool nacht = false;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < 24; b++)
  {
    nacht = false;
    Serial.print(b);
    if (nachtStart < nachtEnde)
    {
      if (b < nachtEnde) nacht = true;
    }
    else   if (b >= nachtStart || b < nachtEnde)
      nacht = true;
    Serial.println(F(" Es ist "));
    if (nacht) Serial.println(F("Nacht!"));
    else
      Serial.println(F("Tag!"));
  }
}

void loop()
{
}

:laughing:

OK, deine Lösung ist definitiv smarter :wink:

Jetzt ja.

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < 24; b++)
  {
    nacht = false;
    Serial.print(b);
    if (b < nachtEnde) nacht=true;
    if ((nachtStart > nachtEnde) && (b>=nachtStart))nacht = true;
    
    Serial.print(F(" Es ist "));
    if (nacht) Serial.println(F("Nacht!"));
    else Serial.println(F("Tag!"));
  }
}
1 Like

Ihr habt jetzt für den Nacht-Anfang vor und nach Mitternacht abgefangen. Das Nacht-Ende muss immer nach Mitternacht sein.
Wenn es nun nicht um "Nacht" sondern um beliebige Tages-Abschnitte ginge, wäre das immer noch nicht "perfekt". (Wenn man daraus eine allgemeingültige Funktion bauen will)

Neuer Zweizeiler:

    if (((nachtStart > nachtEnde) || (nachtStart > nachtEnde && nachtEnde == 0)) && (b >= nachtStart || b<nachtEnde))nacht = true;
    if ((nachtStart < nachtEnde) && (b >= nachtStart && b<nachtEnde)) nacht = true;

Nachtrag: Sauberer zu erkennen als Dreizeiler:

    if ((nachtStart > nachtEnde) || (nachtStart > nachtEnde && nachtEnde == 0))
    {
      if  (b >= nachtStart || b < nachtEnde)nacht = true;
    }
    else if (b >= nachtStart && b < nachtEnde) nacht = true;

@michael_x ich hab mich mal auf Basis von einem gestrigen Thread an was irres rangewagt und nen Einzeiler draus gemacht.

  Serial.println(F("Start..."));
  for (byte b = 0; b < 24; b++)
  {
    Serial.print(b);
    nacht = (((nachtStart > nachtEnde || nachtEnde == 0) && (b >= nachtStart || b < nachtEnde)) || (b >= nachtStart && b < nachtEnde)) ? true:false;
    Serial.print(F(" Es ist "));
    if (nacht) Serial.println(F("Nacht!"));
    else Serial.println(F("Tag!"));
  }

Der ist sicher interessant :slight_smile:
Das müsste jetzt auf alle Zeiten passen....

... kannst du ersatzlos weglassen, aber
Serial.println( nacht? F("Nacht!") : F("Tag!") );
wäre hübsch.

Wenn die Zeile lang genug ist, passt übrigens alles in eine Zeile. Das ist kein Qualitätskriterium :slight_smile:

1 Like

Wieder was gelernt.
DANKE!

@basementmedia dann isses jetzt als kleines Schnipsle:

  for (byte b = 0; b < 24; b++)
  {
    Serial.print(b);
    Serial.print(F(" Es ist "));
    nacht = (((nachtStart > nachtEnde || nachtEnde == 0) && (b >= nachtStart || b < nachtEnde)) ||  // bedingung 1
             (b >= nachtStart && b < nachtEnde));                                                   // bedingung 2
    Serial.println( nacht ? F("Nacht!") : F("Tag!"));
  }

Es hat Spass gemacht.

1 Like

Nur zum Spaß: wenn man die Dauer der Nacht anstatt des Endes benutzt kann man das auch so rechnen:

constexpr unsigned nachtStart = 19;
constexpr unsigned nachtEnde  = 1;
constexpr unsigned nachtDauer = ((nachtEnde+24)-nachtStart) % 24;  // falls man das nicht selbst rechnen will...

bool nacht(unsigned h)
{
    return (h - nachtStart + 24) % 24 <= nachtDauer;
}

void setup()
{
    while (!Serial) {}
    Serial.printf("Start: %02d:00 \nEnde:  %02d:00 \nDauer: %dh\n\n", nachtStart, nachtEnde, nachtDauer);

    for (unsigned h = 0; h < 24; h++)
    {
        Serial.printf("%02d:00 ist %s\n",h,  nacht(h) ? "nacht" : "tag");
    }
}

Ergibt:

Start: 19:00 
Ende:  01:00 
Dauer: 6h

00:00 ist nacht
01:00 ist nacht
02:00 ist tag
03:00 ist tag
04:00 ist tag
05:00 ist tag
06:00 ist tag
07:00 ist tag
08:00 ist tag
09:00 ist tag
10:00 ist tag
11:00 ist tag
12:00 ist tag
13:00 ist tag
14:00 ist tag
15:00 ist tag
16:00 ist tag
17:00 ist tag
18:00 ist tag
19:00 ist nacht
20:00 ist nacht
21:00 ist nacht
22:00 ist nacht
23:00 ist nacht

compiliert in der IDE nicht.
Serial.printf() gibt es nicht und damit geht auch die Platzhaltergeschichte nicht ;(

Geht doch nur um die Rechnung. Nicht um das printf oder hab ich das falsch verstanden?