Qt

Вывести время компиляции исходников __TIMESTAMP__ в виде Unix timestamp в C(C++)

В общем, потребовалось запоминать время компиляции/изменения исходника, для этого есть предопределённые макросы __DATE__, __TIME__ и __TIMESTAMP__ как собирательный образ, но проблема в том, что __TIMESTAMP__ выводит строку в формате «Mon Aug 29 06:31:38 2022», мне же хотелось получить именно в Unix timestamp (секунд, прошедших с полуночи 1 Января 1970, например 1661743898).
Можно, конечно, задавать дефайн при сборке, а метку времени брать от системы, но это, ИМХО, не очень правильно.

Вариант для «C» и Linux (GCC)

#include <iostream>
#include <string.h>
#define __USE_XOPEN
#include <time.h>
#include <locale.h>

int main() {
  struct tm tmCompile;
  memset(&tmCompile, 0, sizeof(tmCompile));
  char* localeLCTime = strdup(setlocale(LC_TIME, NULL)) ; //-- Запомним локаль, потом вернём на место
  setlocale(LC_TIME, "C");
  strptime(__TIMESTAMP__, "%A %B %d %H:%M:%S %Y", &tmCompile);
  setlocale(LC_TIME, localeLCTime);
  uint64_t tsCompile = mktime(&tmCompile);

  printf("TIMESTAMP: %s, tsCompile %lu\n" , __TIMESTAMP__, tsCompile);
}

Но функции strptime нет в стандарте C, поэтому под виндой в MSVC соответственно не соберётся.
Можно таскать ещё исходик strptime с собой: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD но, ИМХО, это уже перебор.


Более кросплатформенный вариант, для «C»:

#include <iostream>
#include <string.h>
#include <time.h>

int main() {
  struct tm tmCompile;
  memset(&tmCompile, 0, sizeof(tmCompile));
  char monthNames[36] ="JanFebMarAprMayJunJulAugSepOctNovDec";
  char monthCur[4] ={0};
  sscanf(__TIMESTAMP__, "%*s %s %d %d:%d:%d %d", monthCur, &tmCompile.tm_mday, &tmCompile.tm_hour, &tmCompile.tm_min, &tmCompile.tm_sec, &tmCompile.tm_year);
  tmCompile.tm_year -= 1900;
  tmCompile.tm_isdst =-1; //-- Дабы избавиться от проблем с переводом времени
  tmCompile.tm_mon = (strstr(monthNames, monthCur)-monthNames)/3;
  uint64_t tsCompile = mktime(&tmCompile);
  printf("TIMESTAMP: %s, tsCompile %lu\n" , __TIMESTAMP__, tsCompile);
}

Для C++ проще, т.к. можно использовать std::get_time.

Вот в общем то и всё…
Можно, по идее, это всё на макросах расписать, но уж шибко много нужно учесть (високосный год, високосные секунды, столетия и т.д.), так что, думаю, лучше так оставить.

Related posts

QML Сделать задержку перед началом анимации

QtCreator не открывает диалог выбора файлов, проектов, не открывает проект

Сборка Qt 6.8 (Dev) из исходников в Docker контейнере (Linux)