Посчитать разницу между датами и вывести на 7seg: ГГ/ММ/ДД

PavelLevin
Offline
Зарегистрирован: 15.12.2019

Привет, я начинающий и задумал сделать подарок на день святого Валентина = рамка которая показывает сколько лет, месяцев и дней мы вместе. Всё бы ничего, сделал, сравнил с онлайн счётчиком и понял что високосные года я прошляпил, как сделать что бы это работало точно, и так же точно через 10 лет? Может есть способ как тут подредактировать?

P.S. Плата уже едет с jlc.pcb, корпус печатается на 3d принтере. Не хочу отказываться от идеи. Буду рад любым советам.

#include <Wire.h>    //Libraries to communicate with RTC
#include "RTClib.h"

RTC_DS1307 rtc;      //create rtc object

int segs[] = {0, 1, 2, 3, 4, 5, 6, 7};//abcdefg. segments
int digits[] = {12, 13, 10, 11, 8, 9};        //number of digits
String num[]  = {"00000011", //0
                 "10011111", //1
                 "00100101", //2
                 "00001101", //3
                 "10011001", //4
                 "01001001", //5
                 "01000001", //6
                 "00011111", //7
                 "00000001", //8
                 "00001001"  //9
                };

DateTime dtBegin (2010, 6, 27, 0, 0, 0); //!!!! adjust time here!!!!!

TimeSpan Timepassed;



int Dayspassed, Yearpassed, Monthpassed, DaysTotal;

void setup()
{
  rtc.begin();//begin rtc communication
  for (int i = 0; i < 8; i++)
  {
    pinMode(segs[i], OUTPUT);//set segment pins output
  }
  for (int i = 0; i < 6; i++)
  {
    pinMode(digits[i], OUTPUT);//set digts as outputs

  }
  
}


void loop()
{


  DateTime nowTime = rtc.now();
  Timepassed = nowTime - dtBegin;
  DaysTotal = Timepassed.days();
  Yearpassed = DaysTotal / 365;
  Monthpassed = (DaysTotal - Yearpassed * 365) / 31;
  Dayspassed = DaysTotal - Monthpassed *  31 - Yearpassed * 365;
  printTime(Dayspassed, Monthpassed, Yearpassed);

}



void printNum(int number)//function to print number
{
  for (int i = 0; i < 8; i++)
  {
    //if (state == true && state1 == true) //if date is displayed show decimal after day
    //    {
    //      num[number].setCharAt(7, '1');
    //    }
    //    //if (state != true || state1 != true) //if not then no decimal
    //    {
    //      num[number].setCharAt(7, '0');
    //    }

    if (num[number].charAt(i) == '1')//set segment high
    {
      digitalWrite(segs[i], HIGH);
    }
    else
    {
      digitalWrite(segs[i], LOW);//set low
    }
  }
}
void printTime(int day, int month, int year)
{
  int d[] = {floor(day / 10), day - 10 * floor(day / 10), floor(month / 10), month - 10 * floor(month / 10), floor(year / 10), year - 10 * floor(year / 10)};

  for (int i = 0; i < 6; i++)
  {
    if (i != 0)
    {
      digitalWrite(digits[i - 1], LOW);
    }
    if (i == 0)
    {
      digitalWrite(digits[5], LOW);
    }
    if (i == 1)
    {
      //  state = true;
    }
    else
    {
      // state = false;
    }

    digitalWrite(digits[i], HIGH);
    printNum(d[i]);
    delay(5);
  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

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

Ищите в гугле.

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

Проблема только в днях?

Есть несколько путей решения. Например, вот такой.

А можно воспользоваться стандартной для C библиотекой времени (как и везде, она живёт в time.h) там можно всё что угодно, хоть фазы Луны, считать.

PavelLevin
Offline
Зарегистрирован: 15.12.2019

Добрый день,

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

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

Проблема только в днях?

Есть несколько путей решения. Например, вот такой.

А можно воспользоваться стандартной для C библиотекой времени (как и везде, она живёт в time.h) там можно всё. что угодно, хоть фазы Луны, считать.

Женя: К сожалению в стандартной библиотеке нет функции, которая посчитает разницу дат не в днях, а в годы/месяцы/дни - корректно, с учетом возможного 29 февраля в последнем кусочке.

===================================

2ТС: Я, по очевидным причинам, не стану писать код, но подскажу, как это делать:

1. Определяешь год ближайшей прошедшей годовщины - то есть если месяц/день годовщины МЕНЬШЕ месяц/день ТЕКУЩИЙ - то ЭТОТ год, иначе - ПРОШЛЫЙ; Вычисляешь разницу лет;

2. Определяешь так же месяц ближайшей даты - то есть если день годовщины МЕНЬШЕ день ТЕКУЩИЙ - то ЭТОТ месяц, иначе - ПРОШЛЫЙ; Вычисляешь разницу месяцев;

3. Определяешь разницу дней. Если месяц из п2 - ТЕКУЩИЙ, то просто разницу, если ПРОШЛЫЙ - и он февраль, то нужно проверить текущий год на наличие 29 февраля. Вычислить количество прошедших дней.

==================

Вот как-то так.

b707
Offline
Зарегистрирован: 26.05.2017

PavelLevin пишет:

Добрый день,

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

по вышеприведенной ссылке функция в две строчки - даже это сложновато?

sadman41
Offline
Зарегистрирован: 19.10.2016

Со стандартной time.h можно заколхозить: обе даты в unixtime, потом делим,умножаем, вычитаем и переводим в человеческие ддммгггг ;)