How to loop from one date to another

Hey, currently I'm trying to read txt files named as "YYDDMMHHmmSS". So to read txt files of two dates I need to iterate the loop so that I can make the file name. Is there any suggestion or a way to do it?

Give an example of two or three dates so we can understand what you are trying to do.

Are you trying to create a string so that you can use it as the name of a file?

If you have something like this

char myDate[] = "YYDDMMHHmmSS";

you can easily replace any of the characters with, for example

myDate[0] = '1';
myDate[1] = '6';
// etc

If you use the YYMMDD format the files will sort in chronological order. And you should really use YYYY so there won't be a problem at the millenium.

...R

EX : 16100912 or the next day 1610100912
I had to use 16 instead of 2016 since there is a character limit for the file name.

I’m saving the files in an SD for every hour, And I have red and see but files don’t save in chronological order. So because of that I have got the number of files and iterate that much of times.So inside that loop I want to create my file name as 16100912 and then 16110913 and then 16100914

I have made the file name according to the same you said. By inserting the date in to a Char array. Now my problem is to read them. For example I have to add 1 hour to every iteration, and then I have to increase the day by 1 in every 24hours. And the month might have 30 day, 31 days or 28 days. Hope you understood what I’m trying to explain. :slight_smile:

I have made the file name according to the same you said. By inserting the date in to a Char array. Now my problem is to read them. For example I have to add 1 hour to every iteration, and then I have to increase the day by 1 in every 24hours. And the month might have 30 day, 31 days or 28 days.

Would it help you used an RTC to derive the date as a filename? It is common practice and would nicely take care of all those funny months. If you need to make a new file every hour, then YYMMDDHH.csv sounds like a fair place to start, and I really can't see why you need to name such a file with mmss as well. I also think it is probably OK to use YY. The next millenium is 984 years away, and I'm sure we will all have lost interest by then.

SasankaKudagoda:
I have made the file name according to the same you said. By inserting the date in to a Char array. Now my problem is to read them. For example I have to add 1 hour to every iteration, and then I have to increase the day by 1 in every 24hours. And the month might have 30 day, 31 days or 28 days. Hope you understood what I'm trying to explain. :slight_smile:

As you seem to be in charge of the whole system I think it would be much simpler just to create a filename that is an integer number of hours from some start point - perhaps counting from midnight between 31Dec15 and 01Jan16. Then each file name is just +1.

It will be easy to parse those numbers back into actual dates if you need to.

If you really do want to keep the YYDDMM format then I think there is no substitute for a table (an array) that holds the number of days in each month.

Or you could store the hour number that represents the first hour of each month if you use my suggestion.

...R

Robin2:
As you seem to be in charge of the whole system I think it would be much simpler just to create a filename that is an integer number of hours from some start point - perhaps counting from midnight between 31Dec15 and 01Jan16. Then each file name is just +1.

Maybe she wants them to be human-readable. Few humans are that good at mental arithmetic. Or maybe the files already exist, and she just wants to read them in, in which case changing the file format is probably more trouble than it is worth.

A day is 24 hours (right now, I'm pretending Daylight Saving Time doesn't exist). The hours in a day are numbered, in order, from 0 to 23. So the hour is easy.

The days in a month are always numbered starting from 1, but finding the number of the last day is a little tricky. I'll get to that later.

The months in a year are numbered in order, from 1 to 12. That is easy.

The years are numbered in order. That is easy, at least until the year 2100, which is probably too far in the future for you to really care about.

As I mentioned, finding the number of the last day in a month is a little tricky. Here is a function I wrote for doing that:

// essential helper function for advancing time
int days_in_month (int y, int m) {
  // Fourth, eleventh, ninth, and sixth,
  // thirty days to each we fix. 
  if ((m==4)||(m==11)||(m==9)||(m==6)) return 30; 
  // Every other, thirty-one,
  // except the second month alone,
  if (m!=2) return 31;
  // which hath twenty-eight, in fine,
  // till leap-year give it twenty-nine.
  // if ((y%400)==0) return 29; // leap year
  // if ((y%100)==0) return 28; // not a leap year
  if ((y%4)==0)   return 29; // leap year
  return 28; // not a leap year 
}

