Динамическое использование препроцессора DATE - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь использовать __DATE__ в C ++ Builder, и мне нужно использовать его динамически. Например, если пользователь нажимает кнопку, метка, содержащая __DATE__, обновится после системной даты.

Я сделал это сейчас:

label1->Text = "Data: " __DATE__;

Это в функции для установки даты называется DateTime(). Для кнопки я уже сделал событие щелчка, но мне нужно, чтобы DateTime() запускался динамически.

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

__DATE__ - константа времени компиляции. Это дата компиляции файла .cpp. Это не то, что вам нужно в данной ситуации.

RTL C ++ Builder имеет функцию Sysutils::Date(), которую вы можете использовать вместо нее, например:

#include <System.SysUtils.hpp>

label1->Text = _T("Data: ") + Date().DateString();

Date() возвращает TDateTime, представляющее текущую системную дату (если вы хотите также включить время, используйте вместо этого Sysutils::Now()). Его метод DateString() форматирует TDateTime в String с использованием настроек локали пользователя. Если вы хотите отформатировать TDateTime самостоятельно, вы можете использовать для этого его метод FormatString(), например:

#include <System.SysUtils.hpp>

label1->Text = _T("Data: ") + Date().FormatString(_T("yyyy-mm-dd"));
or:
label1->Text = Date().FormatString(_T("'Data: 'yyyy-mm-dd"));

Если вам нужно более стандартное решение C ++, посмотрите функции std::time() и std:::strftime(), например:

#include <ctime>

std::time_t now_c = std::time(nullptr);
std::tm now_tm = *std::localtime(&now_c);

char buffer[11] = {};
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d", &now_tm);
    
label1->Text = _T("Data: ") + String(buffer);
or:
label1->Text = String().sprintf(_T("Data: %s"), buffer);

Или посмотрите библиотеку <chrono>, представленную в C ++ 11, например std::chrono::system_clock, например:

#include <chrono>
#include <ctime>

std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm = *std::localtime(&now_c);

char buffer[11] = {};
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d", &now_tm);
    
label1->Text = _T("Data: ") + String(buffer);
or:
label1->Text = String().sprintf(_T("Data: %s"), buffer);

Альтернативно:

#include <chrono>
#include <ctime>
#include <sstream>
#include <iomanip>

std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm = *std::localtime(&now_c);

std::wostringstream oss;
oss << L"Data: " << std::put_time(&now_tm, L"%Y-%m-%d");

label1->Text = oss.str().c_str();
0 голосов
/ 05 августа 2020

Символ __DATE__ является макросом препроцессора , поэтому он определяется только во время компиляции.

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

Если вам нужна строка даты, которая отражает текущие системные часы / дату, тогда вам нужно будет использовать некоторую функцию, которая запрашивает систему для текущего, как time(). Определенно не макрос-строка препроцессора времени компиляции, как __DATE__. См. Другие функции ctime , которые помогут вам в форматировании нужной строки.

Наконец, о построении строки: вам нужно будет составлять строки во время выполнения примерно как sprintf делает. Ваша конструкция "Data: " __DATE__ действительна, потому что вы снова объединяете строку в качестве времени компиляции (это препроцессор компилятора, который выполняет объединение, а не ваша программа). Здесь вы можете прочитать об этой возможности препроцессора C. Кроме того, здесь описано, что это стандартное поведение C99, но не может сказать, не было ли оно определено в более раннем стандарте C.

...