Преобразуйте текущую миллисекунду в формат времени, используя C

мне нужно преобразовать текущее время в миллисекундах в удобочитаемый формат времени. У меня есть следующий код

#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <time.h>

int Cnvrt_To_Time_Frmt(char *Epochval)
{
    unsigned long epoch = 0;
    time_t tt = 0;
    char timestamp[64],usec_buf[20];
    if (!sscanf(Epochval, "%lu", &epoch))
    {
        return 1;
    }
    tt = epoch;

    strftime(timestamp, 64, "%c", localtime(&tt));
    printf("%s\n",timestamp);
    return 0;
}

int main()
{
    uint64_t Epoch_time=1468496250207;
    char str_ms[256];
    sprintf(str_ms, "%llu", (Epoch_time/1000));
    Cnvrt_To_Time_Frmt(str_ms);

}

Результат: Четверг, 14 июля, 17:07:30 2016.

Но мне нужно напечатать результат с миллисекундами. нравится Чт, 14 июля, 17:07:30:40 2016.(17 часов, 07 минут, 30 секунд, 40 миллисекунд)

Как это будет возможно?


person Abdul Manaf    schedule 14.07.2016    source источник
comment
С или С++? Не то же самое...   -  person dear_tzvi    schedule 14.07.2016
comment
в коде Си. я компилирую командой gcc   -  person Abdul Manaf    schedule 14.07.2016


Ответы (5)


Тип time_t по его определению не представляет время с миллисекундным разрешением, функция localtime возвращает указатель на struct tm, который не включает миллисекунды, function strftime не предназначен для создания строк с миллисекундами.

Если вам нужно время в миллисекундах, вы можете использовать timeb структуру с его связанная ftime функция, если они поддерживаются вашей цепочкой инструментов.

person mvidelgauz    schedule 14.07.2016
comment
Обратите внимание, что определение является общим в отношении секунд, а не спецификацией C. time_t может предоставлять информацию с точностью до секунды. Тем не менее, time_t как целое число секунд является обычным явлением. - person chux - Reinstate Monica; 28.09.2020

Используйте это как строку формата:

strftime(timestamp, 64, "%a %b %d %H:%M:%S.XXX %Y", localtime(&tt));

XXX будет скопировано как есть в строку времени. Затем в main вы можете перезаписать X с количеством миллисекунд.

sprintf(&timestamp[20], "%03u", (unsigned)Epoch_time%1000);
timestamp[23] = ' '; // restore the NUL to space again

После этого реорганизуйте свой код, чтобы операции деления и остатка выполнялись внутри Cnvrt_To_Time_Frmt. Вы можете использовать это как прототип:

int msecs_tostr(char *buffer, const char *msecs_since_epoch);
person a3f    schedule 14.07.2016

У меня еще нет 50 повторителей, поэтому я не могу комментировать, поэтому напишу свое предложение в качестве ответа здесь.

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

Создайте структуру, содержащую dayOfWeek, month, dayOfMonth, hour, minute, second, milliSecond, year. Создайте convertFunction, которая получит значение миллисекунд, которое необходимо преобразовать в формат вашей структуры. Возможно, это не лучший способ сделать это, но если вы не можете найти способ использовать существующие библиотеки, создайте свои собственные.

person Mark Davydov    schedule 14.07.2016

... нужно напечатать результат с миллисекундами. ...Как это будет возможно?

Делайте это шаг за шагом

uint64_t Epoch_time=1468496250207;

// Break time into a whole number of seconds and ms fraction
time_t t_unix = Epoch_time/1000;
unsigned t_ms = Epoch_time%1000;

// Convert to YMD HMS structure
struct tm tm = *localtime(&t_unix);

// Form left portion of string
char left[64];
strftime(left, sizeof left, "%a %b %d %H:%M", &tm);

// Form right portion of string
char right[20];
strftime(right, sizeof right, "%Y", &tm);

// Put together with ms
char timestamp[64];
snprintf(timestamp, sizeof timestamp, "%s:%u %s", left, t_ms, right);

// Thu Jul 14 17:07:30:40 2016
// Print as needed
puts(timestamp);

Надежный код добавил бы проверку ошибок с возвращаемым значением каждой функции.


[править] Очевидно, что последние 3 цифры метки времени OP представляют собой дробь / 512.

unsigned t_fraction = Epoch_time%1000;
...
snprintf(timestamp, sizeof timestamp, "%s:%02u %s", left, t_fraction*100/512, right);
person chux - Reinstate Monica    schedule 14.07.2016
comment
я получил ошибку при компиляции этого кода test.c:31:38: ошибка: ожидается ‘)’ перед строковой константой snprintf(timestamp, sizeof timestamp %s:%u %s, left, t_ms, right); ^ test.c:31:1: ошибка: слишком мало аргументов для функции ‘snprintf’ snprintf(timestamp, sizeof timestamp %s:%u %s, left, t_ms, right); - person Abdul Manaf; 15.07.2016
comment
@Abdul Manaf Missing , добавлен. - person chux - Reinstate Monica; 15.07.2016
comment
спасибо, Чукс, но я получил результат, четверг, 14 июля, 17:07:207 2016. - person Abdul Manaf; 16.07.2016
comment
@Abdul Manaf Изменено, чтобы справиться с дробью. - person chux - Reinstate Monica; 16.07.2016

Этот пример программы будет получать текущую временную метку из своей системной ОС и распечатывать ее в удобочитаемом формате. Он похож на ответ @user:2410359, но немного короче.

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

/* 
 * timestamp - read and print the current timestamp
 * Wade Ryan 2020-09-27
 * compile using: g++ timestamp.cpp -o timestamp
 */ 

int main(int argc, char **argv) {
    char   timestamp[24];
    struct timeval currentTime;
    struct tm      ts;

    gettimeofday(&currentTime, NULL);

    long long epoch  =  (unsigned long long)(currentTime.tv_sec) * 1000 +
                        (unsigned long long)(currentTime.tv_usec) / 1000;
        
    strftime(timestamp, sizeof(timestamp), "%F %T", localtime(&currentTime.tv_sec));

    printf("epoch %lld ms :: %s.%03ld\n", epoch, timestamp, currentTime.tv_usec/1000);

}

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

epoch 1601259041504 ms :: 2020-09-27 21:10:41.504
person wryan    schedule 28.09.2020