Как получить текущую дату и время в миллисекундах в C

Я пытаюсь написать программу, которая генерирует случайное число на основе внутренних часов системы таким образом, что мне не нужны ни начальное число, ни первое значение. Первое значение должно быть взято из внутренних часов путем преобразования года, месяца, дня, часов, минут, секунд в миллисекунды и добавления их к текущей миллисекунде, чтобы получить уникальное число (отметку времени). Любая помощь в получении этих значений на C?


person El GaGa    schedule 29.03.2014    source источник
comment
Обратите внимание, что использование текущего времени в качестве начального числа для генератора случайных чисел нормально, если вы не пытаетесь использовать его также в целях безопасности. Если вы пытаетесь обеспечить получение разных значений в большинстве случаев при запуске программы, это подойдет. Если вы пытаетесь быть непредсказуемым, как в криптографии, безнадежно небезопасно использовать время в качестве начального числа для вашего ГПСЧ (он дает вам не более 16 бит энтропии - я великодушен; это больше похоже на 10 бит , и, возможно, меньше, тогда как вам нужно 128 или более бит энтропии для большинства криптографических работ).   -  person Jonathan Leffler    schedule 29.03.2014
comment
Возможный дубликат Как измерить время в миллисекундах с помощью ANSI C? и другие системные версии, например stackoverflow.com/questions/3729169/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 19.03.2016


Ответы (3)


Вы можете использовать clock_gettime() или _ 2_ - или, если вы находитесь в очень бедной среде, _ 3_ или _ 4_. Убедитесь, что вы используете достаточно большой тип данных, чтобы вместить миллиметр.

Для clock_gettime() результатом будет struct timespec с элементами tv_sec и tv_nsec. Вы бы использовали:

#include <time.h>
#include <stdint.h>

struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
int64_t millitime = t.tv_sec * INT64_C(1000) + t.tv_nsec / 1000000;

С gettimeofday() (который официально устарел, но более широко доступен - например, Mac OS X имеет gettimeofday(), но не имеет clock_gettime()), у вас есть struct timeval с членами tv_sec и tv_usec:

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

struct timeval t;
gettimeofday(&t, 0);
int64_t millitime = t.tv_sec * INT64_C(1000) + t.tv_usec / 1000;

(Обратите внимание, что ftime() был стандартным в более старых версиях POSIX, но больше не является частью POSIX, хотя некоторые системы по-прежнему предоставляют его для обратной совместимости. Он был доступен в ранних версиях Unix как средство первого субсекундного времени, но не как еще в 7-м издании Unix. Он был добавлен в POSIX (Single Unix Specification) для обратной совместимости, но вы должны стремиться использовать clock_gettime(), если можете, и gettimeofday(), если нет.)

person Jonathan Leffler    schedule 29.03.2014
comment
FWIW эмпирически я видел, что функция clock_gettime() (в системе Intel Xeon linux) всегда возвращает значение наносекунд, округленное до 250, поэтому вам может потребоваться разделить на 1000000, если вы используете эту часть результата. [РЕДАКТИРОВАТЬ - разделить на 1000 дает микросекунды, как указано ниже] - person 6EQUJ5; 29.03.2014
comment
@AndrewMcDonnell: вам нужно разделить значение наносекунд на один миллион, чтобы получить миллисекунды. - person Jonathan Leffler; 29.03.2014
comment
Конечно, вы правы; Я просто заметил, что если вам нужен больший диапазон, то последние 3 цифры бесполезны - person 6EQUJ5; 29.03.2014
comment
@chux: да, ты прав; что-то должно принудить результат к int64_t перед назначением. Использование суффикса LL - это один из способов сделать это, и я бы использовал его, если бы тип millitime был long long. Но поскольку я использовал int64_t, вероятно, лучше использовать макрос INT64_C(), определенный в <stdint.h> (вместе с int64_t). - person Jonathan Leffler; 29.03.2014
comment
как я могу вставить #include ‹sys / time.h›? мне сказали, что эта библиотека неопознана - person El GaGa; 30.03.2014
comment
@ElGaGa: (а) это не библиотека; это заголовок - (б) если у вас его нет, вы не можете его использовать - (в) на какой платформе вы работаете и у вас ее нет? Windows - это закон сама по себе, и она не очень хорошо согласуется со стандартом POSIX. - person Jonathan Leffler; 30.03.2014

Стандарт C не гарантирует точность времени лучше секунды. Если вы используете систему POSIX, попробуйте часы * функции.

person pmg    schedule 29.03.2014
comment
@ElGaGa: Понятия не имею. Полагаю, как и C, C ++ не гарантирует точности времени лучше секунды. Я не знаю, какие функции помимо стандарта C ++ широко доступны. - person pmg; 31.03.2014

Если вы делаете это в Windows, вы можете использовать:

unsigned int rand = GetTickCount() % A_PRIME_NUMBER_FOR_EXAMPLE;

[Изменить: выделить по модулю что-то подходящее для ваших обстоятельств]

person 6EQUJ5    schedule 29.03.2014
comment
Вероятно, для этого требуются очень точные системные часы. См. здесь для документации. В нем указано, что типичное разрешение составляет 10-16 мс. Кроме того, вы, вероятно, имели в виду 65535. - person FRob; 29.03.2014
comment
Я имел ввиду любое произвольное число. Возможно, я был немного либерален в своей интерпретации вопроса ... некоторые числа более случайны, чем другие, и т. Д. - person 6EQUJ5; 29.03.2014
comment
Простое число имеет преимущества перед магическим числом 65531. - person chux - Reinstate Monica; 29.03.2014
comment
GetTickCount () входит в какую библиотеку ?? - person El GaGa; 30.03.2014
comment
См. Ссылку в сообщении @FRob - person 6EQUJ5; 31.03.2014