如何在 C 程序中获得日期和时间值?

我有这样的东西:

char *current_day, *current_time;
system("date +%F");
system("date +%T");

它在标准输出中输出当前的日期和时间,但是我希望获得这个输出,或者将它们分配给 current_daycurrent_time变量,以便稍后可以对这些值进行一些处理。

current_day ==> current day
current_time ==> current time

现在我能想到的唯一解决方案是将输出定向到某个文件,然后读取该文件,然后将日期和时间的值分配给 current_daycurrent_time。但我觉得这不是个好办法。还有其他简短优雅的方法吗?

443139 次浏览

Use time() and localtime() to get the time:

#include <stdio.h>
#include <time.h>


int main()
{
time_t t = time(NULL);
struct tm tm = *localtime(&t);
printf("now: %d-%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);
}
time_t rawtime;
time ( &rawtime );
struct tm *timeinfo = localtime ( &rawtime );

You can also use strftime to format the time into a string.

instead of files use pipes and if u wana use C and not C++ u can use popen like this

#include<stdlib.h>
#include<stdio.h>


FILE *fp= popen("date +F","r");

and use *fp as a normal file pointer with fgets and all

if u wana use c++ strings, fork a child, invoke the command and then pipe it to the parent.

   #include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;


string currentday;
int dependPipe[2];


pipe(dependPipe);// make the pipe


if(fork()){//parent
dup2(dependPipe[0],0);//convert parent's std input to pipe's output
close(dependPipe[1]);
getline(cin,currentday);


} else {//child
dup2(dependPipe[1],1);//convert child's std output to pipe's input
close(dependPipe[0]);


system("date +%F");
}

// make a similar 1 for date +T but really i recommend u stick with stuff in time.h GL

The answers given above are good CRT answers, but if you want you can also use the Win32 solution to this. It's almost identical but IMO if you're programming for Windows you might as well just use its API (although I don't know if you are programming in Windows).

char* arrDayNames[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
SYSTEMTIME st;
GetLocalTime(&st); // Alternatively use GetSystemTime for the UTC version of the time
printf("The current date and time are: %d/%d/%d %d:%d:%d:%d", st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
printf("The day is: %s", arrDayNames[st.wDayOfWeek]);

Anyway, this is a Windows solution. I hope it will be helpful for you sometime!

strftime (C89)

Martin mentioned it, here's an example:

main.c

#include <assert.h>
#include <stdio.h>
#include <time.h>


int main(void) {
time_t t = time(NULL);
struct tm *tm = localtime(&t);
char s[64];
size_t ret = strftime(s, sizeof(s), "%c", tm);
assert(ret);
printf("%s\n", s);
return 0;
}

GitHub upstream.

Compile and run:

gcc -std=c89 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Sample output:

Thu Apr 14 22:39:03 2016

The %c specifier produces the same format as ctime.

One advantage of this function is that it returns the number of bytes written, allowing for better error control in case the generated string is too long:

RETURN VALUE

Provided that the result string, including the terminating null byte, does not exceed max bytes, strftime() returns the number of bytes (excluding the terminating null byte) placed in the array s. If the length of the result string (including the terminating null byte) would exceed max bytes, then strftime() returns 0, and the contents of the array are undefined.

Note that the return value 0 does not necessarily indicate an error. For example, in many locales %p yields an empty string. An empty format string will likewise yield an empty string.

asctime and ctime (C89, deprecated in POSIX 7)

asctime is a convenient way to format a struct tm:

main.c

#include <stdio.h>
#include <time.h>


int main(void) {
time_t t = time(NULL);
struct tm *tm = localtime(&t);
printf("%s", asctime(tm));
return 0;
}

Sample output:

Wed Jun 10 16:10:32 2015

And there is also ctime() which the standard says is a shortcut for:

asctime(localtime())

As mentioned by Jonathan Leffler, the format has the shortcoming of not having timezone information.

POSIX 7 marked those functions as "obsolescent" so they could be removed in future versions:

The standard developers decided to mark the asctime() and asctime_r() functions obsolescent even though asctime() is in the ISO C standard due to the possibility of buffer overflow. The ISO C standard also provides the strftime() function which can be used to avoid these problems.

C++ version of this question: How to get current time and date in C++?

Tested in Ubuntu 16.04.

#include<stdio.h>
using namespace std;


int main()
{
printf("%s",__DATE__);
printf("%s",__TIME__);


return 0;
}

Timespec has day of year built in.

http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html

#include <time.h>
int get_day_of_year(){
time_t t = time(NULL);
struct tm tm = *localtime(&t);
return tm.tm_yday;
}`

To expand on the answer by Ori Osherov

You can use the WinAPI to get the date and time, this method is specific to Windows, but if you are targeting Windows only, or are already using the WinAPI then this is definitly a possibility1:

You can get both the time and date by using the SYSTEMTIME struct. You also need to call one of two functions (either GetLocalTime() or GetSystemTime()) to fill out the struct.

GetLocalTime() will give you the time and date specific to your time zone.

GetSystemTime() will give you the time and date in UTC.

The SYSTEMTIME struct has the following members:

wYear, wMonth, wDayOfWeek, wDay, wHour, wMinute, wSecond and wMilliseconds

You then need to just access the struct in the regular way


Actual example code:

#include <windows.h> // use to define SYSTEMTIME , GetLocalTime() and GetSystemTime()
#include <stdio.h> // For printf() (could otherwise use WinAPI equivalent)


int main(void) { // Or any other WinAPI entry point (e.g. WinMain/wmain)


SYSTEMTIME t; // Declare SYSTEMTIME struct


GetLocalTime(&t); // Fill out the struct so that it can be used


// Use GetSystemTime(&t) to get UTC time


printf("Year: %d, Month: %d, Day: %d, Hour: %d, Minute:%d, Second: %d, Millisecond: %d", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, t.wMilliseconds); // Return year, month, day, hour, minute, second and millisecond in that order


return 0;
}

(Coded for simplicity and clarity, see the original answer for a better formatted method)

The output will be something like this:

Year: 2018, Month: 11, Day: 24, Hour: 12, Minute:28, Second: 1, Millisecond: 572

Useful References:

All the WinAPI documentation (most already listed above):

An extremely good beginners tutorial on this subject by ZetCode:

Simple operations with datetime on Codeproject:


1: As mentioned in the comments in Ori Osherov's answer ("Given that OP started with date +%F, they're almost certainly not using Windows. – melpomene Sep 9 at 22:17") the OP is not using Windows, however since this question has no platform specific tag (nor does it mention anywhere that the answer should be for that particular system), and is one of the top results when Googling "get time in c" both answers belong here, some users searching for an answer to this question may be on Windows and therefore will be useful to them.

I was using command line C-compiler to compile these and it completely drove me bonkers as it refused to compile.

For some reason my compiler hated that I was declaring and using the function all in one line.

struct tm tm = *localtime(&t);


test.c
test.c(494) : error C2143: syntax error : missing ';' before 'type'
Compiler Status: 512

First declare your variable and then call the function. This is how I did it.

char   todayDateStr[100];
time_t rawtime;
struct tm *timeinfo;


time ( &rawtime );
timeinfo = localtime ( &rawtime );
strftime(todayDateStr, strlen("DD-MMM-YYYY HH:MM")+1,"%d-%b-%Y %H:%M",timeinfo);
printf("todayDateStr = %s ... \n", todayDateStr );
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


struct date
{
int month;
int day;
int year;
};


int calcN(struct date d)
{
int N;
int f(struct date d);
int g(int m);


N = 1461 * f(d) / 4 + 153 * g(d.month) / 5 + d.day;


if(d.year < 1700 || (d.year == 1700 && d.month < 3))
{
printf("Date must be after February 29th, 1700\n");


return 0;
}
else if(d.year < 1800 || (d.year == 1800 && d.month < 3))
N += 2;
else if(d.year < 1900 || (d.year == 1900 && d.month < 3))
N += 1;


return N;
}


int f(struct date d)
{
if(d.month <= 2)
d.year -= 1;


return d.year;
}


int g(int m)
{
if(m <=2)
m += 13;
else
m += 1;
    

return m;
}


int main(void)
{
int calcN(struct date d);
struct date d1, d2;
int N1, N2;
time_t t;


time(&t);
struct tm *now = localtime(&t);




d1.month = now->tm_mon + 1;
d1.day = now->tm_mday;
d1.year = now->tm_year + 1900;


printf("Today's date: %02i/%02i/%i\n", d1.month, d1.day, d1.year);


N1 = calcN(d1);


printf("Enter birthday (mm dd yyyy): ");
scanf("%i%i%i", &d2.month, &d2.day, &d2.year);


N2 = calcN(d2);


if(N2 == 0)
return 0;


printf("Number of days since birthday: %i\n", N1 - N2);


return 0;
}
#include <stdio.h>


int main() {
char *pts; /* pointer to time string */
time_t now; /* current time */
char *ctime();
(void) time(&now);
printf("%s", ctime(&now));


return(0);
}

Sample output:

Sat May 14 19:24:54 2022

This is the easiest way. I haven't even used time.h.

Be advised: The output produced has a newline at the end.