Каково самое маленькое количество байтов, которые могут сохранить метку времени?

Ваш каталог сеанса /var/cpanel/php/sessions/ea-php56/ на сервере может не существовать или у вас нет прав доступа к нему.

Создайте каталог, если он не существует с соответствующими разрешениями, или измените каталог сеанса в файле php.ini. Если у вас нет доступа к серверу, обратитесь к поставщику услуг.

Вы можете установить следующую строку перед доступом или созданием сеанса, чтобы изменить каталог сеанса для вашего скрипта.

ini_set('session.save_path', '/path/to/your/folder')

https://www.php.net/manual/en/function.session-save-path.php

11
задан Justin Tanner 4 January 2017 в 01:55
поделиться

12 ответов

Ну, Вы могли упаковать все это в unsigned short (Это составляет 2 байта, 5 битов в течение Дня, 5 битов в течение часа, 6 битов в течение минуты)..., и используйте некоторые сдвиги и маскирующий для получения значений.

unsigned short timestamp = <some value>; // Bits: DDDDDHHHHHMMMMMM

int day = (timestamp >> 11) & 0x1F;
int hour = (timestamp >> 6) & 0x1F;
int min = (timestamp) & 0x3F;

unsigned short dup_timestamp = (short)((day << 11) | (hour << 6) | min); 

или использование макросов

#define DAY(x)    (((x) >> 11) & 0x1F)
#define HOUR(x)   (((x) >> 6)  & 0x1F)
#define MINUTE(x) ((x)         & 0x3F)
#define TIMESTAMP(d, h, m) ((((d) & 0x1F) << 11) | (((h) & 0x1F) << 6) | ((m) & 0x3F)

(Вы не упоминали месяц/год в своей текущей версии вопроса, таким образом, я опустил их).

[Редактирование: использовать unsigned short - не подписанный short.]

17
ответ дан 3 December 2019 в 01:16
поделиться

Вы имеете в виду ЧАС 0-23 и МИНУТУ 0-59? Я услышал о секундах прыжка, но не минутах прыжка или часах.

(log (* 31 60 24) 2)
=> 15.446

Таким образом, можно соответствовать этим значениям 16 битов или 2 байта. Является ли это хорошей идеей или не является совершенно другим вопросом.

7
ответ дан 3 December 2019 в 01:16
поделиться
  • Месяц: расположитесь 1 - 12 => 4 бита
  • Дата: расположитесь 1 - 31 => 5 битов
  • Час: расположитесь 0 - 24 => 5 битов
  • Минута: расположитесь 0 - 60 => 6 битов

  • Общее количество: 20 битов

Можно использовать битовое поле и использовать компилятор/платформу определенная прагма для хранения ее трудной:

typedef struct packed_time_t {
    unsigned int month  : 4;
    unsigned int date   : 5;
    unsigned int hour   : 5;
    unsigned int minute : 6;
} packed_time_t; 

Но Вам действительно нужно это? Не был бы стандартные функции времени быть достаточно? Битовые поля варьируются в зависимости от архитектуры, дополняя и так далее... не портативную конструкцию.

5
ответ дан 3 December 2019 в 01:16
поделиться

Почему не только используют (4 байта?) вывод C time() функция с NULL как аргумент. Это - только время эпохи Unix (т.е. число секунд с 1-го января 1970). Как ответ Joe, это дает Вам намного больше комнаты для роста, чем какой-либо ответ, который пытается упаковать в течение многих месяцев и дней и лет в биты. Это стандартно. Преобразование time_t переменная к фактическому времени тривиальна в стандарте C (на Unix, по крайней мере) и большую часть времени, если Вам предназначили структуру данных для содержания 3-байтовой переменной, это может быть окружено к 4 байтам так или иначе.

Я знаю, что Вы пытаетесь оптимизировать в большой степени для размера, но 4 байта являются довольно чертовски маленькими. Даже если Вы усекаете от старшего байта, Вы все еще вытаскиваете 194 дня отличных времен из него.

Можно добраться еще больше из этого путем не торопления от time(NULL) и деление его 60 прежде, чем сохранить его, усекая его к минуте и храня это. 3 байта из этого дают Вам, как показано выше, 388 месяцев, и для 2 байтов можно сохранить 45 дней.

Я пошел бы с 4-байтовой версией, просто потому что я не вижу различия между 2, 3 и 4 байта, как являющиеся вообще значительным или жизненно важным ни для какого выполнения программы или не (если это не загрузчик). Это более просто добраться и более простой обработать и вероятно сохранит Вас много головных болей в конце.

Править: Код, который я отправил, не работал. У меня было 3 часа сна, и я выясню, как сделать битовое жонглирование правильно в конечном счете. До тех пор можно реализовать это сами.

4
ответ дан 3 December 2019 в 01:16
поделиться

