Need to get Saturdays date of the week in linux C - c

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.

Related

How do i compare dates using difftime()?

#include <stdio.h>
#include <time.h>
int date_txt[5],today_date;
scanf("%d",&today_date); //i enter (input) the date manually e.g. 20171109
date_txt[0]=20161102; // year month day form (rrrrmmdd)
date_txt[1]=20150101;
date_txt[2]=20170615;
date_txt[3]=20160628;
date_txt[4]=20150101;
I have several dates which i need to compare with today_date to see if the difference is equal to or greater than 1 year. I have found that there exists a function for this called difftime(), but as i am a novice i do not know how to exactly do this. Any help is appreciated, thank you.
You can do something like this:
#include <stdio.h>
#include <time.h>
#define COUNT 5
#define SECONDS_NON_LEAP_YEAR (365*24*3600)
#define SECONDS_LEAP_YEAR (366*24*3600)
typedef struct tm T_TIME;
T_TIME dToday, dTemp;
void convertToTime(int iDate, T_TIME* tTime)
{
tTime->tm_mday = iDate%100;
iDate/=100;
tTime->tm_mon = (iDate%100)-1;
iDate/=100;
tTime->tm_year = iDate-1900;
}
int isLeapYear(int yyyy)
{
if(yyyy%100) // Not a century
{
return !(yyyy%4);
}
return !(yyyy%400);
}
int main(void) {
int date_txt[]={20161102, 20150101, 20170615, 20160628, 20150101};
int today_date, i, flg, isThisYearLeap, tSeconds;
scanf("%d",&today_date); //i enter (input) the date manually e.g. 20171109 year month day form (rrrrmmdd)
convertToTime(today_date, &dToday);
isThisYearLeap = isLeapYear(dToday.tm_year+1900);
for(i=0;i<COUNT; i++)
{
convertToTime(date_txt[i], &dTemp);
tSeconds = difftime(mktime(&dToday), mktime(&dTemp));
flg = (isThisYearLeap || isLeapYear(dTemp.tm_year+1900)) ?
(tSeconds >= SECONDS_LEAP_YEAR) : (tSeconds >= SECONDS_NON_LEAP_YEAR);
printf("The difference between Today and date %d is %s 1 year.\n", date_txt[i],
(flg ? "Greater than or equals to" : "Less than"));
}
return 0;
}
See it in execution here

How to use the date and time that i get from time.h function

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(&current_time);
time_info = localtime(&current_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

Convert a human readable Date to a GMT date

I have a human readable date which is in local time. I need to convert this human readable time to a GMT time in a human readable form.
The human readable date I have is 30th March 2014 02:59.
When I convert the time to GMT I'm expecting the time to be 01:59 on the 30th but my conversion still comes out as 2:59.
I believe the only way to do the conversion is to convert the human time to an epoch and then convert this back to gmtime but doing this I still get 2:59.
Below is the code I am using:
struct tm t;
struct tm *gmtTimeStruct;
time_t t_of_day;
int year = atoi(date);
int month = atoi(date+5);
int day = atoi(date+8);
int hour = atoi(time);
int minutes = atoi(time+3);
char * gmtHumanTime = NULL;
printf("Year: %i Month: %i Day: %i Hour: %i Minutes: %i\n", year, month, day, hour, minutes);
t.tm_year = year - 1900;
t.tm_mon = month - 1;
t.tm_mday = day;
t.tm_hour = hour;
t.tm_min = minutes;
t.tm_sec = 59;
t.tm_isdst = 0;
t_of_day = mktime(&t);
printf("Epoch time: %ld\n", t_of_day);
gmtTimeStruct = gmtime(&t_of_day);
asprintf(&gmtHumanTime, "%s:%s", gmtTimeStruct->tm_hour, gmtTimeStruct->tm_min);
printf("GMT Human Time: %s", gmtHumanTime);
UPDATE 1
I've also tried change the t.tm_isdst flag from 0,1 and -1 to see if anything changes and it doesn't seem to. I know mktime has an issue with this flag as it can't always work out whether the time needs ammending due to DST or not but I'm not sure if timegm has the same issue.
Here's your problem:
The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.
By setting t.tm_isdst = 0; in your code, you are explicitly specifying that there is no daylight saving in effect. You should have provided a negative value.
Reference: http://www.cplusplus.com/reference/ctime/tm/
(Also, shouldn't the format string near the bottom be "%d:%02d"instead of "%s:%s"?)
EDIT
Sorry, I didn't notice you'd tried different values of tm_isdst. Perhaps it would help if you simplified your code a bit. This works perfectly on my system:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
struct tm t, *gmtTimeStruct, *localTimeStruct;
time_t t_of_day;
char *gmtHumanTime, *localHumanTime;
t.tm_year = 2014 - 1900;
t.tm_mon = 3 - 1;
t.tm_mday = 30;
t.tm_hour = 2;
t.tm_min = 59;
t.tm_sec = 59;
t.tm_isdst = -1;
t_of_day = mktime(&t);
gmtTimeStruct = gmtime(&t_of_day);
asprintf(&gmtHumanTime, "%d:%d", gmtTimeStruct->tm_hour, gmtTimeStruct->tm_min);
printf("GMT Human Time: %s\n", gmtHumanTime);
localTimeStruct = localtime(&t_of_day);
asprintf(&localHumanTime, "%d:%d", localTimeStruct->tm_hour, localTimeStruct->tm_min);
printf("Local Human Time: %s\n", localHumanTime);
return 0;
}
Output:
GMT Human Time: 1:59
Local Human Time: 2:59
Try compiling this on your system and see what you get. (Perhaps there is something wrong with your system's time zone setting?)

Printing out current date

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;
}

calculating time in C - AIX machine

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

Resources