Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: При установке системного даты и времени неверно устанавливается час дня  (Прочитано 710 раз)
0 Пользователей и 1 Гость смотрят эту тему.
demon051
Постоялец

ru
Offline Offline

« : 04-04-2018 11:45 » 

Всем привет

Необходимо менять системную дату и время.
OS Debian
Вот код тестовый

Код:
#include <iostream>
#include <time.h>
#include <sys/time.h>
using namespace std;

void setTime(int day, int month, int year, int hour, int minute, int second, int mseconds, __timezone_ptr_t tz)
{
    struct tm time;
    time.tm_mday = day;
    time.tm_mon = month - 1;
    time.tm_year = year - 1900;
    time.tm_hour = hour;
    time.tm_min = minute;
    time.tm_sec = second;
    struct timeval tval;
    tval.tv_sec = mktime(&time);
    tval.tv_usec = mseconds * 1000;
    //settimeofday(&tval, NULL);
    settimeofday(&tval, tz);
}

int main(int argc, char *argv[])
{


    char* day=0; char* month=0;
    char* year=0; char* hour=0;
    char* min=0; char* sec=0;


    time_t rawtime;
    tm * timeinfo;


    time( &rawtime );                               // получить текущую дату, выраженную в секундах
    timeinfo = localtime( &rawtime );

    std::cout << "Текущее локальное время и дата (asctime) "
              << asctime(timeinfo);                 // текущая дата, представленная в нормальной форме

    cout << "argc = "<<argc<<"\n";

    if(argc>1)
        day = argv[1];

    if(argc>=2)
        month = argv[2];

    if(argc>=3)
        year = argv[3];

    if(argc>=4)
        hour = argv[4];

    if(argc>=5)
        min = argv[5];

    if(argc>=6)
        sec = argv[6];

    std::cout << "Текущее локальное время и дата (ctime) "
              << ctime (&rawtime);                 // текущая дата, представленная в нормальной форме*/


    cout<<"Устанавливаем дату и время: " << (day!=0?atoi(day):timeinfo->tm_mday) <<"/"<<(month!=0?atoi(month):timeinfo->tm_mon)<<"/"<<(year!=0?atoi(year):timeinfo->tm_year)
                                         <<" "<<(hour!=0?atoi(hour):timeinfo->tm_hour)<<":"<<(min!=0?atoi(min):timeinfo->tm_min)<<":"<<(sec!=0?atoi(sec):timeinfo->tm_sec)<<endl;
   
    timeval *tv;
    __timezone_ptr_t tz = 0;
    gettimeofday (tv, tz);



     setTime((day!=0?atoi(day):timeinfo->tm_mday), (month!=0?atoi(month):timeinfo->tm_mon), (year!=0?atoi(year):timeinfo->tm_year),
              (hour!=0?atoi(hour):timeinfo->tm_hour), (min!=0?atoi(min):timeinfo->tm_min), (sec!=0?atoi(sec):timeinfo->tm_sec), 0, tz);

     time_t rawtime2;
     tm * timeinfo2;


     time( &rawtime2 );                               // получить текущую дату, выраженную в секундах
     timeinfo2 = localtime( &rawtime2 );
     std::cout << "Новое локальное время и дата (acstime) "
               << asctime(timeinfo2) << endl;

     std::cout << "Новое локальное время и дата (ctime) "
               << ctime (&rawtime2) << endl;                 // текущая дата, представленная в нормальной форме*/

     std::cout << "Год: "  <<timeinfo2->tm_year << endl;
     std::cout << "Месяц: " <<timeinfo2->tm_mon << endl;
     std::cout << "День: " <<timeinfo2->tm_mday << endl;
     std::cout << "Часы: " <<timeinfo2->tm_hour << endl;


     return 0;
}


В итоге устанавливается всё верно кроме часа дня. Т.е. указываешь 16:30:00, а получается 15:30:00
Причем примерно раз на 10 попыток устанавливается корректно то, что указал.
Не понимаю что происходит.
Что делаю неправильно?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #1 : 04-04-2018 14:38 » 

Происходит временная зона. Необходимо правильно проинициализировать поле tm::tm_isdst (например отрицательным значением, чтобы функция сама попыталась определить действует сейчас летнее время или нет). А вообще, лучше взять себе за правило структуры передаваемые в написанные не Вами функции инициализировать целиком (ну или в начале говорить memset(), а потом устанавливать нужные поля).
Записан
demon051
Постоялец

ru
Offline Offline

« Ответ #2 : 04-04-2018 14:40 » 

Происходит временная зона. Необходимо правильно проинициализировать поле tm::tm_isdst (например отрицательным значением, чтобы функция сама попыталась определить действует сейчас летнее время или нет). А вообще, лучше взять себе за правило структуры передаваемые в написанные не Вами функции инициализировать целиком (ну или в начале говорить memset(), а потом устанавливать нужные поля).

так вроде бы я временную зону копирую из полученного локального времени и передаю в функцию установки нового времени

 timeval *tv;
    __timezone_ptr_t tz = 0;
    gettimeofday (tv, tz);

 setTime((day!=0?atoi(day):timeinfo->tm_mday), (month!=0?atoi(month):timeinfo->tm_mon), (year!=0?atoi(year):timeinfo->tm_year),
              (hour!=0?atoi(hour):timeinfo->tm_hour), (min!=0?atoi(min):timeinfo->tm_min), (sec!=0?atoi(sec):timeinfo->tm_sec), 0, tz); <-------- вот тут

и далее происходит

settimeofday(&tval, tz);
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #3 : 04-04-2018 14:44 » 

demon051, попробуйте всё-таки просто сказать time.tm_isdst = -1; Тем более в man пишут, что параметр struct timezone *tz - obsolete и там должен передаваться NULL.
« Последнее редактирование: 04-04-2018 14:47 от darkelf » Записан
demon051
Постоялец

ru
Offline Offline

« Ответ #4 : 04-04-2018 14:44 » new

demon051, попробуйте всё-таки просто сказать time.tm_isdst = -1;
ок. попробую.

Добавлено через 15 часов, 5 минут и 19 секунд:
demon051, попробуйте всё-таки просто сказать time.tm_isdst = -1; Тем более в man пишут, что параметр struct timezone *tz - obsolete и там должен передаваться NULL.

спасибо, Вы оказали правы.
« Последнее редактирование: 05-04-2018 05:49 от demon051 » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines