количество секунд с начала недели? - PullRequest
0 голосов
/ 25 октября 2018

Я пробовал библиотеку дат Говарда.Существует множество примеров получения количества секунд с полуночи определенного дня, но не с начала недели, к которой относится этот день.Следуя примерам, я создал этот код:

using timepoint_t = std::chrono::time_point<
  std::chrono::system_clock,
  std::chrono::nanoseconds
>;

timepoint_t tp; // input
auto dp = std::chrono::floor<date::weeks>(tp); // output, should point to start of week?

Но результаты неверны.Например, tp:

2018-10-25T11:26:00.397836134Z

произведет dp:

2018-10-25T00:00:00.000000000Z 

, то есть полночь 25-го числа, а не полночь 21-го числа.Какой самый прямой способ получения правильного результата?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Я проголосовал за собственный ответ user1095108, так как он получает правильный ответ.Но я хотел добавить больше информации, которая не вписывалась бы в комментарий.

«Начало недели» не всегда согласовано.Некоторые страны переносят понедельник как начало недели, как и стандарт ISO.А другие страны отмечают воскресенье как начало недели.Эта библиотека старается сохранять нейтралитет в этом вопросе.

Даже если вы определите, какой день недели вы нацеливаете, вам также нужно определить, где на планете вы хотите принять во внимание при поиске второй.неделя начинается.

Судя по вашему коду, я предполагаю:

  1. Неделя начинается в воскресенье.
  2. Мы хотим найти началонеделю в соответствии с UTC.

Для следующего кода предположим:

using namespace date;
using namespace std::chrono;

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

Первое, что ябыло бы преобразовать входные данные в time_point с точностью до секунд:

auto tp = floor<seconds>(system_clock::now());

Затем, чтобы выполнить вычисления дня недели, такие как нахождение дня недели ввода tp, каждый собираетсянужно еще time_point с точностью до дней:

auto dp = floor<days>(tp);

Вы можете построить weekday прямо из точности дня time_point (dp), вместо того, чтобы проходить через более дорогиевычисление формирования year_month_weekday:

weekday{dp}

затем (как вы показываете) вычтите количество дней с начала недели:

dp -= weekday{dp} - Sunday;

Теперь у вас есть два time_point s: ваш ввод и начало недели.Вы можете просто вычесть их, чтобы получить количество секунд в неделю:

std::cout << tp - dp << '\n';

Теперь причина, по которой floor<weeks>(tp) не дает желаемого результата, состоит в том, что system_clock равно Unix Time.Эта мера отсчитывает время с 1970-01-01 00:00:00 UTC (без учета високосных секунд).И 1970-01-01 был четверг.Таким образом, усечение system_clock::time_point с точностью до weeks определяет «начало недели» как четверг.

Для еще большего удовольствия вычислите количество секунд с начала недели по местному времени., что может включать корректировки летнего времени.В этом случае вычисление дает более одного правильного ответа: считаете ли вы физические секунды, из-за которых у некоторых недель не получается ровно 604800 секунд, или вы считаете «календарными секундами»?Например, ноябрь / 4/2018 1:00 EST (Америка / New_York) 1 или 2 часа в неделю?Как только вы решите, какой ответ правильный, эта библиотека сможет его вычислить.

0 голосов
/ 25 октября 2018

Большинство расчетов календаря Говарда основаны на date:days.Так что, кажется, вам не повезло с date::weeks.Один из возможных ответов:

auto dp(std::chrono::floor<date::days>(tp));
dp -= date::year_month_weekday(dp).weekday() - date::Sunday;

Количество секунд затем получается как обычное std::chrono::duration_cast<std::chrono::seconds>( tp - dp).count().Может ли быть отсутствие поддержки date::weeks в std::chrono, что приведение date::weeks не работает?date::floor() Говарда дает тот же вывод, что и std::chrono::floor().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...