What does your code look like now? If we know where you are starting from, it will be much easier to find a solution.

Robin2:
As you seem to be in charge of the whole system I think it would be much simpler just to create a filename that is an integer number of hours from some start point - perhaps counting from midnight between 31Dec15 and 01Jan16. Then each file name is just +1.

It will be easy to parse those numbers back into actual dates if you need to.

If you really do want to keep the YYDDMM format then I think there is no substitute for a table (an array) that holds the number of days in each month.

Or you could store the hour number that represents the first hour of each month if you use my suggestion.

...R

Hey, I understand what you are saying but suppose I want to search for a specific day, for an example 27th March 2016. Then I have to go through all the files from top. So to avoid that I have used the above mentioned format.

odometer:
As I mentioned, finding the number of the last day in a month is a little tricky. Here is a function I wrote for doing that:

// essential helper function for advancing time

int days_in_month (int y, int m) {
 // Fourth, eleventh, ninth, and sixth,
 // thirty days to each we fix.
 if ((m==4)||(m==11)||(m==9)||(m==6)) return 30;
 // Every other, thirty-one,
 // except the second month alone,
 if (m!=2) return 31;
 // which hath twenty-eight, in fine,
 // till leap-year give it twenty-nine.
 // if ((y%400)==0) return 29; // leap year
 // if ((y%100)==0) return 28; // not a leap year
 if ((y%4)==0)   return 29; // leap year
 return 28; // not a leap year
}





Hey, I have done the same above code since I wanted to find the number of files from one day to another. Now my problem is how to Iterate. In the iteration how to create my file name. For example after 31st Jan 23 I have to make the month = 2 and date = 1, but if the month is 28 I have to terminate the loop from 28th and then Make the month = 3 and date = 1

Right now my code looks like this


tFileName = (String)charBuf[8] + charBuf[9] + charBuf[3] + charBuf[4] + charBuf[0] + charBuf[1] + charBuf[11] + charBuf[12] + “.dat”; //YYMMDDHH.dat

