Time not printing on command line when compiled - c

I'm trying to run the below code. I'm compiling like so.
gcc -o time time.c
Instead of getting my desired output, the current time of day, hor minute, year, etc.
Today is : Thu Oct 31 02:01:37 2019
Time is : 02:01:37 am
Date is : 31/10/2019
I'm getting this instead. I've tried a variety of different time functions similar to this and I keep getting this below output instead of what I want.
real 0m0.000s
user 0m0.000s
sys 0m0.000s
I'm sure this is really simple, can anyone point me in the right direction?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Print current date and time in C
int main(void){
// variables to store date and time components
int hours, minutes, seconds, day, month, year;
// time_t is arithmetic time type
time_t now;
// Obtain current time
// time() returns the current time of the system as a time_t value
time(&now);
// Convert to local time format and print to stdout
printf("Today is : %s", ctime(&now));
// localtime converts a time_t value to calendar time and
// returns a pointer to a tm structure with its members
// filled with the corresponding values
struct tm *local = localtime(&now);
hours = local->tm_hour; // get hours since midnight (0-23)
minutes = local->tm_min; // get minutes passed after the hour (0-59)
seconds = local->tm_sec; // get seconds passed after minute (0-59)
day = local->tm_mday; // get day of month (1 to 31)
month = local->tm_mon + 1; // get month of year (0 to 11)
year = local->tm_year + 1900; // get year since 1900
// print local time
if (hours < 12) // before midday
printf("Time is : %02d:%02d:%02d am\n", hours, minutes, seconds);
else // after midday
printf("Time is : %02d:%02d:%02d pm\n", hours - 12, minutes, seconds);
// print current date
printf("Date is : %02d/%02d/%d\n", day, month, year);
return 0;
}

It seems to me you are calling the time command somehow, rather than your program.
Typically you will want to do:
./time
Instead of:
time

Related

Why does mktime give me an hour less?

I would like to see if at 00:00:00 on January 1, 1970 it actually corresponds to 0 seconds, and I wrote the following:
#include <stdio.h>
#include <time.h>
int main(void) {
int year = 1970;
struct tm t = {0};
t.tm_mday = 1; // January
t.tm_year = year - 1900;
t.tm_hour = 0;
t.tm_isdst = -1;
printf("%ld\n", mktime(&t));
return 0;
}
it gives me a value of -3600. Where am I wrong?
PS: tested with GCC v.10.1. I tried with another compiler under another architecture and it gives me back the correct value.
The time info you provide to mktime() is in local time, so the timezone matters even if summer time / daylight savings time does not.
You can fool your program by telling it you're in UTC:
$ gcc mytime.c -o mytime
$ ./mytime
28800 <-- Pacific time in the US
$ TZ=GMT0 ./mytime
0
The mktime function takes a time in local time. Apparently, 00:00:00 at your local time was one hour before the epoch. Launch the program with TZ set to UTC.
I would like to see if at 00:00:00 on January 1, 1970 it actually corresponds to 0 seconds, and I wrote the following:
00:00:00 on January 1, 1970 GMT, UTC corresponds to 0 seconds.
00:00:00 on January 1, 1970 Italia time corresponds to -3600 seconds.
Set timezone to UTC and then call mktime(). Unfortunately C does not have a portable way to do this, so the suggested code is only illustrative.
setenv("TZ", "UTC", 1);
tzset();
....
mktime(&t)
time_t does not necessarily match long. Recommend casting to a wide type.
// printf("%ld\n", mktime(&t));
printf("%lld\n", (long long) mktime(&t));
t.tm_mday = 1; // January misleads. .tm_mday is the day of the month, not January.
.tm_mon is the months since January so the initialization to 0 matches January.
Concerns about DST apply here only if the local time was using DST in January.
As other answers indicate, mktime works in your local time zone. However, many operating systems offer a related function timegm that works in UTC. This slight modification of your program prints 0, as expected, on my computer:
#include <stdio.h>
#include <time.h>
int main(void)
{
int year = 1970;
struct tm t = {0};
t.tm_mday = 1; // January
t.tm_year = year - 1900;
t.tm_hour = 0;
t.tm_isdst = -1;
printf("%ld\n", timegm(&t));
return 0;
}
Regrettably, this function is not standardized. You may have to define a special "feature selection macro" to get your time.h to declare it.

How to print a future time from system time in C. Such as if it is 10 am now, to print 12 am instead

