Як надрукувати час у форматі: 2009‐08‐10 18: 17: 54.811


Відповіді:


108

Використовуйте strftime () .

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

int main()
{
    time_t timer;
    char buffer[26];
    struct tm* tm_info;

    timer = time(NULL);
    tm_info = localtime(&timer);

    strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    puts(buffer);

    return 0;
}

Подивіться на це питання на мілісекунди. Як виміряти час у мілісекундах за допомогою ANSI C?


Зараз це ще краща відповідь і реквізит для пошуку, як поводитися з мілісекундною частиною. Я думаю, що ваш буфер зараз трохи довший, ніж повинен бути.
Jack Kelly

14
Краще бути довшим, ніж коротшим :-)
paxdiablo

Чудова відповідь. Я міг робити всілякі речі в PHP, але знав, що все це вже є у C. Спасибі.
Віджай Кумар Канта

1
Можливо, рядок time(&timer)має бути швидше timer = time(NULL);, принаймні для Linux. The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail.
Антонін Дечимо,

5
Відповідь, безумовно, є помилковою хоча б в одному випадку (Linux), оскільки "struct tm", що використовується localtime (), не містить інформації про час нижче секунд. Натомість "struct timeval", який використовується gettimeofday (), має мікросекунди, які, поділені на 1000, дадуть мілісекунди. Усі ці голоси дійсно помилкові та оманливі! Хіба що хтось повідомляє, за якою архітектурою ви отримуєте деталі часу нижче другої за допомогою "struct tm".
EnzoR

30

Наведені вище відповіді не повністю відповідають на питання (зокрема, мілісекційна частина). Моє рішення цього - використовувати gettimeofday перед strftime. Зверніть увагу, щоб уникнути округлення мілісекунд до "1000". Це базується на відповіді Хаміда Назарі.

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>

int main() {
  char buffer[26];
  int millisec;
  struct tm* tm_info;
  struct timeval tv;

  gettimeofday(&tv, NULL);

  millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
  if (millisec>=1000) { // Allow for rounding up to nearest second
    millisec -=1000;
    tv.tv_sec++;
  }

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
  printf("%s.%03d\n", buffer, millisec);

  return 0;
}

gettimeofdayнедоступний у реалізаціях Windows
Мендес,

Будь ласка, додайте параметри '-lm' під час його створення.
skysign

3
Я думаю, що буфера [24] достатньо, причина така, як нижче, РРРР: ММ: ДД ЧЧ: ММ: СС.ммм + '\ 0', дорівнює 24.
skysign

@Mendes, навіщо згадувати Windows? Питання стосується простої мови C. Це краща відповідь (хоча і не правильна), незважаючи на всі ці неправильні голоси!
EnzoR

2
user3624334: Ні, ти не розумієш код. Існує лише один запит на час. Я припускаю, що ви маєте на увазі виклик localtime - він просто переформатує результат з gettimeofday.
Кріс

12

time.hвизначає strftimeфункцію, яка може дати вам текстове представлення time_tвикористання, наприклад:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buff[100];
    time_t now = time (0);
    strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
    printf ("%s\n", buff);
    return 0;
}

але це не дасть вам роздільної здатності на секунду, оскільки це недоступно в time_t. Виводить:

2010-09-09 10:08:34.000

Якщо ви дійсно обмежені специфікаціями і не хочете пробілу між днем ​​та годиною, просто видаліть його із рядка форматування.


+1 за доцільний трюк із заповненням дисплея на мілісекунди. Одного разу у мене був замовник, який хотів, щоб я це зробив, але з ненульовими цифрами, так що, схоже, там було значення. Я відмовив його від цього, але погодився поставити нулі.
RBerteig,

4
Один мій друг (звичайно, не я) скористався подібним трюком - вони зберігали статику, що містить останню секунду та "мілісекунду". Там, де другий не змінився з останнього разу, вони просто додали випадкове значення від 1 до 200 до мілісекунд (переконуючись, що воно не минуло 999, звичайно - фактичний максимум для rand () завжди був мінімальним 200 з половиною відстані до 999). Там, де другий все-таки змінився, вони просто встановили мілісек на 0 перед додаванням. Хороший, здавалося б, випадковий, але належним чином послідовність мілісекунд, і клієнт не був розумнішим :-)
paxdiablo

5

Наступний код друкується з мікросекундною точністю. Все , що потрібно зробити , це використовувати gettimeofdayі strftimeна tv_secі Append tv_usecдо побудованої рядку.

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(void) {
    struct timeval tmnow;
    struct tm *tm;
    char buf[30], usec_buf[6];
    gettimeofday(&tmnow, NULL);
    tm = localtime(&tmnow.tv_sec);
    strftime(buf,30,"%Y:%m:%dT%H:%M:%S", tm);
    strcat(buf,".");
    sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
    strcat(buf,usec_buf);
    printf("%s",buf);
    return 0;
}

2

Ви можете використовувати strftime, але struct tmне має роздільної здатності на частини секунд. Я не впевнений, що це абсолютно потрібно для ваших цілей.

struct tm tm;
/* Set tm to the correct time */
char s[20]; /* strlen("2009-08-10 18:17:54") + 1 */
strftime(s, 20, "%F %H:%M:%S", &tm);

2

фокус:

    int time_len = 0, n;
    struct tm *tm_info;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    tm_info = localtime(&tv.tv_sec);
    time_len+=strftime(log_buff, sizeof log_buff, "%y%m%d %H:%M:%S", tm_info);
    time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,".%03ld ",tv.tv_usec/1000);

1
Будь ласка, детальніше поясніть, чому це працює. і що саме відбувається.
Радж Камаль

Все те саме, що на прикладах вище, але лише ефективніше. `time_len + = snprintf (log_buff + time_len, sizeof log_buff-time_len," log var is =% s ", logvar); int ret = запис (log_fd, log_buff, time_len); `
Андрей Мельников

Звідки імпортувати gettimeofday?
AndreyP

1

Жодне з рішень на цій сторінці не працювало для мене, я змішав їх і змусив працювати з Windows і Visual Studio 2019, ось як:

#include <Windows.h>
#include <time.h> 
#include <chrono>

static int gettimeofday(struct timeval* tp, struct timezone* tzp) {
    namespace sc = std::chrono;
    sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
    sc::seconds s = sc::duration_cast<sc::seconds>(d);
    tp->tv_sec = s.count();
    tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();
    return 0;
}

static char* getFormattedTime() {
    static char buffer[26];

    // For Miliseconds
    int millisec;
    struct tm* tm_info;
    struct timeval tv;

    // For Time
    time_t rawtime;
    struct tm* timeinfo;

    gettimeofday(&tv, NULL);

    millisec = lrint(tv.tv_usec / 1000.0);
    if (millisec >= 1000) 
    {
        millisec -= 1000;
        tv.tv_sec++;
    }

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", timeinfo);
    sprintf_s(buffer, 26, "%s.%03d", buffer, millisec);

    return buffer;
}

Результат:

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.