date and time manipulation in c++ - c++

So, I want to do a class Delivery like this:
class Delivery{
private:
string recipient;
time_t date;
}
So, the date is time_t. The thing I want to do is let the user type the delivery date. Maybe the delivery is made today, maybe tomorrow, maybe next month. I could've made the date attribute string date instead of time_t. Why I didn't do that? Because, I have a list of deliveries and I want to sort the deliveries and then to print the deliveries that were made in a certain period. For example, print the deliveries made from 12.03.2013 until 25.08.2013.
The question is: how can I let the user set the date? I searched the Internet but I didn't found any useful functions. Is there a way to solve this problem?

Assuming you read the input into a string named time_string in the format 01/01/13:
struct tm tm;
strptime(time_string, "%D", &tm);
time_t t = mktime(&tm);
If you include the full year, e.g. 01/01/2013, replace strptime(time_string, "%D", &tm); with strptime(time_string, "%m/%d/%Y", &tm);. %m is the month, %d the day, and %Y the full year, e.g. 2013 instead of 13. Also note that if time_string is an std::string instead of a C-style string, you need to replace time_string with time_string.c_str() in the call to strptime.
Sources: https://stackoverflow.com/a/11213640/2097780 and http://publib.boulder.ibm.com/infocenter/zos/v1r12/index.jsp?topic=%2Fcom.ibm.zos.r12.bpxbd00%2Fstrptip.htm.

Working on date/time involves using the struct tm and time_t data structures.
To convert time_t to struct tm, there are a few differnt functions, such as localtime(), gmtime(), etc.
To convert from struct tm to time_t, you use mktime().
Obviously, you'll also need to write some code that reads year, month, day and perhaps hours and minutes from the user as integer values, then fill in a struct tm with the relevant values, and call mktime() to convert it to "seconds since 1 jan 1970" in a time_t value.
All functions to do this are declared in <ctime>

Given that you are using C++, you might want to consider using: Boost DateTime.

Related

Print current month as calendar using current system date C++

First time poster so excuse me if I make any sort of mistake.
I am fairly new to the whole programming in C++ but I was wondering if it is possible to print out a calendar of a certain month (the current one) e.g. today it is June 2015 so I want to print out the monthly calendar of June 2015 in C++
If anyone has any suggestion how to make this possible that would be extremely helpful. I know how to post the current month with user input yet I want my program to look at the system date.
Thanks in advance.
Use time(0) to get a time_t that is also somehow the number of seconds since xxxoopsxxxxx => epoch: Wed Dec 31 19:00:00 1969, so 1/1/1970
time_t linearTime = time(0);
Use localtime_r to convert the linearTime to
struct tm timeinfo = *localtime_r(&linearTime, &timeinfo);
Use struct tm to decode broken-down-time (in Linux, at /usr/include/time.h) and produce your calendar as you want.
Have fun.
Edit 2
Looked into chrono. Figured out how to measure duration in us.
BUT, the following chrono stuff is suspiciously similar to previous stuff.
std::time_t t0 = std::time(nullptr);
std::tm* localtime(const std::time_t* t0); // std::tm has the fields you expect
// convenient to text
std::cout << std::asctime(std::localtime(&t0)); // prints the calendar info for 'now'
I suspect not much different at all.
edit 3
I have doubts. I think the previous suspiciously familiar bit came from ctime, not chrono. So I plan digging around in chrono some more.

What is the right way to convert into UNIX timestamp from the date and time in C/C++?

