getting the time as a string with correct minutes when less than 10

In this example of how to send the time to the Blynk app it has this line:

  String currentTime = String(hour()) + ":" + minute() + ":" + second();

I don't need the seconds, so we'll skip them. But the minute -- if it's less than 10 shows up wrong. 12:05 PM would show up as 12:5 PM

When I'm printing this to an LCD or something, I'd just throw in an example conditional Serial.print like this:

if (theMinute > 10) Serial.print("0");

but that won't work here as I need the whole time stamp as a string to pass to the blink app in the line:

  Blynk.virtualWrite(V1, currentTime);

I'm sure it's not hard to do this, I just can't figure out how...

Oh dear, it's even worse than I thought. I really would like the time to be in AM/PM format, not 24 hour format. I'd normally do this with some long homemade code like this:

  boolean PMflag = false;  
  int theHour = hour();
  if(theHour == 0) { //12 AM
    theHour = 12;
    PMflag = false; //it's AM
  }
  else if (theHour == 12) { //noon
    //leave theHour as it is
    PMflag = true;
  }
  else if (theHour > 12) { //it's afternoon
    theHour = theHour - 12; 
    PMflag = true;
  }

but now to get all this together, as well as the possible extra '0' if the minute is less than 10, in one string as String currentTime that I can pass to the Blynk app?

Can't you just add that to your statement?

String currentTime = String(hour()) + ":" + ((minute() < 10)? "0": "") + minute() + ":" + second();

Instead of Arduino-crashing Strings, use sprintf(). The "02d" format option automatically zero-fills.

char buf[12];
   sprintf(buf,"%02d:%02d:%02d",hour(),minute(),second());
   Serial.println(buf);

jremington:
Instead of Arduino-crashing Strings, use sprintf(). The "02d" does zero-fill.

char buf[12];

sprintf(buf,"%02d:%02d:%02d",hour(),minute(),second());
  Serial.println(buf);

