RTClib now() within while loop does not update I ran into this while trying to make a battery monitor and wondered where I went wrong. Using RTClib available in the Arduino IDE or from adafruit github, I ran into problems when trying to call now within a while loop inside of loop.  Here is a simple example:
#include &quot;RTClib.h&quot;

#define ledPIN 13

RTC_PCF8523 rtc;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPIN, OUTPUT);
  digitalWrite(ledPIN, LOW);
  Serial.begin(9600);
  while(!Serial) {/* wait for Serial */}
  rtc.begin();
  rtc.start();
  digitalWrite(ledPIN, HIGH);
 }

void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = &quot;YYYY/MM/DD-hh:mm:ss\n&quot;;
  while (millis() &lt; 60000){
    Serial.println((rtc.now()).toString(fmt));
    delay(5000); 
  }
  Serial.println(&quot;Finished&quot;);
  digitalWrite(ledPIN, LOW);
  while(1) { /* do nothing forever */ }
}

The output of this little test will be the same time repeated every 5ish seconds.  If it matters I am using a Feather M0 with the FeatherLogger that has an RTC on it.  Changing this loop function to this:
void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = &quot;YYYY/MM/DD-hh:mm:ss\n&quot;;
  if (millis() &lt; 60000){
    Serial.println((rtc.now()).toString(fmt));
    delay(5000); 
  } else {
    Serial.println(&quot;Finished&quot;);
    digitalWrite(ledPIN, LOW);
    while(1) { /* do nothing forever */ }
  }
} 

shows that now does in fact update the time every 5ish seconds.  I looked at the code for now and it appears to do very basic i2c commands to get the time and report it back.  The only thing I can think of is that the compiler created a (not so) temporary DateTime object for me within the while loop and the RTC library does not provide a convenient constructor or operator to overwrite the existing object.
I tested my theory with this
void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = &quot;YYYY/MM/DD-hh:mm:ss\n&quot;;
  while (millis() &lt; 60000){
    DateTime t1 = rtc.now();
    Serial.println(t1.toString(fmt));
    delay(5000); 
  }
  Serial.println(&quot;Finished&quot;);
  digitalWrite(ledPIN, LOW);
  while(1) { /* do nothing forever */ }
}  

But again, the time did not change so clearly I don't understand what's happening here.  Why doesn't the rtc now function work as intended within a while loop inside the loop function?
See the documentation of DateTime::toString():

The buffer parameter should be initialized by the caller with a
string specifying the requested format. This format string may contain
any of the following specifiers: [...] The specifiers within buffer
will be overwritten with the appropriate values from the DateTime.
Any characters not belonging to one of the above specifiers are left
as-is.

The important thing to realize is that the buffer parameter is used
both as input (for the format description) and as output (for the
formatted date and time). You initialize it with a format description
(&quot;YYYY/MM/DD-hh:mm:ss\n&quot;). Then, after the first call to toString(),
the same buffer contains the formatted date and time. It does not
contain the format description anymore. On the second call to
toString(), as per the rule “Any characters not belonging to one of
the above specifiers are left as-is”, the buffer is not modified.
Solution: Put the buffer initialization within the same while loop
as the call to toString().