I can get the system time using struct tm and time(),localtime(),asctime().but i need help about how i can set time of system using c program.
if you don't want to execute a shell command you can (as you mentioned) use the settimeofday, i would start by reading the MAN page, or looking for some examples
here's an example:
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
struct timeval now;
int rc;
now.tv_sec=866208142;
now.tv_usec=290944;
rc=settimeofday(&now, NULL);
if(rc==0) {
printf("settimeofday() successful.\n");
}
else {
printf("settimeofday() failed, "
"errno = %d\n",errno);
return -1;
}
return 0;
}
Shamelessly ripped From IBMs documentation, the struct timeval struct holds the number of seconds (as a long) plus the number of microseconds (as a long) from 1 January 1970, 00:00:00 UTC (Unix Epoch time). So you will need to calculate these numbers in order to set the time. you can use these helper functions, to better handle dealing with the timeval struct.
Related
I've been trying to time how long it takes for an invocation of popen to complete. popen initializes a process which then creates a pipe, forks, and invokes the shell. In my particular case, I'm using the call to read another programs stdout output.
The problem: I'm expecting the call I make to return the correct length of time it took the program to execute (around 15 seconds for a test program). What I get is that the program took no time at all to finish (0.000223s). Despite all the various functions I have tried, I seem unable to time the call correctly.
Here is a reproducible example of my problem. It is composed of the timing program and a child program that the timing program runs (the child takes about 15s to run on my system):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#define MAXBUF 10
static void gettime (struct timespec *t) {
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
t->tv_sec = mts.tv_sec;
t->tv_nsec = mts.tv_nsec;
#else
clock_gettime(CLOCK_REALTIME, t);
#endif
}
int main (void) {
FILE *fp;
struct timespec tic, toc;
char *executableName = "./a.out";
char answer[MAXBUF];
gettime(&tic);
if ((fp = popen(executableName, "r")) == NULL) {
fprintf(stderr, "The file couldn't be opened.\n");
return 1;
}
gettime(&toc);
fgets(answer, MAXBUF, fp);
double elapsed = (double)(toc.tv_nsec - tic.tv_nsec) / 1E9;
fprintf(stdout, "The program says %s, and took %fs to run!\n", answer, elapsed);
pclose(fp);
return 0;
}
Here is the child program:
#include <stdio.h>
#include <stdlib.h>
int timeWastingFunction (long long n) {
if ((n % 2) == 0) {
return 1;
}
for (int i = 1; i < (n / 2); i += 2) {
if ((n % i) == 0) {
return 1;
}
}
return 0;
}
int main (void) {
int start = 687217000;
while (start--) {
timeWastingFunction(start);
}
fprintf(stdout, "Hello!");
return 0;
}
This might look a bit overdone, but I had previously tried using clock_t, (a CPU based timing facility) to do the timing, and gotten the same answers from it. I therefore tried this solution which you see above. I picked: CLOCK_REALTIME as it seemed appropriate for the job. I unfortunately don't have the option to specify if this clock is on a per-process or per-thread level though (I'd want it to be process independent).
Note: I haven't tried using gettimeofday yet, but I don't want to since its apparently inappropriate for timing this way, dependent on the date of the system using it, and being phased out in favor of clock_gettime.
Edit: Just to be clear, what happens when I run this is that the program calling popen will actually stall for the 15 seconds the other program takes to run, before printing the 'wrong' time. It doesn't immediately print the time implying it didn't wait for the call to complete.
popen() only fork and open a pipe. Your test only show the time that take popen() to create the child and the pipe.
A simple way to solve your problem is to get the time after your pclose(), note that will be not perfect because when you read the data return by your child, it could finish before your call to pclose()
Plus your solution to get the result is broken, you only make the difference between nanosecond, I found a solution on git:
void timespec_diff(struct timespec *start, struct timespec *stop,
struct timespec *result)
{
if ((stop->tv_nsec - start->tv_nsec) < 0) {
result->tv_sec = stop->tv_sec - start->tv_sec - 1;
result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000;
} else {
result->tv_sec = stop->tv_sec - start->tv_sec;
result->tv_nsec = stop->tv_nsec - start->tv_nsec;
}
return;
}
The last thing is that CLOCK_REALTIME should be used if you want the date. Here you just want a duration. So you should use CLOCK_MONOTONIC if it's available on your system because CLOCK_REALTIME can rollback. (REALTIME_CLOCK of host_get_clock_service() seam monotonic too).
CLOCK_MONOTONIC: Clock that cannot be set and represents monotonic time since some unspecified starting point.
REALTIME_CLOCK: A moderate resolution clock service that (typically) tracks time since the system last boot.
So the working code could look like that:
int main (void) {
FILE *fp;
struct timespec tic, toc;
char *executableName = "./a.out";
char answer[MAXBUF];
gettime(&tic);
if ((fp = popen(executableName, "r")) == NULL) {
fprintf(stderr, "The file couldn't be opened.\n");
return 1;
}
fgets(answer, MAXBUF, fp);
pclose(fp);
gettime(&toc);
struct timespec result;
timespec_diff(&tic, &toc, &result);
fprintf(stdout, "The program says %s, and took %lld.%.9lds\n", answer, (long long)result.tv_sec, result.tv_nsec);
return 0;
}
Credit:
How to subtract two struct timespec?
How to print struct timespec?
I have written the following code to convert date to timestamp.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main()
{
struct tm date_time;
char date_time_buf[255];
char date_time_hdr[255]={0};
strncpy(date_time_hdr,"Thu, 02 Mar 2017 05:54:28 GMT",255);
memset(&date_time, 0, sizeof(struct tm));
strptime(date_time_hdr, "%a, %d %b %Y %H:%M:%S %Z", &date_time);
memset(date_time_buf, 0, 255);
strftime(date_time_buf, 255, "%s", &date_time);
int p=atoi(date_time_buf);
printf("time is %d \r\n", p);
return 0;
}
I am able to convert date to timestamp. But facing an issue.
The timestamp is offset by 5 hrs 30 minutes which is the timezone of my linux machine. But I don't want that. Is there a way to ignore system timezone?
Instead of using strftime() to format the broken down time struct tm as an integer, and parsing it using atoi(), you can use the simple but nonstandard timegm() function.
Even though timegm() is not in POSIX, it is provided by most POSIXy systems. If you want your code to be portable across POSIXy systems, you can use a workaround (as described in some versions of the timegm man page):
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
time_t alt_timegm(struct tm *from)
{
char *tz;
time_t result;
int saved_errno;
tz = getenv("TZ");
if (tz)
tz = strdup(tz);
setenv("TZ", "", 1); /* TZ empty refers to UTC */
tzset();
errno = 0;
result = mktime(from);
saved_errno = errno;
setenv("TZ", tz, 1);
free(tz);
errno = saved_errno;
return result;
}
This workaround does have the drawback that it temporarily modifies the current timezone, which affects other threads executing any timezone-related functions. In a single-threaded process this is not an issue (as the timezone-related functions are not async-signal safe, so they aren't to be used in signal handlers).
In multithreaded programs, one should serialize all accesses to the timezone related functions -- alt_timegm() above, mktime(), localtime(), and so on --, to ensure each function is run with the proper timezone set.
The timegm() implementations in Linux and BSDs are thread-safe; that is, they do not modify the timezone.
Using the above, parsing a string using an strptime() format to an Unix timestamp is easy:
const char *parse_utc(const char *s, const char *format, time_t *to)
{
char *result;
struct tm t_parts;
time_t t;
if (!s || !format) {
errno = EINVAL;
return NULL;
}
result = strptime(s, format, &t_parts);
if (!result) {
errno = EINVAL;
return NULL;
}
errno = 0;
t = alt_timegm(&t_parts);
if (to)
*to = result;
return (const char *)result;
}
The above parse_utc() parses a string s using strptime() format format, saving the UTC timestamp to to if not NULL, returning the pointer to the first unparsed character in string s.
Setting errno = 0 in the above functions may look strange, but it is because the mktime() (and timegm()) function may or may not set errno in case of an error; it just returns (time_t)-1. This means that it is impossible to reliably determine whether a (time_t)-1 (corresponding to last second of year 1969 in UTC`) is an actual valid timestamp, or an error return.
In other words, if errno != 0 after a call to parse_utc(), there was an error. (Note that if the string or format was invalid, parse_utc() returns NULL, with errno == EINVAL.) If errno == 0 but *to == (time_t)-1, it depends on the architecture whether the time string actually referred to the last second of year 1969 in UTC, or if it was an error; we simply do not know.
I am trying to create some error handling code in C. I am having trouble finding an input that breaks the function:
time(time_t *tloc)
I want to simulate time() breaking so I can test my error handling code. Either the input I try passes without an error or the entire program crashes (segfault). One error I am trying to produce is when the calendar cannot be located. In this instance, time() would return -1 and set errno to 14 ("Bad address"). How could I force this outcome without the kernel segfaulting me?
Because the libc time() function on a modern x86 linux kernel is implemented using a vdso syscall (See man 7 vdso), we have to resort to some trickery.
With vdso, the kernel is never entered. This is done for high frequency, speed critical calls (like time, gettimeofday, etc). All activity takes place in userspace. Hence, the segfault. The real [non-vdso] syscall will do checks and return the desired error codes.
We must use syscall(SYS_time,...) to force entry into the kernel's version of the syscall.
Here's a sample program:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/syscall.h>
int opt_t;
int
main(int argc,char **argv)
{
char *cp;
time_t tv;
time_t *tp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 't':
opt_t = 1;
break;
}
}
tp = (time_t *) 0xC0000000;
// this segfaults due to vdso
if (opt_t) {
printf("using time ...\n");
tv = time(tp);
}
// this returns error code
else {
printf("using syscall ...\n");
tv = syscall(SYS_time,tp);
}
printf("tv=%8.8lX errno=%d -- %s\n",tv,errno,strerror(errno));
return 0;
}
one way to force the time() function to fail is to run the application on a system that does not have a RTC (Real Time Clock). However such a system would also fail for almost everything else.
In shell scripting, when ever I want the local time I do something like
date +%s
from the command line and it returns me the current date and time in this format "1343221713"
I am wondering whether there is a way to achieve the same result in C
Use time.h library in C
example:
#include <stdio.h>
#include <time.h>
int main()
{
/* Obtain current time as seconds elapsed since the Epoch. */
time_t clock = time(NULL);
/* Convert to local time format and print to stdout. */
printf("Current time is %s", ctime(&clock));
return 0;
}
see more examples:
http://en.wikipedia.org/wiki/C_date_and_time_functions
More flexible than time(3) is gettimeofday(3) as declared in sys/time.h
#include <sys/time.h>
#include <stdio.h>
int main(void)
{
struct timeval tv = {0};
gettimeofday(&tv, NULL);
printf("seconds since epoch %ld, microseconds %ld\n", tv.tv_sec, tv.tv_usec);
return 0;
}
I am wondering is there any function that would return the current time in seconds, just 2 digits of seconds? I'm using gcc 4.4.2.
The following complete program shows you how to access the seconds value:
#include <stdio.h>
#include <time.h>
int main (int argc, char *argv[]) {
time_t now;
struct tm *tm;
now = time(0);
if ((tm = localtime (&now)) == NULL) {
printf ("Error extracting time stuff\n");
return 1;
}
printf ("%04d-%02d-%02d %02d:%02d:%02d\n",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0;
}
It outputs:
2010-02-11 15:58:29
How it works is as follows.
it calls time() to get the best approximation to the current time (usually number of seconds since the epoch but that's not actually mandated by the standard).
it then calls localtime() to convert that to a structure which contains the individual date and time fields, among other things.
at that point, you can just de-reference the structure to get the fields you're interested in (tm_sec in your case but I've shown a few of them).
Keep in mind you can also use gmtime() instead of localtime() if you want Greenwich time, or UTC for those too young to remember :-).
A more portable way to do this is to get the current time as a time_t struct:
time_t mytime = time((time_t*)0);
Retrieve a struct tm for this time_t:
struct tm *mytm = localtime(&mytime);
Examine the tm_sec member of mytm. Depending on your C library, there's no guarantee that the return value of time() is based on a number of seconds since the start of a minute.
You can get the current time with gettimeofday (C11), time (Linux), or localtime_r (POSIX); depending on what calendar & epoch you're interested. You can convert it to seconds elapsed after calendar epoch, or seconds of current minute, whichever you are after:
#include <stdio.h>
#include <string.h>
#include <time.h>
int main() {
time_t current_secs = time(NULL);
localtime_r(¤t_secs, ¤t_time);
char secstr[128] = {};
struct tm current_time;
strftime(secstr, sizeof secstr, "%S", ¤t_time);
fprintf(stdout, "The second: %s\n", secstr);
return 0;
}
You want to use gettimeofday:
man 2 gettimeofday
#include <stdio.h>
#include <sys/time.h>
int main (int argc, char **argv)
{
int iRet;
struct timeval tv;
iRet = gettimeofday (&tv, NULL); // timezone structure is obsolete
if (iRet == 0)
{
printf ("Seconds/USeconds since epoch: %d/%d\n",
(int)tv.tv_sec, (int)tv.tv_usec);
return 0;
}
else
{
perror ("gettimeofday");
}
return iRet;
}
This is better to use then time(0), because you get the useconds as well, atomically, which is the more common use case.