Как проверить время?

У меня есть строка со следующем содержимым: 13:02:01. И еще несколько таких строк.

Я разбил их по часам и записал в массив. То есть у меня в массиве array[20]={"1","3" ...}

Теперь нужно проверить на ночное или дневное время.

Алгоритм такой:

Если ночь (т.е с 21:00 до 5:00), то сделать что-то.

Собственно вопрос, как реализовать это условие?


Ответы (3 шт):

Автор решения: Harry

Разбивайте не по символам, а по числам, разделенными двоеточиями. И работайте...

Простейший способ в С++ — с использованием istringstream, например:

void dayNight(string ss)
{
    int h, m, s;
    char c;
    istringstream(ss) >> h >>c >> m >> c >> s;

    if (h >=21 || h <= 5) cout << "Ночь\n"; else cout << "День\n";
}

https://ideone.com/tbHrsj

А можно совсем по-простому:

bool dayNight(const char * s)
{
    int t[3] = {};
    for(int i = 0; *s && i < 3; ++s)
    {
        if (isdigit(*s)) t[i] = t[i]*10 + *s - '0';
        else if (*s != ':') return false;
        else ++i;
    }
    int ts = (t[0]*60+t[1])*60+t[2];
    if (ts >= 21*3600 || ts < 5*3600) cout << "Ночь\n"; else cout << "День\n";
    return true;
}
→ Ссылка
Автор решения: KoVadim

Есть много способов это сделать и проверить. Вот для начала старый надежный способ

std::string t = "5:00:00";
int h, m, s;
if (sscanf(t.c_str(), "%d:%d:%d", &h, &m, &s) != 3) {
    std::cout << "oops\n";
} else {
    if (h >= 21 || h <= 4 || h == 5 && m == 0 && s == 0) {
        std::cout << "Ночь\n";
    } else {
        std::cout << "День\n";
    }
}

да, я тут считаю, что 5:00 - это ещё ночь, а 5:00:01 - уже день:)

В 20 стандарт подвезли chrono/parse, но там даже примеров нет. думаю, через пару лет можно будет использовать.

Можно парсить и регулярками, но мне способ с sscanf нравится больше

std::string t = "5:00:00";
std::regex re("(\\d+):(\\d+):(\\d+)");
std::smatch mt;
if (std::regex_match(t, mt, re)) {
    int h = std::stoi(mt[1].str());
    int m = std::stoi(mt[2].str());
    int s = std::stoi(mt[3].str());

    if (h >= 21 || h <= 4 || h == 5 && m == 0 && s == 0) {
        std::cout << "Ночь\n";
    } else {
        std::cout << "День\n";
    }
} else {
    std::cout << "плохая строка, не парсится\n";
}

Если же хочется с++'ней способа, то вот он

#include <iomanip>      // std::get_time
#include <ctime>        // struct std::tm
#include <sstream>

struct std::tm when;
std::stringstream s("05:00:01");
s >> std::get_time(&when,"%H:%M:%S");

if (s.fail()) std::cout << "не могу парсить\n";
else {
    std::cout << when.tm_hour << ":" << when.tm_min << ":"  << when.tm_sec << "\n";
    if (when.tm_hour >= 21 || when.tm_hour <= 4 || when.tm_hour == 5 && when.tm_min == 0 && when.tm_sec == 0) {
        std::cout << "Ночь\n";
    } else {
        std::cout << "День\n";
    }
}
→ Ссылка
Автор решения: Иван

Все, я понял. Можно еще проще, без регулярок и парсинга. Просто разбить строку на первые два элемента. Например, если строка со временем содержится в массиве array.

  string array[8]= {"13:02:01"};
            int c;
            c = ((int)array[0] - '0') * 10;//умножение на десять, чтобы получить десятки
            int b = (int)array[1] - '0';
            c += b;

Просто преобразуем первые два элемента в инт, а потом вычитаем код символа ноль из ASCII. То есть, по таблице ASCII код символа "1" это 49, а код символа "0" это 48, 49-48 = 1. Код символа "3" это 51, 41-38 = 3. Умножаем на 10, чтобы получить десятки. Дальше, складываем c и b и получаем число 13, а дальше просто реализуем условие:

if (c > 21 || c < 6){
    //выполнить что-то
}
→ Ссылка