часовые пояса из модуля часов DS3231

sanja404
Offline
Зарегистрирован: 03.10.2014

господа и дамы, всем доброго времени суток!

задался идеей поочередно выводить  на дисплей время разных часовых поясов.

я не силен в программировании на с++ и поэтому первое что пришло в голову это поочередно записывать разные значения часового регистра непосредственно в модуль DS 3231. это решит проблему, но удобно ли это?

второе что пришло в голову модуль часов не трогать, и обрабатывать это програмно. 

но, если при t = rtc.getTime()   и hour1 = t.hour, DEC; (использую библиотеку <DS3231.h>) сделать и выводить hour1 = hour1 + 8; или hour1 = hour1 - 8;  -   время будет выводится не  корректно. 

на этом мои познания в программировании были исчерпаны. а нужно  совсем немного, обработать hour1, но я не силен в программировании на с++ и как это зделать я не знаю

буду рад вашим подсказкам 

с уважением, sanja404

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sanja404 пишет:

я не силен в программировании на с++

В программировании на чём Вы сильны?

sanja404 пишет:

hour1 = hour1 + 8; или hour1 = hour1 - 8;  -   время будет выводится не  корректно. 

Ну, так берите остаток от деления на 24 и всё будет корректно. Например, 21 + 8, если взять остаток, получится 5 - вполне себе корректно.

При чём тут С++? Вы в арифметике-то сильны?

 

sanja404
Offline
Зарегистрирован: 03.10.2014

ЕвгенийП пишет:

Ну, так берите остаток от деления на 24 и

будет ли корректно выглядеть так? 


hour1 = t.hour, DEC;
  if (hour1 < 24) { 
    hour2 = (hour1 + 8);
  }
  else {
    hour2 = (hour1 + 8 - 24);
  }
  if (hour1 < 24) { 
    hour3 = (hour1 - 8);
  }
  else {
    hour3 = (hour1 - 8 - 24);
  }

... получилось без деления

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, конечно, нет. Вы сами-то смотрите. Ну, допустим, что hour1 в первой строке получился 23. Тогда hour2 получается 31. Это то, чего Вы хотели?

sanja404
Offline
Зарегистрирован: 03.10.2014

ЕвгенийП пишет:

Ну, допустим, что hour1 в первой строке получился 23. Тогда hour2 получается 31. 

int tokio = -6;
int newyrk = 8;

void setup() {..}

void loop() (

hour1 = t.hour, DEC;
  
  int hour22 = (hour1 + newyrk);
  if (hour22 < 24) { 
    hour2 = (hour1 + newyrk);
  }
  else {
    hour2 = (hour1 + newyrk - 24);
  }
  int hour33 = (hour1 + tokio);
  if (hour33 < 24) { 
    hour3 = (hour1 + tokio);
  }
  else {
    hour3 = (hour1 + tokio - 24);
  }

...

}

спасибо за помощь

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, а теперь что? Что это Вы такое написали?

Ну, допустим стало 2 часа ночи (кстати, что за бред в строке 8? Он и раньше был, просто я внимания не обращал) и каким при этом у Вас получится hour3? По-моему будет -4.

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

По-моему наименее замороченный способ, позволяющий избежать часовой арифметики (а ведь придется учитывать не только переход секунд-минут-часов через ноль, но и корректировать дни, месяца и високосные годы) - при считывании с RTC преобразовывать время в timestamp. При использовании (отображении) преобразовывать обратно в структуру, предварительно добавив нужное смещение часового пояса. За работу со временем отвечают функции из <time.h>: mk_gmtime(), gmtime_r() и структура tm. Однако есть еще множество подводных камней, таких как, например несоответствие значений номера месяца - DS возвращает 1..12, а mk_gmtime оперирует с 0..11. 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Дерзайте :)))

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Так мне-то чего дерзать - у меня с часовыми поясами всё OK, а вот топикстартер ввязался в крайне веселую историю.

Кстати, ни DS, ни какая-либо из библиотек для Arduino не учитывает переходы на летнее и зимнее время. 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