I have a lot of dates with time in this format:
day.mon.year - hour:min:sec
And I need to convert this dates with time into Unix timestamp.
I used tm structure, but I can't fill those fields:
tm_wday
tm_yday
And I don't must I fill those field, because I don't know do this field have any effect to the value of Unix timestamp.
Help me to choose rigth way to calculate Unix timestamp.
P.S. Dates with time aren't current, they can be date of the 20-th century or future dates (to 2038 year).
P.P.S. I use OS Windows.
POSIX has a formula for exactly what you want:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15
tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
(tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
This works whenever you have a broken-down time in GMT, even if the underlying system's mktime, etc. functions do not use the same format time_t as "Unix timestamps".
If your original time is in local time, you can use mktime and gmtime to convert it to GMT using the system's notion of timezone rules. If you want to apply your own timezone offset rules, just do that manually before using the above formula.
If you are on unix, mktime() will get the second part of the timestamp. It ignores the tm_wday and tm_yday fields.

(Detailed) how to calculate time duration from epoch 1900 to now use boost?

As title, how to calculate time duration from epoch 1900 to now use boost?
Edit: Sorry about too short question at previous. I will describe my question again.
I have problem about save birthday to database as integer number. I have create four functions use as following:
ptime to integer (by day):
int ti=time_to_int(ptime(date(2012,1,1),0));
=> ti = 15430;//number of day from 1970 to 2012
integer to ptime:
ptime pt = int_to_time(15430);
ptime to string:
ptime pt(date(2012,1,1), 0);
string s = time_to_string(pt, "%d.%m.%Y");
string to ptime:
ptime pt = string_to_time(%d.%m.%Y);
PROBLEM:
Above, I have used epoch from 1970 and All work very well. So how can I convert 01/01/1945 to integer? I think that need use epoch from such as 1900.
However, when convert 01/01/2012 to int from 1900 it returns negative number, because "I think" tick count in miliseconds overflow (32bit).
Use some ways manual to calculate date to int is ok, but convert int back to date seems to bad. I want to use boost to do this.
Any suggestion?
Thanks!
Integer (int) is not big enough to hold the number of seconds since 1900. It can only hold about 68 years. You need to use a long (64 bit). Boost's time_duration will give you access to the number of seconds as a long. You could also use the number of days as mentioned by #jogojapan. However, day lengths are not always the same (23-25 hours), so sometimes keeping track of things in days is more prone to error (if you are careful it should be fine though).
Take a look at some examples from the documentation. You can subtract two ptime objects to get a time_duration:
time_duration td = ptime1 - ptime2;
long secElapsed = td.total_seconds();

create variable to hold time created

Im creating a contact list program and need to beable to record when the contact was created and list the contacts according to their creation date.
what can i use to give a variable a date? i know the time.h file has something inside, but i dont know how to use it with less code as possible.
perhaps
time.h seconds = timeStamp;
?
if this is the way, then what would the output be? and whats the best way to output it in order? this variable will be part of a class.
I know you can use time_t for dates. If you need higher precision, use clock_t
You can get the current time as follows. Note that what is stored is an integer value of the number of seconds since January 1st, 1970.
#include <time.h>
....
time_t s = time(NULL);
See this for further details. Hope that helps!
#include <time.h>
...
time_t seconds = time(NULL);
The seconds variable will contain the number of seconds since 1970, which is enough information to store both date and time.
You can use the asctime function to convert this value into a human-readable string.

Date/Time parsing in C++

While doing the data/time parsing in c++ (converting a string in any format to a date), i found the following useful methods
1) strptime() - here the %d, %m etc can have either 1 or 2 characters. The function will take care of that. As a result of this it will enforce that we use a separator between two conversion specifiers. Ex: Its not valid to give %d%m it has be to %d/%m or any other separator. Also this does not support timezones.
2) Boost date IO - here the %d, %m has to have 2 characters. Now, the input string i get is not guaranteed to have this. As a result, its not possible to use this successfully. However, this does seem to support timezone, but not sure. because it says for inputs it does support timezone
So i am planning to use both in conjunction to determine the date. But i would like to get one where i can take into account the timezone as well. But none seems to be supporting that.
Does anybody have a suggestion?
Rgds,
AJ
#AJ: Added another answer so the code gets formatted
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
int
main(void)
{
struct tm tm[1] = {{0}};
strptime("Tue, 19 Feb 2008 20:47:53 +0530", "%a, %d %b %Y %H:%M:%S %z", tm);
fprintf(stdout, "off %ld\n", tm->tm_gmtoff);
return 0;
}
And a run looks like (glibc 2.10.1):
freundt#clyde:pts/28:~/temp> ./test
off 19800
Depends on the libc version, I'd say, and of course what you mean by `taking into account': Is it supposed to read the additional info and then ignore it, is it supposed to store the parsed info in the tm struct, or is it meant to convert to system/environment time?
glibc 2.10.1's strptime() does time zones, from the info page
`%z'
The offset from GMT in ISO 8601/RFC822 format.
`%Z'
The timezone name.
_Note:_ Currently, this is not fully implemented. The format
is recognized, input is consumed but no field in TM is set.
As you noticed strptime doesn't directly support timezones. All it does is read formatted timezone-less data into a tm structure. You'll have to parse an optional timezone indicator yourself (unless it's fixed), and then set TZ and use mktime to convert into a time_t. If you set tm.is_dst to -1 you can even ask that mktime try to figure out the DST for you automatically.
Alternately you could construct your own parser using steams (boost supports a few formats, but may not be general enough). Again like above you can use mktime to compose a time_t.