Result is negative number but must be positive

Hi Group,

I a writing a routine to calculate the Day Of Year number from the DATE .
But running the code it produces some unexpl. output. Here's the code

``````#include "Arduino.h"
#include <Streaming.h>  /* http://arduiniana.org/libraries/streaming/ */

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // opens serial port, sets data rate to 115200 bps
Serial.println(__DATE__);
Serial << "0-DOY : " << DayOfYear(__DATE__) << endl;
}

void loop() {
// put your main code here, to run repeatedly:
}

int DayOfYear(char const *date) {
char *strMonth = "TEST";
int month, day, year;
int doy = 0;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
sscanf(date, "%s %d %d", strMonth, &day, &year);
Serial << "1-Complete date: " << date << endl;
Serial << "2-This month: " << strMonth << endl;
Serial << "3-This day: " << day << endl;
Serial << "4-This year: " << year << endl;

month = (strstr(month_names, strMonth)-month_names)/3+1;
Serial << "5-Days until month: " << month << endl;
doy += month;
doy += day;
Serial << "6-Day Of Year " << doy << endl;
return doy;
}
``````

It several debug results that produces the result:

``````Mar 20 2021
0-DOY : 1-Complete date: Mar 20 2021
2-This month: Mar
3-This day: 20
4-This year: 2021
5-Days until month: -90
6-Day Of Year -70
-70
``````

0-doy (return value for today's number (70),should be the same as 6-Day Of Year but its not.
Did I missed something??

Harry

following worked on laptop after defining strMonth as a variable instead of a string

``````#include <iostream>
#include <string.h>

int DayOfYear(char const *date) {
char strMonth [10];
int month, day, year;
int doy = 0;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";

sscanf(date, "%s %d %d", strMonth, &day, &year);

std::cout << "1-Complete date: " << date << std::endl;

std::cout << "2-This month: " << strMonth << std::endl;
std::cout << "3-This day: " << day << std::endl;
std::cout << "4-This year: " << year << std::endl;
month = (strstr(month_names, strMonth)-month_names)/3+1;
std::cout << "5-Days until month: " << month << std::endl;
doy += month;
doy += day;
std::cout << "6-Day Of Year " << doy << std::endl;
return doy;
}

int
main ()
{
std::cout << __DATE__ << std::endl;

DayOfYear (__DATE__);
}
``````

Compiles here with many errors. Is this correct Arduino code??

the code i posted i ran on my laptop using gcc

This line is not legal in C++. It declares and initializes a pointer, but does not reserve memory for storing new data. In Arduino IDE preferences, turn on "show verbose" for compilation.

``````  char *strMonth = "TEST";
``````
``````char* strMonth = "TEST";
char strMonth[] = "TEST";
``````

Yes, once you fix that, your pointer manipulation will return a month number

``````month = (strstr(month_names, strMonth)-month_names)/3+1;
``````

Then you are going to need to use that number as an index to pick up the cumulative days in the months preceding.

This will get you a little closer. You're still missing Leap Year calculations.

``````int DayOfYear(char const *date)
{
char strMonth[10];
int month, day, year;
int daysBeforeMonth;
int doy = 0;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
static const int DTM[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 305, 335, 366};
sscanf(date, "%s %d %d", strMonth, &day, &year);
Serial.print("1-Complete date: ");
Serial.print(date);
Serial.print('\n');
Serial.print("2-This month: ");
Serial.print(strMonth);
Serial.print('\n');
Serial.print("3-This day: ");
Serial.print(day);
Serial.print('\n');
Serial.print("4-This year: ");
Serial.print(year);
Serial.print('\n');

month = (strstr(month_names, strMonth) - month_names) / 3 + 1;
Serial.print("5A-Month number: ");
Serial.print(month);
Serial.print('\n');

daysBeforeMonth = DTM[month-1];
////// If month is greater than 2 (Feb), add 1 if Leap Year

Serial.print("5B-Days before month: ");
Serial.print(daysBeforeMonth);
Serial.print('\n');

doy = daysBeforeMonth + day;
Serial.print("6-Day Of Year ");
Serial.print(doy);
Serial.print('\n');
return doy;
}
``````

Thanx, that worked. Added some lines to check the leapyear and here is the complete code

``````#include <Streaming.h>  /* http://arduiniana.org/libraries/streaming/ */

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // opens serial port, sets data rate to 115200 bps
Serial << "Today's date " << (__DATE__) << endl;
Serial << "Today's doy " << DayOfYear(__DATE__) << endl;
}

int DayOfYear(char const *date) {
//  char const *date = __DATE__;
char strMonth[]= " ";
int month, day, year;
int DayOfYear = 0;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Check if it is a leap year, this is confusing business
// See: https://support.microsoft.com/en-us/kb/214019
if (year % 4  == 0) {
if (year % 100 != 0) {
daysInMonth[1] = 29;
}
else {
if (year % 400 == 0) {
// The arrray at [0] so February would be in [1]
daysInMonth[1] = 29;
}
}
}
sscanf(date, "%s %d %d", strMonth, &day, &year);
month = (strstr(month_names, strMonth) - month_names) / 3 + 1;

for (int i = 0; i < month - 1; i++) {
DayOfYear += daysInMonth[i];
}
DayOfYear += day;

return DayOfYear;
}

void loop() {
// put your main code here, to run repeatedly:

}
``````

I wil make a litle change for myself as I on;y use the DOY functio, going to call the sub with no arguments eg.

``````int DayOfYear(char const *date) {
``````

becomes

``````int DayOfYear() {
char const *date = __DATE__;
``````

Again thanx for all the response

Harry

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.