Isolating a part of a string returned by a serial port

I am using a esp8266 to retrieve the current date and time from a web server

String response = "";         
      
while(wifi.available())
{
   char c = wifi.read(); // read the next character.
   response+=c;
}  
    
Serial.print(response);

This prints the following to the hardware serial

+IPD,0,637:HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Connection: close
Status: 200 OK
X-Frame-Options: ALLOWALL
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
Access-Control-Allow-Headers: origin, content-type, X-Requested-With
Access-Control-Max-Age: 1800
ETag: "6618644d86bb40f12eefc8f3f59cd42e"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 54474c64-10bc-4dc6-9bc4-4d893915a6eb
X-Runtime: 0.095279
X-Powered-By: Phusion Passenger 4.0.57
Date: Sun, 01 Nov 2015 17:54:56 GMT
Server: nginx/1.9.3 + Phusion Passenger 4.0.57

Sun, 01/11/2015, 17:54
OK

I cant use a substring on this string and am trying to work out a way that I can pull out just the date and time information. Something like this.

Sun, 01/11/2015, 17:54

Any help would be appreciated.

if you are familiar with C strings, try strstr() to locate the substring "Date: "

one you have your pointer there you ought to be able to tokenize the string using strtok() with the chars that tokenize the date you are looking for.

One strategy were:

wait for a line beginning with "+IPD"
wait for the next empty line
grab the next line and return it

Code you could insert

// example usage
  Serial.print("* parsetest: ");
  char* result = (char*)dateContent(buff, buffLen);
  Serial.print("result '");
  Serial.print(result);
  Serial.print("' len ");
  Serial.println(strlen(result));

// implementation

const int buffLen = 100;
byte buff[buffLen];

enum {
  sStart,     // collect line until CR, if "+IPD" next state
  sScan,      // collect line until CR, if empty next state
  sStore,     // collect line until CR, then next state
  sDeliver    // zero terminate result, leave parser
};

byte* dateContent(byte* buf, int bufLen) {
  byte sState = sStart;
  byte cPos = 0;
  byte inByte;

  bufLen -= 2;  // adjust to maxStorePos

  while (sState != sDeliver) {
    if (Serial.available()) {
      if (10 == (inByte = Serial.read())) {
        continue;                           // ignore LF
      }
      switch (sState) {
        case sStart:
          if (inByte == 13) {
            if (!strncmp((char*)buf, "+IPD", 4)) { // prelude found
              sState = sScan;
            }
            cPos = 0;                       // drop line
          } else {
            if (cPos < bufLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          }
          break;
        case sScan:
          if (inByte == 13) {
            if (!cPos) {  // prelude found
              sState = sStore;
            }
            cPos = 0;                       // drop line
          } else {
            if (cPos < bufLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          }
          break;
        case sStore:
          if (inByte != 13) {
            if (cPos < buffLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          } else {
            buf[cPos] = 0;
            sState = sDeliver;              // exit parser
          }
          break;
      }
    }
  }
  return buf;
}

Testprogramm using your original data (maybe without LF but that is ignored anyway)

class dummySerial {
  public:
    dummySerial() {};
    void begin(char* readStart, int len) {
      rCurr = readStart;
      rEnd = readStart + len;
    }
    int available() {
      return rEnd - rCurr;
    };
    byte read() {
      return (rCurr < rEnd) ? *rCurr++ : 0;
    };
    char* rCurr;
    char* rEnd;
};

dummySerial Cerial;

char testInput[] = "\r+IPD,0,637:HTTP/1.1 200 OK\rContent-Type: text/html; charset=utf-8\rConnection: close\rStatus: 200 OK\rX-Frame-Options: ALLOWALL\rAccess-Control-Allow-Origin: *\rAccess-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH\rAccess-Control-Allow-Headers: origin, content-type, X-Requested-With\rAccess-Control-Max-Age: 1800\rETag: \"6618644d86bb40f12eefc8f3f59cd42e\"\rCache-Control: max-age=0, private, must-revalidate\rX-Request-Id: 54474c64-10bc-4dc6-9bc4-4d893915a6eb\rX-Runtime: 0.095279\rX-Powered-By: Phusion Passenger 4.0.57\rDate: Sun, 01 Nov 2015 17:54:56 GMT\rServer: nginx/1.9.3 + Phusion Passenger 4.0.57\r\rSun, 01/11/2015, 17:54\rOK\r\r";

const int buffLen = 100;
byte buff[buffLen];

enum {
  sStart,     // collect line until CR, if "+IPD" next state
  sScan,      // collect line until CR, if empty next state
  sStore,     // collect line until CR, then next state
  sDeliver    // zero terminate result, leave parser
};

byte* dateContent(byte* buf, int bufLen) {
  byte sState = sStart;
  byte cPos = 0;
  byte inByte;

  bufLen -= 2;  // adjust to maxStorePos

  while (sState != sDeliver) {
    if (Cerial.available()) {               // CHANGE TO YOUR SERIAL
      if (10 == (inByte = Cerial.read())) { // CHANGE TO YOUR SERIAL
        continue;                           // ignore LF
      }
      switch (sState) {
        case sStart:
          if (inByte == 13) {
            if (!strncmp((char*)buf, "+IPD", 4)) { // prelude found
              sState = sScan;
            }
            cPos = 0;                       // drop line
          } else {
            if (cPos < bufLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          }
          break;
        case sScan:
          if (inByte == 13) {
            if (!cPos) {  // prelude found
              sState = sStore;
            }
            cPos = 0;                       // drop line
          } else {
            if (cPos < bufLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          }
          break;
        case sStore:
          if (inByte != 13) {
            if (cPos < buffLen) {
              buf[cPos++] = inByte;         // store if possible
            }
          } else {
            buf[cPos] = 0;
            sState = sDeliver;              // exit parser
          }
          break;
      }
    }
  }
  return buf;
}
byte* dateContent(byte* buf, int bufLen);

void setup() {
  Cerial.begin(testInput, strlen(testInput));
  Serial.begin(115200);
  Serial.print("* parsetest: ");
  char* result = (char*)dateContent(buff, buffLen);
  Serial.print("result '");
  Serial.print(result);
  Serial.print("' len ");
  Serial.println(strlen(result));
}

void loop() {}

Output

* parsetest: result 'Sun, 01/11/2015, 17:54' len 22

You should be able to do what you want fairly simply using Strings. You need to find a unique starting place in what you captured, then parse from there. You might try String parsing code like below to see if it gets you closer.

String response = "";         
     
while(wifi.available())
{
   char c = wifi.read(); // read the next character.
   response+=c;
} 
   
int ind1 = response.indexOf("\r\n\r\n");
response = response.substring(ind1);

Serial.print(response);