Как получить значения даты и времени в программе на Си? - PullRequest
51 голосов
/ 18 сентября 2009

У меня есть что-то вроде этого:

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

Он печатает текущий день и время в stdout, но я хочу получить эти выходные данные или присвоить их переменным current_day и current_time, чтобы позже я мог выполнить некоторую обработку с этими значениями.

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

Единственное решение, которое я могу придумать сейчас, - это направить вывод в какой-то файл, а затем прочитать файл и затем присвоить значениям даты и времени значения current_day и current_time. Но я думаю, что это не очень хороший способ. Есть ли другой короткий и элегантный способ?

Ответы [ 9 ]

122 голосов
/ 18 сентября 2009

Используйте time() и localtime(), чтобы получить время:

#include <time.h>

time_t t = time(NULL);
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);
16 голосов
/ 18 сентября 2009
time_t rawtime;   
time ( &rawtime );
struct tm *timeinfo = localtime ( &rawtime );

Вы также можете использовать strftime для форматирования времени в строку.

15 голосов

strftime (C89)

Мартин упомянул это , вот пример:

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];
    assert(strftime(s, sizeof(s), "%c", tm));
    printf("%s\n", s);
    return 0;
}

GitHub upstream .

Скомпилируйте и запустите:

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

Пример вывода:

Thu Apr 14 22:39:03 2016

Спецификатор %c создает тот же формат, что и ctime.

Одним из преимуществ этой функции является то, что она возвращает количество записанных байтов, что позволяет лучше контролировать ошибки в случае, если сгенерированная строка слишком длинна: ​​

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

  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 и ctime (C89)

asctime - удобный способ форматирования 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;
}

Пример вывода:

Wed Jun 10 16:10:32 2015

И есть также ctime(), который согласно стандарту является сокращением для:

asctime(localtime())

Как уже упоминалось Джонатаном Леффлером , этот формат имеет недостаток отсутствия информации о часовом поясе.

POSIX 7 пометил эти функции как "устаревшие", чтобы их можно было удалить в будущих версиях:

Разработчики стандарта решили пометить функции asctime () и asctime_r () устаревшими, хотя asctime () входит в стандарт ISO C из-за возможности переполнения буфера. Стандарт ISO C также предоставляет функцию strftime (), которую можно использовать, чтобы избежать этих проблем.

C ++ версия этого вопроса: Как узнать текущее время и дату в C ++?

Протестировано в Ubuntu 16.04.

1 голос
/ 24 апреля 2018

В Timespec встроен день года.

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;
}`
1 голос
/ 19 сентября 2009

Ответы, приведенные выше, являются хорошими ответами CRT, но если вы хотите, вы также можете использовать решение Win32 для этого. Он почти идентичен, но IMO, если вы программируете для Windows, вы могли бы просто использовать его API (не знаю, программируете ли вы в Windows, но неважно)

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. Надеюсь, это когда-нибудь пригодится вам!

0 голосов
/ 24 ноября 2018

Расширить ответ на Ори Ошеров

Вы можете использовать WinAPI для получения даты и времени, этот метод специфичен для Windows, но если вы ориентируетесь только на Windows или уже используете WinAPI, то это определенно возможно 1

Вы можете получить время и дату, используя SYSTEMTIME struct. Вам также необходимо вызвать одну из двух функций (GetLocalTime() или GetSystemTime()), чтобы заполнить struct .

GetLocalTime() даст вам время и дату , специфичные для вашего часового пояса .

GetSystemTime() даст вам время и дату в UTC .

В SYSTEMTIME struct входят следующие члены:

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

Затем вам нужно просто получить доступ к struct обычным способом


Фактический пример кода:

#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;
}

(Код для простоты и ясности см. Оригинальный ответ для лучшего формата )

Вывод будет примерно таким:

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

Полезные ссылки:

Вся документация WinAPI (большинство уже перечислено выше):

Очень хороший учебник для начинающих на эту тему от Zetcode:

Простые операции с датой и временем на Codeproject:


1: Как упоминалось в комментариях в ответе Ори Ошерова ("Given that OP started with date +%F, they're almost certainly not using Windows. – melpomene Sep 9 at 22:17"), ОП является , а не с использованием Windows, однако, поскольку этот вопрос не имеет специфического для платформы тега (и при этом нигде не упоминается, что ответ должен быть для этой конкретной системы), и это один из лучших результатов, когда Googling «получает время в c» оба ответа принадлежат здесь, некоторые пользователи, ищущие ответ на этот вопрос, могут быть в Windows и, следовательно, будут полезны для них .

0 голосов
/ 26 марта 2018
#include<stdio.h>
using namespace std;

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

return 0;
}
0 голосов
/ 11 марта 2018

Я получаю следующую ошибку при компиляции кода Адама Розенфилда в Windows. Оказывается, в коде ничего не хватает.

Ошибка (до)

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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                                                                                                         ^
C:\C\Codes>

Решение

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\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}

C:\C\Codes>

Компиляция

C:\C\Codes>gcc time.c -o time

C:\C\Codes>    

Окончательный результат

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

C:\C\Codes>

Надеюсь, это поможет и другим

0 голосов
/ 19 сентября 2009

вместо файлов используйте каналы, и если вы хотите использовать C, а не C ++, вы можете использовать popen вот так

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

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

и используйте * fp в качестве обычного указателя файла с fgets и всем

если вы хотите использовать строки c ++, разветвите дочерний элемент, вызовите команду и затем передайте ее родительскому элементу.

   #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");
    }

// сделать аналогичный 1 для даты + T, но на самом деле я рекомендую придерживаться вещей во времени. H GL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...