можно создать по екземпляру класса библиотеки для каждого пояса, если не желается считать.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Клапауций 112 пишет:
можно создать по екземпляру класса библиотеки для каждого пояса, если не желается считать.

Экая изощренная диверсия ;)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sadman41 пишет:

Кстати, ни DS, ни какая-либо из библиотек для Arduino не учитывает переходы на летнее и зимнее время. 

Вообще-то это не ее функции.

От таблицы умножения же Вы не требуете перехода на зимнее либо летнее время.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

С чего вы взяли, что я требую от нее что-то? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Так мне-то чего дерзать - у меня с часовыми поясами всё OK, а вот топикстартер ввязался в крайне веселую историю.

Простите, я по ошибке думал, что это ТС

sadman41 пишет:

Кстати, ни DS, ни какая-либо из библиотек для Arduino не учитывает переходы на летнее и зимнее время. 

Не знаю, что Вы понимаете по "библиотеками для Ардуино", но с некоторой версии (в 1.8.1 точно есть) идёт старая добрая time.h, а там и не такое есть - например вычисление времени астрономических событий по географическим координатам.

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Не знаю, что Вы понимаете по "библиотеками для Ардуино", но с некоторой версии (в 1.8.1 точно есть) идёт старая добрая time.h, а там и не такое есть - например вычисление времени астрономических событий по географическим координатам.

Так вот что надо использовать в солнечном трекере!!!

sadman41
Онлайн
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:
Не знаю, что Вы понимаете по "библиотеками для Ардуино", но с некоторой версии (в 1.8.1 точно есть) идёт старая добрая time.h, а там и не такое есть - например вычисление времени астрономических событий по географическим координатам.

Под библиотеками для Arduino я подразумеваю как ту, на которую сослался ТС, так и те, что устанавливаются через Arduino IDE. Я вполне с вами согласен, что time.h - старая и добрая, однако, насколько я читал, в avr-lib она реализована не в полном объеме. Так же, для части астрономических вычислений, требуется установка longtitude/latitude, а не простая передача datetime, взятого с RTC.

К тому же математически неописуемы постановления правительства, которыми как раз и устанавливается момент и величина смещения локального времени относительно UTC (DST rules), который только и имеет смысл хранить в RTC. Интеграцию же tzdata (и ее своевременную актуализацию) в какой-нибудь Atmega328 сложно представить, а о реализации этого чудесного плана остается только мечтать.

И это не спор с вами, а информация для ТС.

sanja404
Offline
Зарегистрирован: 03.10.2014

sadman41 пишет:

И это не спор с вами, а информация для ТС.

ТС начал изучать  time.h

спасибо за помощь

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sanja404 пишет:

ТС начал изучать  time.h

спасибо за помощь

Имейте в виду, в AVR'овской есть отличия от стандартной. См. вот здесь.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вот правильный лопух в комплект к нечестным костылям Ардуино: http://www.nongnu.org/avr-libc/user-manual/group__avr__time.html

К слову - DS3231 тоже использует базу Y2K, но напрямую в struct tm не переносится. Нужно будет корректировать месяц (-1) и год (-1900) для того, чтобы правильно работали функции <time.h>

Подскажу еще одну жирную, но простую функцию для быстрого формирования в char[] строки с временем-датой - strftime().

han2001
Offline
Зарегистрирован: 09.01.2015

Искал в Инете подобное решение задачи ТС и наткнулся на эту ветку. Понимаю, что ветка очень старая, но может кто то будет искать подобное и кому понадобиться математическое решение задачи ТС, а не через функции. В его случае код выглядел бы так

   h_temp=h1+t_offset;
   if ( h_temp < 24 ) hour=h1+t_offset;
   if (h_temp==24) hour=0;
   if (h_temp>24) hour=h1+t_offset-24;

 Где:

h_temp - временное значение времени :-) с учетом смещения  t_offset, где значение могут принимать и 25 и 26 и 27 часов, т.е. данная переменная чисто для проверки условия. 

h1 - исходный счетчик часов;

t_offset  - некое временное смещение в зависимости от часового пояса;

hour - результирующее правильное время с учетом часового пояса.