Implement a function that determines and prints out the current year, month and day. For example:
Today is 03/04/2014.
Code so far that I have:
#include <stdio.h>
#include <time.h>
int main ()
{
int days, weeks, months, years, option, rmd, currentyear, currentmonth;
int daysinjan, daysinfeb, daysinmarch;
time_t seconds;
seconds = time(NULL);
days = seconds/(60*60*24);
weeks = seconds/((60*60*24)*7);
rmd=seconds%31557600;
months = ((seconds/31557600) * 12)+(((float)rmd/31557600)*12);
years = days/(365.25);
currentyear = 1970 + years;
currentmonth = (((float)rmd/31557600)*12)+1;
printf("%ld/%ld", currentmonth,currentyear);
return 0;
}
Please do not mind all the useless stuff in the code, this question is part of a project and i simply used the code from my previous question to try and work with that code in order to solve this question. The problem i have is that i cannot print the current day of the month that it is, because of this i feel that i have gone about this question wrongly.
This uses standard library calls to do all the math for you.
From Here:
#include <time.h>
#include <stdio.h>
#define SIZE 256
int main (void)
{
char buffer[SIZE];
time_t curtime;
struct tm *loctime;
/* Get the current time. */
curtime = time (NULL);
/* Convert it to local time representation. */
loctime = localtime (&curtime);
/* Print out the date and time in the standard format. */
fputs (asctime (loctime), stdout);
/* Print it out in a nice format. */
strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime);
fputs (buffer, stdout);
strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime);
fputs (buffer, stdout);
return 0;
}
If you wanted to create this as a function to return a string, you could do it like this:
char * getTimeString (char *str)
{
//replace this comment with relevant code from above with (at least) two additional lines:
strcpy(str, buffer);
return str;
}
Call it like this:
int main(void)
{
char *timeStr;
timeStr = malloc(30);//sufficient length to accept values assigned in getTimeString()
printf("%s\n", getTimeString(timeStr);
free(timeStr);
return 0;
}
#include <time.h> // for time_t
#include <stdio.h> // for printf
int main () {
int days, weeks, months, years, option, rmd, currentyear, currentmonth;
int daysinjan, daysinfeb, daysinmarch;
time_t seconds;
seconds = time(NULL);
days = seconds/(60*60*24);
weeks = seconds/((60*60*24)*7);
rmd=seconds%31557600;
months = ((seconds/31557600) * 12)+(((float)rmd/31557600)*12);
years = days/(365.25);
currentyear = 1970 + years;
currentmonth = (((float)rmd/31557600)*12)+1;
printf("%ld/%ld", currentmonth,currentyear);
return 0;
}
Related
Let's say the user is prompted for the date - e.g. Friday.
How can that string be used to correctly compare with another sting?
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t current_time;
struct tm * time_info;
char timeString[9];
time(¤t_time);
time_info = localtime(¤t_time);
strftime(timeString, sizeof(timeString), "%A", time_info);
printf("%s\n",timeString);
if (timeString == "Friday")
{printf("Weekday");
}
else
{printf("not weekday");
}
return 0;
}
The program keeps printing out not weekday.
Use strncmp() instead of comparing the string with ==:
if (strncmp(timeString,"Friday",7) == 0)
{printf("Weekday");
}
See this in action at tutorialspoint.com:
Friday
Currently, it is Thursday (for ~50% of the world) - so try this one:
Thursday
I need to validate a date-time value for "YYYYMMDDHHMMSSmmmmmm" format. Actually what I am hoping is I need to find out a already tested working C code to validate a date time value for above format.
Further, I have a date-time value like 201304011031000000. I need a function to verify whether this is a valid date or not.[isdatetime()]
Below are the each parts of formats.
YYYY : Year
MM : Month
DD : Day
HH : hour
MM : Minutes
SS : seconds
mmmmmm: micro-seconds
If you're on a POSIX system, this looks like something that should be handled with strptime(), but the 'milliseconds' (or microseconds) part is not handled by strptime() or any other standard conversion function I know of.
Assuming the question is asking for microseconds, you could use a variation on the theme provided by:
#include <stdio.h>
#include <string.h>
#include <time.h>
int main(void)
{
const char datetime[] = "20130417221633012345"; // YYYYMMDDHHMMSSFFFFFF
struct tm time_val;
unsigned microsecs;
const char *end = strptime(datetime, "%Y%m%d%H%M%S", &time_val);
if (end != 0)
{
int nbytes;
if (strlen(end) == 6 && sscanf(end, "%6u%n", µsecs, &nbytes) == 1 &&
nbytes == 6)
{
char buffer[32];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &time_val);
printf("%s = %s.%.6u\n", datetime, buffer, microsecs);
}
}
return 0;
}
Revised requirement
#include <stdio.h>
#include <string.h>
#include <time.h>
int isdatetime(const char *datetime)
{
// datetime format is YYYYMMDDHHMMSSFFFFFF
struct tm time_val;
unsigned microsecs;
int nbytes;
const char *end = strptime(datetime, "%Y%m%d%H%M%S", &time_val);
if (end != 0 && strlen(end) == 6 &&
sscanf(end, "%6u%n", µsecs, &nbytes) == 1 && nbytes == 6)
return 1; // Valid
return 0; // Invalid
}
You can use regex.h for windows or for linux.
"YYYYMMDDHHMMSSMSSSSS" is something like: (\d{4}[0,1][0,9]\d{})... you can find your specific format here, it depends wether you enable 24 or 12 clock etc.
I am editing time value using a variable of type struct tm (adding some seconds to tm->tm_sec), but I am getting wrong results after doing mktime(&t).
Doing so in Linux gets me proper results, but in AIX not. What could be the problem?
#include <stdio.h>
#include <time.h>
#include <langinfo.h>
#include <locale.h>
int main ()
{
struct tm tm;
struct tm *end;
time_t t;
char str[20] = {'\0'};
//if (strptime("7 Feb 2013 01:47:30", "%d %b %Y %H:%M:%S", &tm) == NULL)
if (strptime("2012-10-17-01-07-30", "%Y-%m-%d-%H-%M-%S", &tm) == NULL)
{printf("Error\n");
}
tm.tm_sec = (tm.tm_sec + 1200);
//tm.tm_sec = 12;
//t = mktime(&tm);
//t = t + 12;
//end =localtime(&t);
strftime(str,20,"%Y %m %d %H %M %S",&tm);
printf("str is %s\n",str);
return 0;
}
I believe the correct answer is to use time_t, which is a large number representing the time in seconds since midnight of 1 Jan 1970. Adding arbitrary number of seconds here becomes very trivial.
I expect that if you are just adding seconds to tm->tm_sec, it overflows, and that causes the result to be incorrect. If you are unlucky, you will need to ripple your change in seconds all the way through to year (adding 5 seconds to 31 Dec 2013 23:59:56 will take you to 01 Jan 2014 00:00:01). Which of course can be done, but instead of:
t =+ 5;
you get about a dozen steps along the line of
tm.tm_sec += 5;
if (tm.tm_sec >= 60)
{
tm.tm_sec -= 60;
tm.tm_min += 1;
if (tm.tm_min >= 60)
{
... And so on ...
}
}
It gets even more interesting if you overflow the days in a month, since you then have to take into account of the number of days in each month, 28, 29, 30 or 31 depending on which month [and if it's a leap-year or not].
This is effectively what Mats said:
#include <stdio.h>
#include <time.h>
#include <langinfo.h>
#include <locale.h>
int main ()
{
struct tm tm;
time_t t;
char str[20] = {'\0'};
if (strptime("2012-10-17-01-07-30", "%Y-%m-%d-%H-%M-%S", &tm) == NULL) {
printf("error\n");
}
t = mktime(&tm);
t += 1200;
tm = *localtime(&t);
strftime(str,20,"%Y %m %d %H %M %S",&tm);
printf("str is %s\n",str);
return 0;
}
Produces:
cc -o t t.c && ./t
str is 2012 10 17 02 27 30
I am trying to get Saturday's date of the week in Linux C. Using the function time and localtime, I got today's date and time details. How to proceed further to get Saturday's date?
#include <time.h>
#include <stdio.h>
#include <string.h>
int main()
{
char date[20];
struct tm *curr_tm = NULL;
time_t curr_time;
curr_time = time(NULL);
curr_tm = localtime(&curr_time);
curr_tm->tm_wday = 6;
//Refers to saturday.
printf("new date %d\t%d\t%d\n", curr_tm->tm_mday, curr_tm->tm_mon, curr_tm->tm_year+1900);
return 1;
}
How should I proceed with this?
struct tm orig;
// ...
// struct tm correctly set with everything within range.
orig.tm_mday += 6 - orig.tm_wday;
mktime(&orig);
tm_mday is the number of days since Sunday. Thus, 6 minus that is the number of days until Saturday (if today is Saturday it does nothing). This puts the structure out of range, which mktime fixes.
EDIT:
curr_time->tm_mday += 6 - curr_time->tm_wday;
mktime(curr_time);
Based on your code, the following will get you the next Saturday (today if it's Saturday).
#include <time.h>
#include <stdio.h>
#include <string.h>
int main() {
char date[20];
struct tm *curr_tm = NULL;
time_t curr_time;
curr_time = time(NULL);
curr_tm = localtime(&curr_time);
// Add the difference between todays day of week and Saturday, then re-make.
curr_tm->tm_mday += 6 - curr_tm->tm_wday;
mktime (curr_tm);
printf("new date %d\t%d\t%d\n",
curr_tm->tm_mday, curr_tm->tm_mon+1, curr_tm->tm_year+1900);
return 1;
}
You can replace the curr_tm->tm_mday += 6 - curr_tm->tm_wday; line with:
curr_tm->tm_mday += (curr_tm->tm_wday == 6) ? 7 : 6 - curr_tm->tm_wday;
to get next Saturday even if today is Saturday.
i need some advice and help with a plugin i am writing for Nagios.
i am writing the plugin in C, but have no previous experience in the language except for minor amounts whilst trying to get this plugin to work.
basically what i am trying to-do is the following.
read a text file that is generated on a remote PC by an application i have written, this program writes nothing more than 5 characters into the file, the first 4 chars are the time in 24 hour format. e.g. 22:30 > 10:30pm
it then needs to take these 4 characters convert them into a time and compare it to the current system time (if there is a difference of 5 mins then it generates a reply to nagios to flag a warning).
I have tried many different ways of doing this, my first attempt was to convert the characters into an integer, then convert the time into an integer and compare the difference .. failed at doing this.
my second attempt is to generate two Time Structs one with the current time in and the other with my "homemade" time in and compare them but this is not working either.
heres my code, no matter what i try the date from the file is always the same as the current system time, i know its something to-do with having to set the time at the top.
t_of_file = time(NULL);
time_from_file = localtime(&t_of_file);
but if i do not do this i get a segmentation fault.
heres the code.
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define COPYMODE 0644
int main(int argc, char *argv[])
{
struct tm *time_from_file;
struct tm *the_system_time;
time_t t_of_file;
time_t t_of_sys;
t_of_sys = time(NULL);
the_system_time = localtime(&t_of_sys);
t_of_file = time(NULL);
time_from_file = localtime(&t_of_file);
time_from_file->tm_year = the_system_time->tm_year;
time_from_file->tm_mon = the_system_time->tm_mon;
time_from_file->tm_mday = the_system_time->tm_mday;
time_from_file->tm_hour = 10; //should be read in from file
time_from_file->tm_min = 30; //should be read in from file
time_from_file->tm_sec = the_system_time->tm_sec;
time_from_file->tm_isdst = the_system_time->tm_isdst;
t_of_file = mktime(time_from_file);
printf("%s\n",ctime(&t_of_file));
t_of_sys = mktime(the_system_time);
printf("%s\n",ctime(&t_of_sys));
double difference = difftime(t_of_file, t_of_sys );
printf("%lf\n",(double)t_of_file);
printf("%lf\n",(double)t_of_sys);
if (difference >= 0.0) { //this should be 5 mins, not quite sure what to put here yet
// second is later than first
printf("later\n");
}
else if (difference < 0.0) {
// second is earlier than first
printf("earlier\n");
}
printf("%lf\n", difference);
return 0;//STATE_OK;
}
any help you can offer would be appreciated on this.
Following the answers i got, PACE's answer was spot on for what i wanted to-do and now i have a simpler bit of code that works perfectly for what i am trying to-do and is easier to under stand. below is the code in its modified form (it compiles perfectly on Linux btw).
#include <stdio.h>
#include <time.h>
int main ()
{
time_t filetime;
time_t presenttime;
struct tm * timeinfo;
time ( &filetime );
time ( &presenttime);
timeinfo = localtime ( &filetime );
timeinfo->tm_hour = 14; //this should be entered from file
timeinfo->tm_min = 15; //this should be entered from file
filetime = mktime ( timeinfo );
printf("my time %s\n",ctime(&filetime));
printf("pc time %s\n",ctime(&presenttime));
double difference = difftime(filetime, presenttime );
printf("%lf\n",(double)filetime);
printf("%lf\n",(double)presenttime);
if (difference > 300.0) {
// second is later than first
printf("later\n");
}
else if (difference < 0.0) {
// second is earlier than first
printf("earlier\n");
}
printf("%lf\n", difference);
return 0;
cheers for the help guys.
There is an example of making a time here. You can then compare the times with the difftime method.
If it were me, I'd be tempted to just save the result of time() to the file. That would save a whole lot of string parsing work on the other side.
I modified your code as follows and it does now what you were expecting:
struct tm time_from_file;
struct tm the_system_time;
time_t t_of_file;
time_t t_of_sys;
t_of_sys = time(NULL);
memcpy(&the_system_time,localtime(&t_of_sys),sizeof(struct tm));
t_of_file = time(NULL);
memcpy(&time_from_file,localtime(&t_of_sys),sizeof(struct tm));
time_from_file.tm_hour = 10; //should be read in from file
time_from_file.tm_min = 30; //should be read in from file
t_of_file = mktime(&time_from_file);
printf("%s\n",ctime(&t_of_file));
printf("%s\n",ctime(&t_of_sys));
double difference = difftime(t_of_file, t_of_sys );
printf("%lf\n",(double)t_of_file);
printf("%lf\n",(double)t_of_sys);
printf("%lf\n", difference);
What was wrong with your code:
You were using and modifying the pointer returned by localtime which happens to be same in both cases.
Consequently your pointers time_from_file and the_system_time were infact pointing to the same location.Any modification of one modifies the other as well and finally you have a difference of zero.
(Thanks gdb for helping me figure out that!!:D)
Paring your format is easy in C. Use this to read the time components from the file:
int hr, min;
fscanf (file, "%d:%d", &hr, &min);
Here is a complete solution:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
struct HrMin_ {
int hr;
int min;
};
typedef struct HrMin_ HrMin;
static const double TIME_DIFFERENCE = (double) (5 * 1000);
static HrMin read_time (FILE* file);
int
main (int argc, char **argv)
{
time_t sys_time_t = 0;
struct tm *sys_time = NULL;
struct tm *file_time = NULL;
double d = 0.0f;
if (argc != 2)
{
printf ("Usage: time_cmp <time_file>\n");
return 1;
}
time (&sys_time_t);
sys_time = localtime (&sys_time_t);
file_time = malloc (sizeof (struct tm));
file_time->tm_sec = sys_time->tm_sec;
file_time->tm_min = sys_time->tm_min;
file_time->tm_hour = sys_time->tm_hour;
file_time->tm_mday = sys_time->tm_mday;
file_time->tm_mon = sys_time->tm_mon;
file_time->tm_year = sys_time->tm_year;
file_time->tm_wday = sys_time->tm_wday;
file_time->tm_yday = sys_time->tm_yday;
file_time->tm_isdst = sys_time->tm_isdst;
FILE *file = fopen (argv[1], "r");
if (file == NULL)
{
printf ("Failed to open file: %s\n", argv[1]);
return 1;
}
HrMin hr_min = read_time (file);
fclose (file);
file_time->tm_hour = hr_min.hr;
file_time->tm_min = hr_min.min;
d = difftime (sys_time_t, mktime (file_time));
free (file_time);
if (d < 0) d *= -1;
printf ("Diff: %f\n", d);
if (d >= TIME_DIFFERENCE)
printf ("WARN!\n");
return 0;
}
static HrMin
read_time (FILE *file)
{
HrMin hr_min;
hr_min.hr = 0;
hr_min.min = 0;
fscanf (file, "%d:%d", &hr_min.hr, &hr_min.min);
return hr_min;
}