написать std :: string для сопоставимого * time * синтаксического анализатора, который может потерпеть неудачу

Я знаю, что size_t без знака и, следовательно, отрицательные значения недопустимы, time_t, насколько мне известно, подписано, поэтому мне разрешено присваивать -1 для size_t. Однако для time_t я не совсем уверен. Если я буду следовать определению через заголовочные файлы, я окажусь здесь:

typedef __time_t time_t;

, тогда здесь:

__STD_TYPE __TIME_T_TYPE __time_t;  /* Seconds since the Epoch.  */

и наконец

#define __TIME_T_TYPE       __SYSCALL_SLONG_TYPE

Я не слишком уверен, что __SYSCALL_SLONG_TYPE есть, но я думаю, что это подписанный долго. К сожалению, даже после этой трассировки, я могу только надеяться, что другие платформы C ++ 11 имеют такую ​​же реализацию. Я все еще не уверен, что это будет законно и четко определено для всех них:

size_t foo = -1;

Конечно, имеет смысл сделать time_t подписанным, так как можно иметь отрицательные смещения времени, например, для моделирования часовых поясов. Но, с другой стороны, имеет смысл оставить его без знака, потому что после 1970 года нужно считать много секунд. Так что здравый смысл идет в обе стороны 🙂 Поиск в time_t вернул следующее:

«По историческим причинам оно обычно реализуется как интегральное значение, представляющее количество секунд, прошедших с 00:00 часов, 1 января 1970 года по Гринвичу (т.е. временная метка Unix). Хотя библиотеки могут реализовывать этот тип с использованием альтернативных представлений времени».

Источник: http://www.cplusplus.com/reference/ctime/time_t/

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

Так что time_t совсем не определено во всех системах, однако time () возвращает time_t: так что я бы не стал первым экспортировать его в интерфейс. Какой другой тип я должен использовать?

Я спрашиваю по этим двум причинам:

  • Скорость: Используя структуру, как структура тм медленный, так как имеет больше байтов и, следовательно, копирование или сравнение его с другой структурой tm будет медленнее, чем выполнение того же самого с long.
  • Сортировка: Я хочу иметь быстрый тип данных для дат, который позволяет мне сделать < б, чтобы выяснить, какие из дат а и б на первом месте.

Вопрос: Поскольку time_t не является четко определенным представлением времени на всех платформах, какой тип данных, который является (1) быстрым и (2) сопоставимым, я могу использовать, который является переносимым?

Например, относительно порядка time_t:

#include <iostream>
#include <ctime>
#include <cstring>

int main() {
struct tm tm_a, tm_b;
memset(&tm_a, 0, sizeof(struct tm));
memset(&tm_b, 0, sizeof(struct tm));
if(strptime("2014-01-01 12:00:00", "%Y-%m-%d %H:%M:%s", &tm_a) && strptime("2014-01-01 11:59:59", "%Y-%m-%d %H:%M:%s", &tm_b)) {
if(mktime(&tm_a) > mktime(&tm_b)) std::cout << "time_t ordering OK." << std::endl;
else std::cout << "time_t ordering tainted" << std::endl;
} else std::cout << "failed to parse time" << std::endl;
return 0;
}

Будет время незапятнанный на всех платформах?

0

Решение

(time_t)(-1) уже означает «это не действительное время», независимо от того, что time_t на самом деле Стандартная функция mktime возвращает это значение при ошибке, вы тоже можете.

Стандарты C и C ++ ничего не говорят о кодировании времени в time_t, Стандартная функция difftime вычисляет разницу во времени в секундах, как doubleмежду двумя временами представлен как time_tи это единственный благословенный способ сделать заказ time_t ценности в хронологическом порядке. Тем не менее, стандарт POSIX указывает, что time_t время в секундах, поэтому в системе POSIX все в порядке time_t непосредственно с <,

Обратите внимание, что и C, и POSIX позволяют time_t быть любым арифметическим типом (не просто целым).

4

Другие решения

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

Например Boost.Date_Time, там вы можете выбрать любое представление, которое оно поддерживает. Вы даже можете использовать секунды, прошедшие с эпохи способом, который не зависит от платформы (на всех платформах, поддерживаемых boost).

1

Я стал зависимым от optional (через повышение, или сверните свое собственное основанное на C ++ 1y tr рабочий документ).

optional<foo> это либо foo или nullopt, Вы получаете доступ к foo через разграничение, но данные хранятся в optional через союз. Моя ленивая реализация использует указатель для foo или нет «, поскольку это делает отладку тривиальной.

Он передает сообщение об ошибке лучше, чем значения флага, и заменяет набор маркировок на основе указателей в коде, который я пишу.

0
По вопросам рекламы [email protected]