Go Down

Topic: Extracting hour/minute/second/date from String (Read 6707 times) previous topic - next topic

arsalh

Feb 29, 2016, 09:55 pm Last Edit: Feb 29, 2016, 10:10 pm by arsalh
Can someone help me with converting a string to day/date/hour/sec/minute etc into separate variables?
I have a string that contains date/time and want to use it to set time using Arduino's Time Library.


STRING TO CONVERT:      "Date: Mon, 29 Feb 2016 12:02:00 GMT"
FUNCTION TO USE:          setTime(hr,min,sec,day,month,yr);

So from the string above, I want to extract hour, minute, seconds, day, month and year into variables. I am trying to do this on an Arduino Uno.

aarg

Well, as you can imagine, it will be a huge pain. So, I have to ask, why do you need to read the time in this format? Perhaps we can suggest a better alternative if you explain the reason.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

arsalh

Hey I am trying to get accurate time for my project. I am using ESP8266 and want to keep track of the time in the project. I have seen the API methods for getting time but it seems to me that those take a little longer. So what I am doing instead is that I am extracting the time/date from the GET response I receive when I try to open a JSON file stored on a web server. Since I am opening the JSON file either way for my project, I wouldn't have to connect to a separate host to get time/date if I do it this way.

I may be super wrong in my assumptions but I just thought that might be the better way of approaching this. Let me know what you think.

aarg

#3
Feb 29, 2016, 10:47 pm Last Edit: Feb 29, 2016, 10:55 pm by aarg
Oh, yeah. I've noticed that string. I thought about tapping into it. Have you thought about using NTP? There is an NTP example in the Ethernet library. The example shows how to convert the time to a format that the Time library can import.

Just be a good netizen and don't poll the NTP server more than once a few minutes.

Or even easier, use an accurate RTC.

Otherwise, I don't believe there is an easy answer, it will just be lines and lines of dull plodding parsing code.

Note that DateStrings.cpp in the Time Library has the strings you need, e.g.
Code: [Select]
const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

PaulS

Quote
Can someone help me with converting a string to day/date/hour/sec/minute etc into separate variables?
Is the data in a string, as this question suggests? Or, is it in a String, as the thread topic suggests.

Parsing a string is easy. Parsing a String is a pain in the ass.
The art of getting good answers lies in asking good questions.

Jon_White

Try this.  As long as the date is always well-formed, it should work...

Code: [Select]
#include "stdafx.h"

int ParseDatePart(int partNumber, char* pDate)
{
// Find the right part using space and colon as delimiters.  Return -1 if we run out of parts.
int index = 0;
while (partNumber)
{
if (pDate[index] == ':' || pDate[index] == ' ') partNumber--;
if (!pDate[++index]) return -1;
}

// If the part starts with a digit, read all of the digits.
int result = 0;
while (pDate[index] >= '0' && pDate[index] <= '9')
{
result = result * 10 + pDate[index++] - '0';
if (pDate[index] < '0' || pDate[index] > '9') return result;
}

// Otherwise, read it as a month.
switch (pDate[index++])
{
case 'J':
if (pDate[index] == 'a') return 1;
if (pDate[index++] && pDate[index] == 'n') return 6;
return 7;
case 'F':
return 2;
case 'M':
if (pDate[index++] && pDate[index] == 'r') return 3;
return 5;
case 'A':
if (pDate[index] == 'p') return 4;
return 8;
case 'S':
return 9;
case 'O':
return 10;
case 'N':
return 11;
case 'D':
return 12;
}

// Return -1 if it didn't parse as either a number or a month.
return -1;
}

int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Usage:   foo <date>\r\n");
printf("Example: foo \"Date: Mon, 29 Feb 2016 12:02:00 GMT\"\r\n");
return 1;
}
char* pDate = argv[1];
int day = ParseDatePart(3, pDate);
int month = ParseDatePart(4, pDate);
int year = ParseDatePart(5, pDate);
int hour = ParseDatePart(6, pDate);
int minute = ParseDatePart(7, pDate);
int second = ParseDatePart(8, pDate);
printf("%d/%d/%d %d:%d:%d\r\n", month, day, year, hour, minute, second);
return 0;
}

zoomkat

Quote
So from the string above, I want to extract hour, minute, seconds, day, month and year into variables. I am trying to do this on an Arduino Uno.
If the character string received is captured as a String, then the various String functions can be used to extract the desired data.
Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

-dev

#7
Mar 01, 2016, 03:38 pm Last Edit: Aug 06, 2016, 06:06 pm by /dev Reason: Add link to Majenko's excellent article
Don't use String.  The solutions using C strings (i.e., char arrays) are very efficient.

String will add at least 1600 bytes of FLASH to your program size and 10 bytes per String variable.  Although String is fairly easy to use and understand, it will also cause random hangs and crashes as your program runs longer and/or grows in size and complexity.  This is due to dynamic memory fragmentation  caused by the heap management routines malloc and free.

The most recent example of the pitfalls of String can be seen here.

Related forum discussions:
Commentary from systems experts elsewhere on the net:
Cheers,
/dev
Really, I used to be /dev.  :(

Go Up