Для варианта использования Вы описываете, (мелкое разрешение времен в 31-дневном диапазоне) я просто использовал бы 16-разрядный мелкий счетчик. При сериализации этих данных (к диску, сети) затем, можно использовать некоторое целое число переменной длины, кодирующее для сохранения байтов для маленьких значений.

2
ответ дан 3 December 2019 в 01:16
поделиться

Примечание: Исходный вопрос был отредактирован, и месяц больше не необходим. Исходные вычисления были ниже:

Это - просто вопрос того, сколько вычисления Вы хотите сделать. Самый трудный способ упаковать его состоит в том, если можно сделать собственный тип и использовать следующую математику для преобразования от и до ее соответствующего целого числа:

Допустимые диапазоны:

Month: 1-12 -> (0-11)+1
Day: 1-31 -> (0-30)+1
Hour: 0-24
Minute: 0-60

Можно выбрать порядок сохранить значения в (я удержу его вышеупомянутый порядок).

Month-1 Day-1  Hour   Minute
(0-11)  (0-30) (0-23) (0-59)

Сделайте немного умножения/подразделения для преобразования значений с помощью следующей формулы в качестве руководства:

value = (((Month - 1) * 31 + (Day - 1)) * 24 + Hour) * 60 + Minute

Так, у Вас есть минимальное значение 0 и максимальное значение ((11*31+30)*24+23)*60+59, который является 535,679. Таким образом, Вам нужен минимум на 20 битов для хранения этого значения как целого числа без знака (2^20-1 = 1,048,575; 2^19-1 = 524,287).

Если Вы хотите сделать вещи трудными, но сохранить байт, можно использовать 3 байта и управлять ими сами. Или можно использовать (32-разрядный) интервал и работать с ним обычно использование простых математических операторов.

НО существует некоторая комната для проигрывания с там хотя, поэтому давайте посмотрим, можем ли мы сделать это легче:

Допустимые диапазоны, снова:

Month: 1-12 -> (0-11)+1 --- 4 bits (you don't even need the -1)
Day: 1-31 -> (0-30)+1   --- 5 bits (you again don't need the -1) 
Hour: 0-24              --- 5 bits
Minute: 0-60            --- 6 bits

Это составляет в общей сложности 20 битов, и действительно легкий управлять. Таким образом, Вы ничего не получаете путем уплотнения дальше, чем использование простого смещения бита, и можно сохранить значение как это:

19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
---Month--- ----Day------- ---Hour--- --Minute---

Если Вы не заботитесь о месяце, самое трудное, которое можно получить:

value = ((Day - 1) * 24 + Hour) * 60 + Minute

отъезд Вас с диапазоном от 0 до 44 639, который может подойти аккуратно к 16-разрядному short.

Существует некоторая комната для проигрывания с там хотя, поэтому давайте посмотрим, можем ли мы сделать это легче:

Допустимые диапазоны, снова:

Day: 1-31 -> (0-30)+1 --- 5 bits (you don't even need the -1) 
Hour: 0-24            --- 5 bits
Minute: 0-60          --- 6 bits

Это составляет в общей сложности 16 битов, и снова действительно легкий управлять. Так.... хранят значение как это:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
----Day------- ---Hour--- --Minute---
4
ответ дан 3 December 2019 в 01:16
поделиться

В целом можно вычислить этот ответ следующим образом (где log2 является основой 2 логарифма, т.е. число битов):

  • Если Вы хотите использовать сдвиги и маски, чтобы вложить данные и, взять log2 () количества возможных значений для каждого поля, окружить (для получения битов), добавьте результаты (для получения общих битов), разделитесь на восемь (общие байты, w. дробные байты), и окружите снова (общие байты).

    log2 (60) + log2 (60) + log2 (24) + log2 (31) + log2 (12) = 6+6+5+5+4 = 26 битов = 4 байта

  • Если Вы хотите вложить поля и путем умножения и добавления / деление и по модулю, умножить вместе количество возможных значений для каждого поля и взять log2 () этого, разделиться на восемь и окружить.

    log2 (60*60*24*31*12) = 24,9379 бита = 4 байта

  • Можно сохранить крошечную дополнительную сумму пространства путем объединения неизоформальных полей (например, храня день года, а не месяца и день месяца), но это редко стоит того.

    log2 (60*60*24*366) = 24,91444 бита = 4 байта

- MarkusQ "учат человека ловить рыбу"

2
ответ дан 3 December 2019 в 01:16
поделиться

только предложить альтернативу:

  • если Вам только нужно разрешение мелкого уровня,
  • и Вы не пересекаете границы даты (месяц/год)
  • и Ваши сообщения последовательны с гарантируемой доставкой

затем можно сохранить метку времени как смещение от метки времени последнего сообщения.

В этом случае Вам только нужно достаточно битов для содержания максимального количества минут между сообщениями. Например, при испускании сообщений, самое большее на расстоянии в 255 минут затем один байт будет достаточен.

Обратите внимание, однако, что самое первое сообщение, возможно, должно включать абсолютную метку времени в свою полезную нагрузку для синхронизации.

[я не говорю, что это - хорошее решение - это довольно хрупко и делает много предположений - просто альтернативное]

1
ответ дан 3 December 2019 в 01:16
поделиться

5 битов в течение дня плюс 5 битов в течение часа плюс 6 битов в течение минуты равняются короткому целому без знака. Дальнейшая упаковка не уменьшила бы требуемое пространство памяти и увеличит использование CPU и сложность кода.

0
ответ дан 3 December 2019 в 01:16
поделиться

Упростить это без потери общности,

День (0 - 30), час (0 - 23), минута (0 - 59)

encoding = Day + (Hour + (Minute)*24)*31

Day = encoding %31
Hour = (encoding / 31) % 24
Minute = (encoding / 31) / 24

Максимальное значение кодирования 44639, который является немного меньше чем 16 битами.

Править: rampion, сказанный в основном то же самое. И это получает Вас минимальное представление, которое является меньше, чем поразрядное представление чередования.

0
ответ дан 3 December 2019 в 01:16
поделиться

Ну, игнорируя лишний ЧАС 24 и МИНУТА 60, у нас есть 31 x 24 x 60 = 44 640 возможных уникальных временных стоимостей. 2^15 = 32,768 <44,640 <65,536 = 2^16, таким образом, нам будут нужны по крайней мере 16 битов (2 байта) для представления этих значений.

Если мы не хотим делать арифметику по модулю для доступа к значениям каждый раз, когда мы, несомненно, должны будем сохранить каждого в его собственном битовом поле. Нам нужны 5 битов для хранения ДНЯ, 5 битов для хранения ЧАСА, и 6 битов для хранения МИНУТЫ, которая все еще помещается в 2 байта:

struct day_hour_minute {
  unsigned char DAY:5; 
  unsigned char HOUR:5;
  unsigned char MINUTE:6;
};

Включая МЕСЯЦ увеличил бы наши уникальные временные стоимости фактором 12, дав 535 680 уникальных значений, которые потребуют, чтобы по крайней мере 20 битов сохранили (2^19 = 524,288 <535,680 <1,048,576 = 2^20), который требует по крайней мере 3 байтов.

Снова, для предотвращения арифметики по модулю нам нужно отдельное битовое поле в течение МЕСЯЦА, который должен только потребовать 4 битов:

struct month_day_hour_minute {
  unsigned char MONTH:4;
  unsigned char DAY:5;
  unsigned char HOUR:5;
  unsigned char MINUTE:6;
  unsigned char unused: 4;
};

В обоих из этих примеров однако, знать, что C предпочитает, его структуры данных на сокращении - то есть, что они - кратные числа 4 или 8 байтов (обычно), таким образом, он может заполнить Ваши структуры данных вне того, что минимально необходимо.

Например, на моей машине,

#include <stdio.h>

struct day_hour_minute {
  unsigned int DAY:5;
  unsigned int HOUR:5;
  unsigned int MINUTE:6;
};
struct month_day_hour_minute {
  unsigned int MONTH:4;
  unsigned int DAY:5;
  unsigned int HOUR:5;
  unsigned int MINUTE:6;
  unsigned int unused: 4;
};

#define DI( i ) printf( #i " = %d\n", i )
int main(void) {
  DI( sizeof(struct day_hour_minute) );
  DI( sizeof(struct month_day_hour_minute) );
  return 0;
}

печать:

sizeof(struct day_hour_minute) = 4
sizeof(struct month_day_hour_minute) = 4
0
ответ дан 3 December 2019 в 01:16
поделиться

60 Минут/Час означают необходимость по крайней мере в 6 битах для хранения минуты (с 59-й минуты == 111011b), в то время как 24 Часа/День означают еще 5 битов (23-й час == 10111b). Если бы Вы хотите объяснить какой-либо (возможно) из 366 Дней/Год, Вам были бы нужны еще 9 битов (366-й день (365 когда день 1 == 0) == 101101101b). Таким образом, если бы Вы хотели сохранить все в чисто доступном формате, то Вам были бы нужны 20 битов == 3 байта. С другой стороны, добавление поля Month заставило бы общее возможное Дневное значение пойти от 366 до 31 - вниз к 5 битам с еще 4 битами в течение месяца. Это также дало бы Вам 20 битов или 3 байта с 4 битами для экономии.

С другой стороны, если бы Вы отслеживали дату только к минутам от некоторой даты начала, то 3 байта дали бы Вам разрешение 16 777 215 минут перед переворачиванием к 0 снова - это составляет приблизительно 279 620 часов, 11 650 дней и приблизительно 388 месяцев, и это использует все 24 бита. Это - вероятно, лучший способ пойти, если Вы не заботитесь о секундах, и если Вы не возражаете занимать определенное время выполнения для интерпретации часа, дня и месяца. И это было бы намного легче увеличить!

1
ответ дан 3 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: