关于datetime:如何在C程序中获取日期和时间值?

How to get the date and time values in a C program?

我有这样的事情:

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

它在stdout中打印当前日期和时间,但我想获取此输出或将它们分配给current_daycurrent_time变量,以便稍后我可以使用这些值进行一些处理。

1
2
current_day ==> current day
current_time ==> current time

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


使用time()localtime()来获取时间:

1
2
3
4
5
6
7
#include <time.h>

time_t t = time(NULL);
struct tm tm = *localtime(&t);

printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);


1
2
3
time_t rawtime;  
time ( &rawtime );
struct tm *timeinfo = localtime ( &rawtime );

您还可以使用strftime将时间格式化为字符串。


strftime(C89)

马丁提到了,这是一个例子:

main.c中

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
#include <stdio.h>
#include <time.h>

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

GitHub上游。

编译并运行:

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

样本输出:

1
Thu Apr 14 22:39:03 2016

%c说明符生成与ctime相同的格式。

此函数的一个优点是它返回写入的字节数,以便在生成的字符串太长时允许更好的错误控制:

RETURN VALUE

1
2
3
4
  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.

asctimectime(C89)

asctime是格式化struct tm的便捷方式:

main.c中

1
2
3
4
5
6
7
8
9
#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;
}

样本输出:

1
Wed Jun 10 16:10:32 2015

此外,还有ctime()标准所说的快捷方式:

正如Jonathan Leffler所述,该格式的缺点是没有时区信息。

POSIX 7将这些功能标记为"过时",以便在将来的版本中将其删除:

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 ++版本:如何在C ++中获取当前时间和日期?

在Ubuntu 16.04中测试过。


Timespec内置了一年中的一天。

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

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

上面给出的答案是很好的CRT答案,但如果你想要,你也可以使用Win32解决方案。它几乎完全相同,但IMO如果您正在为Windows编程,您可能也只是使用它的API(不知道如果你实际上在Windows中编程,但无论如何)

1
2
3
4
5
char* arrDayNames[7] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; // Jeez I hope this works, I haven't done this in ages and it's hard without a compiler..
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]);

无论如何,这是你的Windows解决方案。希望它有时对你有用!


To expand on the answer by Ori Osherov

您可以使用WinAPI获取日期和时间,此方法特定于Windows,但如果您仅针对Windows,或者已经在使用WinAPI,那么这绝对是一种可能性1:

您可以使用SYSTEMTIME struct获取时间和日期。您还需要调用两个函数之一(GetLocalTime()GetSystemTime())来填充结构。

GetLocalTime()将为您提供特定于您所在时区的时间和日期。

GetSystemTime()将以UTC格式提供时间和日期。

SYSTEMTIME struct具有以下成员:

wYearwMonthwDayOfWeekwDaywHourwMinutewSecondwMilliseconds

然后,您需要以常规方式访问结构

实际示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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;
}

(为简单和清晰而编码,请参阅原始答案以获得更好的格式化方法)

输出将是这样的:

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

有用的参考文献:

所有WinAPI文档(大多数已在上面列出):

  • GetLocalTime()
  • GetSystemTime()
  • SYSTEMTIME
  • 时间功能

Zetcode关于这个主题的非常好的初学者教程:

  • http://zetcode.com/gui/winapi/datetime/

在Codeproject上使用datetime进行简单操作:

  • https://www.codeproject.com/Articles/5546/WinAPI-Simple-Operations-with-datetime

1:正如Ori Osherov的回答("Given that OP started with date +%F, they're almost certainly not using Windows. – melpomene Sep 9 at 22:17")中的评论中所提到的,OP不使用Windows,但是因为这个问题没有特定于平台的标签(也没有提到答案应该针对该特定系统的任何地方)谷歌搜索"获取时间"这两个答案都属于这里,一些搜索此问题答案的用户可能在Windows上,因此对他们有用。


在Windows上编译Adam Rosenfield的代码时出现以下错误。
事实证明,代码中缺少一些东西。

错误(之前)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
C:\C\Codes>gcc time.c -o time
time.c:3:12: error: initializer element is not constant
 time_t t = time(NULL);
            ^
time.c:4:16: error: initializer element is not constant
 struct tm tm = *localtime(&t);
                ^
time.c:6:8: error: expected declaration specifiers or '...' before string constant
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
        ^
time.c:6:36: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                    ^
time.c:6:55: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                       ^
time.c:6:70: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                                      ^
time.c:6:82: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                                                  ^
time.c:6:94: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                                                              ^
time.c:6:105: error: expected declaration specifiers or '...' before 'tm'
 printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                                                                         ^
C:\C\Codes>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
C:\C\Codes>more time.c
#include <stdio.h>
#include <time.h>

int main()
{
        time_t t = time(NULL);
        struct tm tm = *localtime(&t);

        printf("now: %d-%d-%d %d:%d:%d
"
, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}

C:\C\Codes>

编译

1
2
3
C:\C\Codes>gcc time.c -o time

C:\C\Codes>

最终产出

1
2
3
4
C:\C\Codes>time
now: 2018-3-11 15:46:36

C:\C\Codes>

我希望这对其他人也有帮助


而不是文件使用管道,如果你使用C而不是C ++你可以使用像这样的popen

1
2
3
4
#include<stdlib.h>
#include<stdio.h>

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

并使用* fp作为fgets和all的普通文件指针

如果您使用c ++字符串,请分叉子项,调用该命令,然后将其传递给父项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   #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");
    }

//为date + T做一个类似的1,但我真的建议你坚持使用time.h


1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
using namespace std;

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

return 0;
}