How do i convert seconds into days in C? - c

I'm a bit lost, how can I convert the output of sys_inf.uptime (seconds) into days?
#include <stdio.h>
#include <sys/sysinfo.h>
int main(void) {
struct sysinfo sys_inf; // for system information
sysinfo(&sys_inf); // to get system information
int days = sys_inf.uptime;
float totalDays = days / 86400;
printf("Latest reboot was : %.2ld seconds ago (%.2f)", sys_inf.uptime, totalDays);
return 0;
}

You're doing integer division here:
int days = sys_inf.uptime;
float totalDays = days / 86400;
Add .0 to make it a floating point division:
int days = sys_inf.uptime;
float totalDays = days / 86400.0;

Related

How to add two 24hour times

Hi pretty new to coding in c, but would love your help in my following coding problem.
I want to add two times (that are in twenty four hour time notation already).
Currently they are both integers and the arithmatic addition function is great for whole hour (e.g. 800+1000), however because our / computer's numbers are base ten, it will not roll over to the next hour after 60min which leads to problems with addition.
I'm not sure if the modulus % can solve this? Ideally I would like to use simple c coding (that I understand), and not start importing timing keys into the program.
e.g.
#include <stdio.h>
int main (void)
{
int time1 = 1045; // 10:45am in 24hour time
printf("Time %d ",time1);
int time2 = 930; //9 hours & 30min
printf("+ time %d", time2);
int calc = time1 + time2;
printf(" should not equal ... %d\n", calc);
printf("\nInstead they should add to %d\n\n", 2015); //8:15pm in 24hr time
return 0;
}
Yes, you're correct that modulo division is involved. Remember, that is remainder division. This is more worthy as a comment since supplying a complete answer for problems like this is generally frowned upon, but it's too long for that; this should get you started:
#include <stdio.h>
int main(void)
{
// Assuming the given time has the format hhmm or hmm.
// This program would be much more useful if these were
// gathered as command line arguments
int time1 = 1045;
int time2 = 930;
// integer division by 100 gives you the hours based on the
// assumption that the 1's and 10's place will always be
// the minutes
int time1Hours = time1 / 100; // time1Hours == 10
int time2Hours = time2 / 100; // time2Hours == 9
// modulus division by 100 gives the remainder of integer division,
// which in this case gives us the minutes
int time1Min = time1 % 100; // time1Min == 45
int time2Min = time2 % 100; // time2Min == 30
// now, add them up
int totalHours = time1Hours + time2Hours; // totalHours = 19
int totalMin = time1Min + time2Min; // totalMin = 75
// The rest is omitted for you to finish
// If our total minutes exceed 60 (in this case they do), we
// need to adjust both the total hours and the total minutes
// Clearly, there is 1 hour and 15 min in 75 min. How can you
// pull 1 hour and 15 min from 75 min using integer and modulo
// (remainder) division, given there are 60 min in an hour?
// this problem could be taken further by adding days, weeks,
// years (leap years become more complicated), centuries, etc.
return 0;
}
I used this for a long time...
// convert both times hhmm to minutes an sum minutes
// be sure to do integer division
int time1m = ((time1 / 100) * 60)+(time1 % 100);
int time2m = ((time2 / 100) * 60)+(time2 % 100);
int sumMin = time1m + time2m;
// convert back to hhmm
int hhmm = ((sumMin / 60) * 100)+(sumMin % 60);
You can also include a day, as time is of 24 hour format.
#include <stdio.h>
int main()
{
int t1=2330;
int t2=2340;
int sum=((t1/100)*60)+(t1%100)+((t2/100)*60)+(t2%100);
int day=sum/(24*60);
sum = sum % (24*60);
int hours=sum/(60);
int mins=sum % 60;
printf("days = %d \t hours = %d \t mins=%d\n",day, hours, mins);
return 0;
}

calculate how many days before a unix process time overflows

I'm working through an example for Advanced Programming in the Unix Environment and the following questions was asked:
If the process time is stored as a 32bit signed integer, and the system counts 100 ticks per second, after how many days will the value overflow?
void proc_ovf()
{
int sec = 60;
int min = 60;
int hour = 24;
int tick = 100;
int epoch_time = (((INT_MAX / (sec * tick)) / min) / hour);
struct tm * timeinfo;
time_t epoch_time_as_proc_t = epoch_time;
timeinfo = localtime(&epoch_time_as_proc_t);
printf("3] overflow date of proc: %s", asctime(timeinfo));
}
Is the following solution a reasonable calculation for how many days before overflow?
(((INT_MAX / (sec * tick)) / min) / hour)
This calculation yielded 248 days.
248 days looks good.
But your code doesn't. Your variables have the wrong names. They should be:
int ticks_per_second = 100;
int seconds_per_minute = 60;
int minutes_per_hour = 60;
int hours_per_day = 24;
int ticks = INT_MAX;
int seconds = ticks / ticks_per_second;
int minutes = seconds / seconds_per_minute;
int hours = minutes / minutes_per_hour;
int days = hours / hours_per_day;
printf("overflow after %d days\n", days);
The above code takes care of mentioning the measurement units. Can you see how nicely the measurement units cancel out in each line of the second part of the code?

Calculate datetime difference in C

I need a function that can calculate the difference between two datetime (year, month, day, hours, minute, seconds). and then return the difference in the same format.
int main (){
struct datetime dt_from;
init_datetime(&dt_from, 1995, 9, 15, 10, 40, 15);
struct datetime dt_to;
init_datetime(&dt_to, 2004, 6, 15, 10, 40, 20);
struct datetime dt_res;
datetime_diff(&dt_from, &dt_to, &dt_res);
return 0;
}
void datetime_diff(struct datetime *dt_from, struct datetime *dt_to
, struct datetime *dt_res) {
//What can I do here to calculate the difference, and get it in the dt_res?
}
Please have a look and try this example which uses time.h and should be portable. It calculates the difference in days between the dates in your question. You can change the program a little so that it works the way you want.
#include <stdio.h>
#include <time.h>
#include <math.h>
int main() {
time_t start_daylight, start_standard, end_daylight, end_standard;;
struct tm start_date = {0};
struct tm end_date = {0};
double diff;
printf("Start date: ");
scanf("%d %d %d", &start_date.tm_mday, &start_date.tm_mon, &start_date.tm_year);
printf("End date: ");
scanf("%d %d %d", &end_date.tm_mday, &end_date.tm_mon, &end_date.tm_year);
/* first with standard time */
start_date.tm_isdst = 0;
end_date.tm_isdst = 0;
start_standard = mktime(&start_date);
end_standard = mktime(&end_date);
diff = difftime(end_standard, start_standard);
printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));
/* now with daylight time */
start_date.tm_isdst = 1;
end_date.tm_isdst = 1;
start_daylight = mktime(&start_date);
end_daylight = mktime(&end_date);
diff = difftime(end_daylight, start_daylight);
printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));
return 0;
}
Test
Start date: 15 9 1995
End date: 15 6 2004
3195 days difference
Or even simpler for non-interactive code and with standard or daylight savings time:
#include <stdio.h>
#include <time.h>
#include <math.h>
int main()
{
time_t start_daylight, start_standard, end_daylight, end_standard;;
struct tm start_date = {0};
struct tm end_date = {0};
double diff;
start_date.tm_year = 1995;
start_date.tm_mon = 9;
start_date.tm_mday = 15;
start_date.tm_hour = 10;
start_date.tm_min = 40;
start_date.tm_sec = 15;
end_date.tm_mday = 15;
end_date.tm_mon = 6;
end_date.tm_year = 2004;
end_date.tm_hour = 10;
end_date.tm_min = 40;
end_date.tm_sec = 20;
/* first with standard time */
start_date.tm_isdst = 0;
end_date.tm_isdst = 0;
start_standard = mktime(&start_date);
end_standard = mktime(&end_date);
diff = difftime(end_standard, start_standard);
printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));
/* now with daylight time */
start_date.tm_isdst = 1;
end_date.tm_isdst = 1;
start_daylight = mktime(&start_date);
end_daylight = mktime(&end_date);
diff = difftime(end_daylight, start_daylight);
printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));
return 0;
}
Here is the basic idea:
Convert your datetime into an integral type (preferable long long or unsigned long long) which represents your datetime value as it's smallest unit (second in your case). How to achieve that? Easy transform the single values into seconds and add everything together. (seconds + minutes * 60 + hours * 3600 ...)
Do this for both values and then subtract the integer values.
Now convert the single integer value, the time difference, back to a datetime. How? Start with the biggest unit (years) and divide the difference by the amount of seconds within one year (60 * 60 * 24 * 365). Now you know how many years are in between your two datetimes. Take the rest and divide it by the amount of seconds per month, and so on...
(Obviously I ignored everything rather complicated, like daylight saving time for example)
However I would highly recommend using struct tm from time.h as mentioned in the comments. It is portable and you can use difftime.

Calculate the difference between two times on two different days

I am trying to determine the time difference between two times, which i represent as unsigned integers (in a sturct) as follows:
unsigned int day;
unsigned int month;
unsigned int year;
unsigned int hour;
unsigned int mins;
unsigned int seconds;
i can work out the time difference in minutes between two times that occur on the same day easily enough using: This isn't my exact code, this is just the logic behind it.
time1 = hours*3600 + mins*60 + seconds;
time1 = hours2*3600 + mins2*60 + seconds2;
//time2 will always be less than time1
time_diff_secs = time1_secs - time2_secs;
time_diff_mins = time_diff_secs / 60;
time_diff_secs = time_diff_secs % 60;
this produces this output:
Time mayday was issued: 13 Hours 4 Mins 0 Seconds
Time mayday was recieved: 13 Hours 10 Mins 0 Seconds
Time between sending and receiving: 6.00Mins
which is correct, but when I have two times that are on different days I get this as the result:
Time mayday was issued: 23 Hours 0 Mins 0 Seconds
Time mayday was recieved: 0 Hours 39 Mins 38 Seconds
Time between sending and receiving: 71581448.00Mins
This is obviously incorrect, I am not sure how to progress from here, the actual result should be 40mins, not 71.5million.
Another way to do it using the standard C library, the only advantage of this is you do not have to worry about your dates overlapping years, or problems with overlapping month boundaries + leap year nonsense:
unsigned int day;
unsigned int month;
unsigned int year;
unsigned int hour;
unsigned int mins;
unsigned int seconds;
time_t conv(void)
{
time_t retval=0;
struct tm tm;
tm.tm_mday=day;
tm.tm_mon=month -1;
tm.tm_year=year - 1900;
tm.tm_hour=hour;
tm.tm_min=mins;
tm.tm_sec=seconds;
tm.tm_isdst=-1;
retval=mktime(&tm);
return retval;
}
int main()
{
time_t start=0;
time_t end=0;
time_t diff=0;
// assign day, month, year ... for date1
start=conv();
// assign day, month, year ... for date2
end=conv();
if(start>end)
diff=start - end;
else
diff=end - start;
printf("seconds difference = %ld\n", diff);
return 0;
}
You are getting an underflow. Try this (works regardless of whether the variables are signed or unsigned):
if (time1_secs < time2_secs) {
// New day. Add 24 hours:
time_diff_secs = 24*60*60 + time1_secs - time2_secs;
} else {
time_diff_secs = time1_secs - time2_secs;
}
time_diff_mins = time_diff_secs / 60;
time_diff_secs = time_diff_secs % 60;
Change
time_diff_secs = time1_secs - time2_secs;
to
time_diff_secs = abs(time1_secs - time2_secs) % 86400;
This will force it to be the minimum time difference between both times and will work even if you add days, months, etcetera to the time_diff_secs calculation.

Calculate minutes until specific time? (C)

What's the simplest way to calculate the number of minutes until 9pm (being today or tomorrow)?
Was looking over mktime() but seemed a hassle to get the day # and month, dealing with all that.
Just calculate the delta to today's 9pm. If it's negative, add 24hrs to get the delta to tomorrow's 9pm.
#include <stdio.h>
#include <time.h>
int main(int argc, char* argv[]) {
struct tm* tm;
time_t ts=time(NULL);
if(tm=localtime(&ts)) {
long int delta;
tm->tm_hour = 21;
tm->tm_min = 0;
tm->tm_sec = 0;
delta = mktime(tm) - ts;
if(delta<0) {
delta+=24*60*60;
}
printf("%d minutes til (next)9pm\n",delta/60);
}
return 0;
}
This will give you the minutes until 9pm.:
time_t currenttime;
time_t ninePM;
struct tm * timeinfo;
int minutesUntilNine;
// Fill currenttime + convert to struct tm
time ( &currenttime );
timeinfo = localtime ( &rawtime );
// Check for after 9pm...
if (timeinfo->tm_hour >= 21) // Are we after 9pm?
timeinfo->tm_day++; // increment our day
// Set timeinfo to the time you want...
timeinfo->tm_sec = 0;
timeinfo->tm_min = 0;
timeinfo->tm_hour = 21; // 9pm
ninePM = mktime( timeinfo );
minutesUntilNine = (ninePM - currenttime) / 60;
A simple way is to calculate the number of hours and minutes (given what the time is now, plus the fact that there are 24 hours in a day), and multiply the number of hours by 60 to make it a number of minutes. Alternatively, instead of using a 24-hour clock to express the time, use a 1440 minute clock: it's easy to subtract one time from another, to get a time difference.
Here it is (output in seconds...)
#include <stdio.h>
#include <time.h>
int main(void)
{
double dt = 0.0f;
time_t ti = time(NULL);
time_t tf;
struct tm *pt_actual = localtime(&ti);
struct tm t_actual = *pt_actual;
struct tm t_target = *pt_actual;
t_target.tm_hour = 21; // 09:00 pm
t_target.tm_min = 0;
tf = mktime(&t_target);
dt = difftime(tf, ti);
if (dt < 0)
dt += (24*60*60); // if negative, just consider **next** 9pm target, add a day
printf("difftime = %f seconds\n", dt );
return 0;
}
The guy's asking for the simplest way. All your ways are unnecessarily complex. Just use modular arithmetic:
#include <stdio.h>
#include <time.h>
#define TARGET_TIME 21*60 // 9:00 PM, in format HH * 60 + MM
int main(int argc, char* argv[])
{
struct tm* tm;
time_t ts = time(NULL);
int minutes_until_9pm;
tm = localtime(&ts);
minutes_until_9pm = 24*60 - (tm->tm_min + tm->tm_hour * 60 + TARGET_TIME)%(24*60);
//alternatively, the following is slightly faster
//minutes_until_9pm = 24*60 - (tm->tm_min + tm->tm_hour * 60 + TARGET_TIME) + (tm->tm_min+tm->tm_hour*60+TARGET_TIME>24*60?24*60:0);
printf("%d minutes til (next)9pm\n", minutes_until_9pm);
return 0;
}
If you know your timezone , it all becomes even simpler:
#include <stdio.h>
#include <time.h>
#define TARGET_TIME 21*60 // 9:00 PM, in format HH * 60 + MM
#define TIMEZONE (-6) // This is CST; replace with your own timezone
int main(int argc, char* argv[])
{
int minutes_until_9pm = 24*60 - (time(NULL)/60 + TARGET_TIME + (24+TIMEZONE)*60)%(24*60);
printf("%d minutes til (next)9pm\n", minutes_until_9pm);
return 0;
}
What's going on here is that, modulo one day, we're getting number of minutes since midnight. Then we're adding 9:00 PM to get the the number of minutes since 9:00 PM. Then we're subtracting that from 24 hours to get the number of minutes until the next 9:00 PM.
If you need higher accuracy (i.e. rounded to the nearest number of minutes, rather than simply number of minutes), simply subtract (tm->tm_sec>=30?0:1) from minutes_until_9pm, or replace time(NULL)/60 with (time(NULL)+30)/60, respectively.
C99 version:
#include <math.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
struct tm now = *localtime(&(time_t){ time(NULL) });
struct tm then = now;
then.tm_hour = 21;
then.tm_min = 0;
then.tm_sec = 0;
int dt = ((int)round(
difftime(mktime(&then), mktime(&now)) / 60) + 24 * 60) % (24 * 60);
printf("time till 9pm: %i minutes\n", dt);
}
The more profound, if less helpful, answer is that there is no simple answer.
How do you even know that today will have a 9pm? OK, sure, I'm sure all the time zones that exist never skip 21:00, but they skip hours in the middle of the night once a year.
Calendrics is a disaster of complexity. Beware.

Resources