Для этой программы мне нужно «получить время начала всего процесса в пределах максимальной точности времени, включая наносекунды». в формате: 9 апреля 2022 г. 13:18:17.123456789
Я могу получить все, кроме наносекунд. возможно и/или что посоветуете?
Вот что у меня есть:
//%B - Full Month Name
//%e - day space padded (%d 0 padded)
//$G - year (with century)
//%R - 24-hour HH:MM time, equivalent to %H:%M
//%N - nanoseconds?
//%T - ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S
#define BUFFERSIZE 256
char timeStringEnd[BUFFERSIZE] = {0};
time_t timeEnd = time(NULL);
struct tm *timePointerEnd = localtime(&timeEnd);
strftime(timeStringEnd, BUFFERSIZE, "\n%B%e, %G %T", timePointerEnd);
puts(timeStringEnd);
%N не хочет работать. Приветствуются любые дополнительные материалы/источники по использованию времени. ТИА
Кратко — нет, это не отвечает на вопрос по существу. Он печатает одно число, а не отформатированную дату/время, как здесь запрошено.
@IłyaBursov, хотя я согласен с Джонатаном, это очень полезно. Спасибо за ваш вклад
Использование localtime()
и печать с %B%e, %G %T
без индикации дневное время может сделать последующие выходные метки времени более похожими на шаг назад, когда часы переходят с дневного времени на стандартное время. Я рекомендую использовать 1) gmtime()
или 2) продолжить с localtime()
и печатать с %z, %Z
...
Функция strftime()
не поддерживает время меньше секунды. Вам нужно будет добавить это самостоятельно. Вам также нужно использовать функцию, которая возвращает время меньше секунды — это не time()
. Предполагая, что у вас есть система POSIX, вы можете использовать clock_gettime()
:
struct timespec tv;
clock_gettime(CLOCK_REALTIME, &tv);
struct tm *timePointerEnd = localtime(&tv.tv_sec);
size_t nbytes = strftime(timeStringEnd, BUFFERSIZE, "\n%B%e, %G %T", timePointerEnd);
snprintf(timeStringEnd + nbytes, sizeof(timeStringEnd) - nbytes,
"%.9ld", tv.tv_nsec);
puts(timeStringEnd);
C11 предоставляет функцию timespec_get()
, которая выполняет примерно ту же работу. Он использует struct timespec
, но аргументы немного отличаются. Вы бы сначала передали указатель и указали TIME_UTC
в качестве второго аргумента.
Спасибо. Я использовал timespec в другой части программы, чтобы получить время начала в секундах и наносекундах, когда функция вызывается, чтобы в конечном итоге дать мне что-то для расчета прошедшего времени. Например, если бы я хотел получить общее время между timePointerStart и timePointerEnd, включая наносекунды, вы бы порекомендовали мне сначала выполнить математику в наносекундах, а затем snprintf результаты?
Я разрываюсь между тем, чтобы сказать «это новый вопрос» и дополнить этот ответ кодом для арифметики на структурах struct timespec
. Если вы хотите напечатать отформатированное время, это делается с использованием варианта того, что показано выше. Если вы хотите рассчитать и распечатать прошедшее время, вам нужно использовать другой код. В каком формате должно быть напечатано прошедшее время? 3d 13h 12m 43.912317664s
? 306763.912317664s
? Нет суффикса s
для обозначения единиц измерения? Или обозначение «период» (также известное как «интервал») ISO 8601? Или что? Арифметика проста; вариантов форматирования легион!
Понятно! Если вы хотите, я сначала проведу тест и, если нужно, отправлю еще один вопрос, но формат будет 0s.123456789ns... Я думаю, что у меня есть "секунды" и "nsecs", использующие timespec, привязанные к struct timespec start и остановись... просто не знаю, есть ли еще что-нибудь встроенное, что я мог бы использовать.
В библиотеках POSIX или C нет стандартных функций, специально предназначенных для форматирования длительности времени (промежутка между двумя моментами времени).
При использовании timespec tm -> clock_gettime (realtime, & tm) я получаю это как вывод: как секунды 1649528225? и откуда берутся первые 2 цифры в наносекундах? timespec sec - TIME Second START: 1649528225 timespec nsec - TIME Nano START: 879597000 April 9, 2022 14:17:05879597000
Предполагая struct timespec tm; clock_gettime(CLOCK_REALTIME);
, значение в tm->tv_sec
является значением time_t
и будет таким же, как значение, которое вы получили бы от time_t now = time(0);
. Это стандартное «количество секунд, прошедших с начала Эпохи — также известное как 1970-01-01 00:00:00Z». Значение в tm.tv_nsec
представляет собой дробную часть секунды, представленную в виде значения в наносекундах от 0 до 999 999 999. При печати очень важно правильно обрабатывать значение с помощью %.9ld
или эквивалентного. Это добавляет ведущие нули, чтобы вы могли различать 0,100000000` и 0.000001000
и т. д.
Если вы хотите напечатать микросекунды, используйте %.6ld
и tm.tv_nsec / 1000
; если вы хотите напечатать миллисекунды, используйте %.3ld
и tm.tv_nsec / 1000000
. Требуется уход.
Ох, ладно. Я ценю вашу помощь, так как сегодня я многому научился здесь. Спасибо, это проясняет для меня ситуацию. Итак, если моя логика верна, то, что я видел, поскольку первые 2 цифры были 2 миллисекундами, за которыми следовали наносекунды, которые я добавил, потому что они включены во время эпохи?
Наверное — это лучшее, что я могу сказать. Я рад, что мой комментарий был чем-то полезен. Правильное обращение со временем — сложный процесс, который требует ясности в понимании того, что именно вы ищете в качестве информации.
@jTruBela "общее время между timePointerStart и timePointerEnd, включая наносекунды" --> double diff_in_seconds = difftime(end.tv_sec, start.tv_sec) + (end.tv_nsec - start.tv_nsec)/1.0e9
. Тогда printf("%.9f seconds\n", diff_in_seconds);
.
@chux-ReinstateMonica: Поскольку для количества секунд требуется 10 десятичных цифр, а для дробной части — 9, у вас могут возникнуть проблемы с количеством цифр, которые может хранить double
. Тем не менее, если вы имеете дело с текущими измерениями, вряд ли у вас будут такие разные числа секунд, но об этом стоит помнить.
Отвечает ли это на ваш вопрос? Время печати с начала эпохи в наносекундах