for (int i = 0; i < noOfFiles; i++ ) {
      reqHour += 1;
      tFileName = (String)charBuf[0] + charBuf[1] + charBuf[3] + charBuf[4] + charBuf[8] + charBuf[9] + reqHour + “.dat”; //YYMMDDHH.dat

myFile = SD.open(tFileName);
      if (myFile) {
        while (myFile.available()) {
          struct DataLog dataLog;
          myFile.read((uint8_t *)&dataLog, sizeof(dataLog));
          Serial.print(dataLog.timeStamp); Serial.print(" “);
          Serial.print(dataLog.s1); Serial.print(” “);
          Serial.print(dataLog.s2); Serial.print(” “);
          Serial.print(dataLog.s3); Serial.print(” “);
          Serial.print(dataLog.s4); Serial.print(” “);
          Serial.print(dataLog.s5); Serial.print(” “);
          Serial.print(dataLog.s6); Serial.print(” “);
          Serial.print(dataLog.s7); Serial.print(” “);
          Serial.print(dataLog.angle); Serial.print(” ");
          Serial.print(dataLog.errorType); Serial.println();
        }
        myFile.close();
      }

// essential helper function for advancing time
int days_in_month (int y, int m) {
// Fourth, eleventh, ninth, and sixth,
// thirty days to each we fix.
if ((m==4)||(m==11)||(m==9)||(m==6)) return 30;
// Every other, thirty-one,
// except the second month alone,
if (m!=2) return 31;
// which hath twenty-eight, in fine,
// till leap-year give it twenty-nine.
// if ((y%400)==0) return 29; // leap year
// if ((y%100)==0) return 28; // not a leap year
if ((y%4)==0) return 29; // leap year
return 28; // not a leap year
}

After reading all this, I can't believe you wouldn't spend $2-50 and have a clock do it all for you - with about three lines of code.......

Even if you weren't messing about with all this, you might find you need a clock anyway to timestamp the data.

SasankaKudagoda:
Hey, I understand what you are saying but suppose I want to search for a specific day, for an example 27th March 2016. Then I have to go through all the files from top.

No you don’t. You just need code to generate the file number (the hour number) that is appropriate for that date and then get that file.

Maybe a more pertinent question is why are you creating a new file every hour? Why not just add data to an existing file and have one file per month or per week or per day?

…R

Robin2:
Maybe a more pertinent question is why are you creating a new file every hour? Why not just add data to an existing file and have one file per month or per week or per day?

Q -> Can you help me with directions to Geneva?
A -> Why would you want to go there, go to Paris instead.

SasankaKudagoda:
Hey, I understand what you are saying but suppose I want to search for a specific day, for an example 27th March 2016. Then I have to go through all the files from top. So to avoid that I have used the above mentioned format.

I'm not quite clear if you need to programmatically access them versus human readable. Have you thought about using a UNIX timestamp (uint32_t) for the file name? It occurs to me that you have space for that and they would then be searchable in order.

Making the file name from a given date-time then becomes quite trivial... and comparing even more so.

SasankaKudagoda:

tFileName = (String)charBuf[8] + charBuf[9] + charBuf[3] + charBuf[4] + charBuf[0] + charBuf[1] + charBuf[11] + charBuf[12] + ".dat"; //YYMMDDHH.dat
  1. Why are you using a capital-S String?
  2. As for charBuf[8], charBuf[9], etc.: what exactly does this charBuf array (or is it a String object?) contain?
for (int i = 0; i < noOfFiles; i++ ) {
  1. What datatype is noOfFiles? How is it calculated? Are you sure there will never be more than 32767 files? At one file per hour, you will run out of space within four years.

You have not posted your entire sketch. Please help us to help you by posting your entire sketch and not just the part you think is relevant.

Robin2:
No you don't. You just need code to generate the file number (the hour number) that is appropriate for that date and then get that file.

BulldogLowell:
I'm not quite clear if you need to programmatically access them versus human readable. Have you thought about using a UNIX timestamp (uint32_t) for the file name? It occurs to me that you have space for that and they would then be searchable in order.

Making the file name from a given date-time then becomes quite trivial... and comparing even more so.

I could be mistaken, but I believe that the OP wants to be able to find the file she wants without having to reach for a calculator. (Please see reply #6.)

odometer:
I could be mistaken, but I believe that the OP wants to be able to find the file she wants without having to reach for a calculator. (Please see reply #6.)

Isn't the Arduino a calculator?

IMHO a huge part of using a computer is to translate between stuff that is convenient for humans and stuff that is convenient for a program.

...R

The easiest way is probably to make use of the time library; all the hard work is done for you.

#include <Time.h>

tmElements_t theTime;
char txBuffer[64];

void setup()
{
  Serial.begin(115200);

  // set an initial date and time
  theTime.Second = 0;
  theTime.Minute = 0;
  theTime.Hour = 0;
  theTime.Day = 28;
  theTime.Month = 2;
  theTime.Year = 2016 - 1970;

  // create a unix time stamp from the given tm
  time_t t = makeTime(theTime);

  // print
  sprintf(txBuffer, "%04d/%02d/%02d %02d:%02d:%02d", theTime.Year + 1970, theTime.Month, theTime.Day, theTime.Hour, theTime.Minute, theTime.Second);
  Serial.println(txBuffer);

  // add a day
  t += 86400; // or t += SECS_PER_DAY;

  // convert unix timestamp to tm struct
  breakTime(t, theTime);

  // print
  sprintf(txBuffer, "%04d/%02d/%02d %02d:%02d:%02d", theTime.Year + 1970, theTime.Month, theTime.Day, theTime.Hour, theTime.Minute, theTime.Second);
  Serial.println(txBuffer);
}

void loop()
{

}

Modify to your needs :wink: