how to get boost::posix_time::ptime from formatted string - c++

I have a formated string like "2012-03-28T08:00:00".
i want to get year, month(in string format),date,hour, min ,sec and day (in string format).
can any one suggest me the easiest way to do it in boost.
thanks

If the existing from_string() methods do not suit your needs then you can use a time input facet that allows you to customise the format from which the string is parsed.
In your case you can use the ISO extended format string so you can use the following code to parse your strings:
boost::posix_time::time_input_facet *tif = new boost::posix_time::time_input_facet;
tif->set_iso_extended_format();
std::istringstream iss("2012-03-28T08:00:00");
iss.imbue(std::locale(std::locale::classic(), tif));
iss >> abs_time;
std::cout << abs_time << std::endl;

Without using facets;
ptime dateTime = boost::date_time::parse_delimited_time<ptime>(string, 'T');
The two from*_string functions have limits on what formats are converted.
Does not accept 'T': time_from_string(s).
Does not accept '-': from_iso_string(s).
Roundtripping ISO 8601 date/time in boost;
std::string date = to_iso_extended_string(dateTime);

Related

Is there a way to extract certain info from a string? c++

I need to read in some lines from a text file (amount of lines will be known during run time) but an example could be something like this:
Forecast.txt:
Day 0:S
Day 3:W
Day 17:N
My idea was to create a class which I did:
class weather
{
int day;
char letter;
};
Then create a vector of class as so:
vector<wather>forecast;
and now here is where I'm stuck. So I think I'd use a while loop?
id use my ifstream to read the info in and use a string to hold the information im reading in.
What I want to do is read in each line and extract the day number so in this example the 0, 3 and 15 and get the letter so S, W, N and store it in the vector of the class.
I was wondering if there's any way to do that? I could be coming at this wrong so forgive me im new to c++ and trying to figure this out.
Thank you for helping!
Your can use std::istringstream to parse each line, eg:
#include <sstream>
while (getline(in_s1, lines2))
{
istringstream iss(lines2);
string ignore1; // "Day"
char ignore2; // ":"
forecast f;
if (iss >> ignore1 >> f.day >> ignore2 >> f.letter)
weather.push_back(f);
}
Live Demo
Alternatively, you can parse each line using std::regex and related classes.
istringstream and the >> operator is probably the neatest C++ way to do it, as described in Remy's answer. In case you prefer to be a little less reliant on the stream magic and a bit more explicit, you can find the tokens you need and then extract them directly from the string.
Something like this:
while (getline(in_s1, lines2))
{
size_t startPos = lines2.find(' '); //get position of the space before the day
size_t endPos = lines2.find(':', startPos); //get position of the colon after the day
string day = lines2.substr (startPos+1, endPos-startPos-1); //extract the day
forecast f;
f.day = stoi(day); //stoi only supported since C++11, otherwise use atoi
f.letter = lines2[endPos+1];
weather.push_back(f);
}

How to insert a colon in between string as like date formats in c++?

I have string 20150410 121416 in c++.
I need to turn this into 20150410 12:14:16
How can i insert a colon to the string?
One can format date/times in C and C++ with strftime. There also exists a non-standard but common POSIX function called strptime one can use to parse times. One could use these to parse your date/time in your input format, and then format it back out in your desired format.
That is, assuming you didn't want to write the parsing code yourself.
If you have C++11, then you could use this free, open-source date/time library to help you do all this with strftime-like format strings. Such code could look like:
#include "tz.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
std::string input = "20150410 121416";
std::stringstream stream{input};
stream.exceptions(std::ios::failbit);
sys_seconds tp;
parse(stream, "%Y%m%d %H%M%S", tp);
auto output = format("%Y%m%d %T", tp);
std::cout << output << '\n';
}
Output:
20150410 12:14:16
One advantage of using a date/time parsing/formatting library, as opposed to just treating these as generic strings, is that you can more easily alter the formatting, or manipulate the datetime during the format conversion (e.g. have it change timezones).
For example, next month the specification might change on you and now you're told that this is a timestamp representing local time in Moscow and you need to convert it to local time in London and output it in the form YYYY-MM-DD HH:MM:SS <UTC offset>. The above code hardly changes at all if you're using a good date/time library.
#include "tz.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
std::string input = "20150410 121416";
std::stringstream stream{input};
stream.exceptions(std::ios::failbit);
local_seconds tp;
parse(stream, "%Y%m%d %H%M%S", tp);
auto moscow_time = make_zoned("Europe/Moscow", tp);
auto london_time = make_zoned("Europe/London", moscow_time);
auto output = format("%F %T %z", london_time);
std::cout << output << '\n';
}
2015-04-10 10:14:16 +0100
But if you started out just doing string manipulation, all of the sudden you've got a major task in front of you. Writing code that understands the semantics of the datetime "20150410 121416" is a significant leap above manipulating the characters of "20150410 121416" as a string.
<script type="text/javascript">
function formatTime(objFormField){
intFieldLength = objFormField.value.length;
if(intFieldLength==2 || intFieldLength == 2){
objFormField.value = objFormField.value + ":";
return false;
}
}
</script>
Enter time <input type="text" maxlength="5" minlength="5" onKeyPress="formatTime(this)"/>

