Q:

default parameter class method

I have this function (which works fine):
String Esper::rtcTimeString() {
  DateTime now = rtc.now();
  char buf[] = "MM/DD/YY hh:mm:ss";
  return now.toString(buf);
}

I'd like to have a default value of "MM/DD/YY hh:mm:ss" but also pass an argument to a parameter such as "MM/DD/YYYY" if I want to override this default behavior.
Typically, in the definitions .h file I would do something like:
String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

and subsequently in the .cpp:
String Esper::rtcTimeString(char ts[]) {
  DateTime now = rtc.now();
  return now.toString(ts);
}

However that results in the same returned time string every time.
e.g.
1/6/2020 12:01:12
1/6/2020 12:01:12
1/6/2020 12:01:12

How can I implement a parameter such that the functionality is the same as in the first code block?

A:

You cannot pass an array of characters as an argument (implicit or not)
to a function. When you write
String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

The array notation is implicitly converted to a pointer. The line above
is then equivalent to:
String rtcTimeString(char *ts = "MM/DD/YY hh:mm:ss");

And this is incorrect: you are initializing a pointer to modifiable
characters using the address of an array of constant characters. The
compiler should have warned you about this... if you enabled compiler
warnings. The correct prototype should be
string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss");

But then you cannot pass this pointer to DateTime::toString(), as this
method expects the template string to live in a buffer it can overwrite:
that's where it will write the formatted string.
I suggest this solution:
string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss") {
    DateTime now = rtc.now();
    char buf[strlen(ts)+1];  // allocate a fresh buffer
    strcpy(buf, ts);         // copy the template there
    return now.toString(buf);
}