This sounds great! I'll try it out. I don't understand the sprintf function at all (I'm arduino self taught, no schooling in actual C). So I guess I can replace the line: Serialprintln(buf) with.
Blynk.virtualWrite(V1, buf);

I'll try it an see!

First of all, dump the String class. It will cause you nothing but problems down the road. While this may seem harder, it's not:

   char timeString[10];
   int hours;
   int minutes;

   hours = hour();
   strcpy(timeString, itoa(hours);      // Convert hours to a string and copy it to the buffer
   strcat(timeString, ":");

   minutes = minute();
   if (minutes < 10) {
      strcat(timeString, "0");
   }
   strcat(timeString, itoa(minutes));
   if (hours > 12) {                         // Adjust if military time
      strcat(timeString, " PM");
   } else {
      strcat(timeString, " AM");
   }
   Serial.println(timeString);

The String class is a crutch, so stick with the C string functions shown here. The sprintf() function will work, but it's an H-bomb to kill an ant. Compare code size for yourself, using sprintf() and the version shown here. My guess is that this version is at least 1K smaller.

Why even bother with strcat?
Just print each item, one after the other - let the serial output buffer do the concatenation :smiley:

SouthernAtHeart:
This sounds great! I'll try it out. I don't understand the sprintf function at all (I'm arduino self taught, no schooling in actual C).

That's no excuse. Google sprintf or his ugly cousin printf for more information.

econjack:
First of all, dump the String class. It will cause you nothing but problems down the road. While this may seem harder, it's not:

   char timeString[10];

int hours;
  int minutes;

hours = hour();
  strcpy(timeString, itoa(hours);      // Convert hours to a string and copy it to the buffer
  strcat(timeString, ":");

minutes = minute();
  if (minutes < 10) {
      strcat(timeString, "0");
  }
  strcat(timeString, itoa(minutes));
  if (hours > 12) {                        // Adjust if military time
      strcat(timeString, " PM");
  } else {
      strcat(timeString, " AM");
  }
  Serial.println(timeString);




The String class is a crutch, so stick with the C string functions shown [here](https://www.tutorialspoint.com/c_standard_library/string_h.htm). The *sprintf()* function will work, but it's an H-bomb to kill an ant. Compare code size for yourself, using *sprintf()* and the version shown here. My guess is that this version is at least 1K smaller.

I'd like to try this, but it doesn't compile. An error "too few arguments to function 'char* itoa(int, char*, int)'"

TolpuddleSartre:
Why even bother with strcat?
Just print each item, one after the other - let the serial output buffer do the concatenation :smiley:

Serial output is not the end result of this all, which I stated in the first post...

SouthernAtHeart:
I'd like to try this, but it doesn't compile. An error "too few arguments to function 'char* itoa(int, char*, int)'"

I bet you could've googled this

TolpuddleSartre:
I bet you could've googled this

LOL, I did. found a similar page Here, that someone else suggested and it looks just as greek to me. :frowning:
I'll just stick with the 24 hour format. It'll be fine like that.

jremington:
...use sprintf()...

snprintf is a better choice.

econjack:
While this may seem harder, it's not:

strncat is a better choice.

SouthernAtHeart:
I'd like to try this, but it doesn't compile. An error "too few arguments to function 'char* itoa(int, char*, int)'"

My bad: the itoa function needs three arguments:

   char timeString[10];
   char temp[5];            // Can be done without this, but easier to understand with it
   int hours;
   int minutes;

   hours = hour();
   itoa(hours, temp, DEC);               // Use base 10 numbers
   strcpy(timeString, temp);      // Convert hours to a string and copy it to the buffer
   strcat(timeString, ":");

   minutes = minute();
   if (minutes < 10) {
      strcat(timeString, "0");
   }
   itoa(minutes, temp, DEC);
   strcat(timeString, temp);
   if (hours > 12) {                         // Adjust if military time
      strcat(timeString, " PM");
   } else {
      strcat(timeString, " AM");
   }
   Serial.println(timeString);

I'm still away from my computer, but this should work...

@econjack, what do you don't like on sprintf?

Juraj:
@econjack, what do you don't like on sprintf?

Code bloat if you're not using it a bunch of times. It's a BIG function.

Juraj:
@econjack, what do you don't like on sprintf?

Like Delta_G said, code size. sprintf() is a very powerful and flexible function, but rarely does a program use a significant portion of that power. In the following program:

#include <TimeLib.h>

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  while (!Serial);
  
  char buf[12];

  Serial.begin(115200);
  while (!Serial);

  sprintf(buf, "%02d:%02d:%02d", hour(), minute(), second());
  Serial.println(buf);

/*
   char timeString[10];
   char temp[5];            // Can be done without this, but easier to understand with it
   int hours;
   int minutes;

   hours = hour();
   itoa(hours, temp, DEC);               // Use base 10 numbers
   strcpy(timeString, temp);      // Convert hours to a string and copy it to the buffer
   strcat(timeString, ":");

   minutes = minute();
   if (minutes < 10) {
      strcat(timeString, "0");
   }
   itoa(minutes, temp, DEC);
   strcat(timeString, temp);
   if (hours > 12) {                         // Adjust if military time
      strcat(timeString, " PM");
   } else {
      strcat(timeString, " AM");
   }
   Serial.println(timeString);
 */ 
}

void loop() {

}

the sprintf() version of the code, although only a couple of lines, uses 4038 bytes of flash and 241 bytes of SRAM. The commented-out code, while considerably longer, only uses 2848 bytes of flash and 239 bytes of SRAM. True, in this little test program it really doesn't matter, but as programs become more complex and memory starts disappearing, you just might have to put sprintf() on the back shelf.

char currentTime[9];

byte hh = hour();
byte mi = minute();
byte ss = second();

currentTime[0] = '0' + (hh / 10);
currentTime[1] = '0' + (hh % 10);
currentTime[2] = ':';
currentTime[3] = '0' + (mi / 10);
currentTime[4] = '0' + (mi % 10);
currentTime[5] = ':';
currentTime[6] = '0' + (ss / 10);
currentTime[7] = '0' + (ss % 10);
currentTime[8] = 0;