Convert string with thousands (and decimal) separator into double

User can enter double into textbox. Number might contain thousands separators. I want to validate user input, before inserting entered number into database.
Is there a C++ function that can convert such input (1,555.99) into double? If there is, can it signal error if input is invalid (I do not want to end up with function similar to atof)?
Something like strtod, but must accept input with thousands separators.
Convert the input to double using a stream that's been imbued with a locale that accepts thousand separators.
#include <locale>
#include <iostream>
int main() {
double d;
std::cin.imbue(std::locale(""));
std::cin >> d;
std::cout << d;
}
Here I've used the un-named locale, which retrieves locale information from the environment (e.g., from the OS) and sets an appropriate locale (e.g., in my case it's set to something like en_US, which supports commas as thousands separators, so:
Input: 1,234.5
Output: 1234.5
Of course, I could also imbue std::cout with some locale that (for example) uses a different thousands separator, and get output tailored for that locale (but in this case I've used the default "C" locale, which doesn't use thousands separators, just to make the numeric nature of the value obvious).
When you need to do this with something that's already "in" your program as a string, you can use an std::stringstream to do the conversion:
std::string input = "1,234,567.89";
std::istringstream buffer(input);
buffer.imbue(std::locale(""));
double d;
buffer >> d;
A C solution would be to use setlocale & sscanf:
const char *oldL = setlocale(LC_NUMERIC, "de_DE.UTF-8");
double d1 = 1000.43, d2 = 0;
sscanf("1.000,43", "%'lf", &d2);
if ( std::abs(d1-d2) < 0.01 )
printf("OK \n");
else
printf("something is wrong! \n");
setlocale(LC_NUMERIC, oldL);

Float64 to string

In C++, how can I convert a data of type float64 to a string without losing any of the data in float64? I need it to not only be converted to a string, but add a string to either side of the number and then sent to be written in a file.
Code:
string cycle("---NEW CYCLE ");
cycle+=//convert float64 to string and add to cycle
cycle+= "---\r\n";
writeText(cycle.c_str()); //writes string to txt file
Thanks.
The usual way of converting numbers to std::strings is to use std::ostringstream.
std::string stringify(float value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}
// [...]
cycle += stringify(data);
You should use sprintf. See documentation here C++ Reference.
As an example it would be something like:
char str[30];
float flt = 2.4567F;
sprintf(str, "%.4g", flt );
Also I would use string::append to add the string. See here .
UPDATE
Updated code according to comment.
You can use sprintf to format the string.

C++ check if a date is valid

is there any function to check if a given date is valid or not?
I don't want to write anything from scratch.
e.g. 32/10/2012 is not valid
and 10/10/2010 is valid
If your string is always in that format the easiest thing to do would be to split the string into its three components, populate a tm structure and pass it to mktime(). If it returns -1 then it's not a valid date.
You could also use Boost.Date_Time to parse it:
string inp("10/10/2010");
string format("%d/%m/%Y");
date d;
d = parser.parse_date(inp, format, svp);
The boost date time class should be able to handle what you require.
See http://www.boost.org/doc/libs/release/doc/html/date_time.html
If the format of the date is constant and you don't want to use boost, you can always use strptime, defined in the ctime header:
const char date1[] = "32/10/2012";
const char date2[] = "10/10/2012";
struct tm tm;
if (!strptime(date1, "%d/%m/%Y", &tm)) std::cout << "date1 isn't valid\n";
if (!strptime(date2, "%d/%m/%Y", &tm)) std::cout << "date2 isn't valid\n";