I am currently learning C programming and i am trying to out put a time for the next scheduled flight of a mock airport. i though i could use the system time, then have that be modified so it out puts which ever time is 3 hours from that moment. However, i could only find solutions to out put the current time on the system. Any help would be appreciated.
I've tried a few different methods I've seen others do, but have had no luck in modifying them as of yet. I am still very new to C programming, so i cant read many of these functions, and due to that cannot find where in them to edit or change out in order to achieve the desired result.
#include<stdio.h>
#include<time.h>
int main(){
time_t t;
time(&t);
printf("\n right now the time is: %s",ctime(&t));
}
this outputs to "Mon Aug 12 10:00:17 2019"
my end goal is something similar to "12:00 pm" if the current time is 10 am
In t the seconds since the unix epoch (1970-01-01 00:00 UTC) is stored.
So you can simply add 3h = 3600*3 = 10800 to it:
time_t t;
time(&t);
t += 10800;
printf("\n In 3 hours the time is: %s",ctime(&t));
Since flights are every 3 hours, I take be modified so it out puts which ever time is 3 hours from that moment. to mean up to 3 hours from the current moment.
If so,
1) Avoid making the non-portable assumption the time_t is in seconds.
2) Convert to local time, do the math on the .tm_hour member.
time_t t;
if (time(&t) == -1) Handle_invalid_time();
printf("Right now the time is: %s",ctime(&t));
struct tm *tm = localtime(&t);
if (tm == NULL) Handle_invalid_conversion();
tm->tm_hour += 3;
tm->tm_min = 0;
tm->tm_sec = 0;
// re-adjust members to their usual range (Handle going into next, day, month, year)
mktime(tm);
printf("Flight time: %s", asctime(tm));

Formatted elapsed time in C

I'm writing a function that, among other things, must print out an elapsed time counter. It receives by reference a start time _start, and compares it to current, both typed as time_t. I want to use strftime() to print out the observed time delta in ISO 8601 format. Here's what I attempted to do:
// Negative start time implies program has not begun
if (*_start > 0) {
time_t elapsed = current - *_start;
strftime(time_str, sizeof(time_str) - 1, "%T", localtime(&elapsed));
printf("%s\n", time_str);
}
And here is the output I get immediately after running the program
01:00:00
01:00:00
01:00:01
01:00:01
01:00:01
The seconds work fine, if I let it run longer they get incremented as expected, so do the minutes, however the hour starts as 01 as opposed to 00. Why is this happening? How can I get the hours to start zeroed, like the minutes?
time_t typically (see edit) stores absolute timestamps (the number of seconds since midnight UTC, January 1, 1970). By calculating current - *_start, you're getting elapsed time in seconds (as desired), but by then passing that to localtime and strftime, you're telling the computer to take the time elapsed since the start of your program and treat it as the time elapsed since midnight UTC 1-1-1970.
I'm guessing that happens to be 01:00:00 in your system's local time zone.
I'm not aware of a C99 function to print elapsed time, but it's not hard to write one yourself.
void format_elapsed_time(char *time_str, int total_seconds_elapsed) {
int hours_elapsed = total_seconds_elapsed / 3600;
int minutes_elapsed = (total_seconds_elapsed % 3600) / 60;
int seconds_elapsed = total_seconds_elapsed % 60;
sprintf(time_str, "%02i:%02i:%02i", hours_elapsed, minutes_elapsed, seconds_elapsed);
}
Edit: As #chux points out, time_t doesn't have to store timestamps as seconds since 1-1-1970. See this answer for details.
To portably find the number of elapsed seconds between 2 time_t, use difftime() as subtracting 2 time_t values is not specified in C to be a difference in seconds.
double difftime(time_t time1, time_t time0); C11dr ยง7.26.2.2
The difftime function returns the difference expressed in seconds as a double.
double elapsed_seconds = difftime(current, *_start);
printf("elapsed_seconds: %f\n", elapsed_seconds);
If you want to use this method, you should be aware that time() returns UTC. If you then subtract that from your local time (as returned by localtime()), time zones will have an effect on the result (it's likely your particular time zone is removed from UTC by one hour).
Consider the following complete program, similar to your snippet:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main(void) {
time_t start = time(0);
char time_str[100];
for (int i = 5; i > 0; i--) {
sleep (1);
time_t elapsed = time(0) - start;
strftime(time_str, sizeof(time_str) - 1, "%T", localtime(&elapsed));
printf("%s\n", time_str);
}
return 0;
}
Also consider that my particular time zone is removed from UTC by eight hours:
pax> date ; date -u
Thursday 30 March 10:25:57 AWST 2017
Thursday 30 March 02:25:57 UTC 2017
When I run it, I see:
08:00:01
08:00:02
08:00:03
08:00:04
08:00:05
You can see there that the eight-hour time difference from UTC affects the value. The fix for that is actually quite simple: don't use local time at all. If you replace the localtime() call with gmtime(), you get the output you expect:
00:00:01
00:00:02
00:00:03
00:00:04
00:00:05
I realize this question already has an answer, but I thought I might shift the focus a little and expand on the accepted answer. Since the OP specified that they are dealing with elapsed times, one can avoid dealing with absolute timestamps altogether using the clock() function.
clock_t start = clock();
.
.
clock_t end = clock();
double elapsed = (end - start) / (double)CLOCKS_PER_SEC;
then you can call the notionally revised format_elapsed_time() function, like so:
void format_elapsed_time(char *time_str, double elapsed) {
int h, m, s, ms;
h = m = s = ms = 0;
ms = elapsed * 1000; // promote the fractional part to milliseconds
h = ms / 3600000;
ms -= (h * 3600000);
m = ms / 60000;
ms -= (m * 60000);
s = ms / 1000;
ms -= (s * 1000);
sprintf(time_str, "%02i:%02i:%02i.%03i", h, m, s, ms);
}

How many seconds between now and a specific time in C

I need to be able to count the seconds between now and a specific time (like the next time it's 3pm). I saw some similar questions but I wasn't able to use any of these.
C standard library has two representation of time: time_t is a seconds since Unix Epoch and struct tm where you can individially set seconds, minutes, etc.
So to get next moment in time when wall clock will show 3 p.m. you'll need take current time in seconds time(NULL), convert it to struct tm, advance time to 3 p.m. by setting structure fields, convert it back to time_t and calculate the difference:
#include <time.h>
#include <string.h>
#include <stdio.h>
int main() {
time_t now, next3pm;
struct tm threepm;
// Get current time (now)
now = time(NULL);
// Copy current date to a `threepm`, and set time
memcpy(&threepm, gmtime(&now), sizeof(struct tm));
if(threepm.tm_hour > 15) {
// Advance to a next day
++threepm.tm_mday;
}
threepm.tm_hour = 15;
threepm.tm_min = threepm.tm_sec = 0;
printf("%.f seconds till 3:00 PM\n", difftime(mktime(&threepm), now));
return 0;
}
I used UTC conversion functions gmtime()/mktime(). Since there is no timezoned version of mktime() you may need to convert time on your own. Using UTC time may cause trouble with advancing to a next day when it shouldn't do that (because it is already 15:00 according to UTC, but not yet 15:00 according to a local time).
Or, a classic joke version:
int main() {
time_t t;
struct tm* tm;
do {
t = time(NULL);
tm = gmtime(&t);
usleep(1000000);
} while(tm->tm_hour != 15 && tm->tm_min != 0);
puts("0 seconds till 3:00 PM");
}

converting milliseconds to date in C

Is there any way of converting milliseconds to date in C?
What I am trying to do is write a small application in C that can return the financial year and the like(quarter, week) given the start month and isCurentYear bool, where the input might be milliseconds or a date!
In the first place, is there any way by which this can be achieved in C?
And if so, in the process of finding out a way of converting milliseconds to date
I have found out that the use of time_t takes the current millis of our system and by creating a structure pointing to it,it permits us to extract the year,month, date, sec etc!
Refer the below code:
#include <sys/time.h>
#include<stdio.h>
#include<time.h>
void main()
{
time_t t = time(000);
//time_t t = time(0);
struct tm tm = *localtime(&t);
printf("now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
And also, can time_t be used to store millisecond values so that it can be converted to date using tm struct?
Function time_t time(time_t* timer) returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC. In addition, if the input argument timer != NULL, then the function also sets this argument to the same value (so you probably have no reason to call it with anything else but NULL).
Function struct tm* localtime(const time_t* timer) takes the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC, and returns a structure that represents the equivalent time & date. If you're working on a multi-threaded application, then please note that this function is not thread safe.
As to your question - is there any way for converting milliseconds to time & date - yes, but:
Take into consideration that the milliseconds will be considered as of 00:00 hours, Jan 1, 1970 UTC.
Since the time_t type is 32-bit long, you will not be able to convert 4G*1000 milliseconds or more.
Here is a function for converting milliseconds to time & date:
struct tm* GetTimeAndDate(unsigned long long milliseconds)
{
time_t seconds = (time_t)(milliseconds/1000);
if ((unsigned long long)seconds*1000 == milliseconds)
return localtime(&seconds);
return NULL; // milliseconds >= 4G*1000
}
For those of us who were searching the web for an answer to apply to embedded c applications, think pic 32 programming here is the mathematical calculation:
Date in Epoch_seconds = ( (epoch_seconds / 1000) / 86400 ) + 25569
Resulting in a 5 digit answer which is 10 bits long format dd/MM/yyyy
(Note: the slashes are encoded in the result here so when converting to human readable date please account for it)
Where one day = 86400 ms
and the date 1970/1/1 = 25569
example:=( (1510827144853/1000) / 86400 ) + 25569 = 43055
put 43055 in excel and format cell to date dd/MM/yyyy and it gives you 16/11/2017
Perhaps, you are looking for strftime function.
char text[100];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(text, sizeof(text)-1, "%d %m %Y %H:%M", t);
printf("Current Date: %s", text);

Resources