| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COBALT_SRC_LOCAL_AGGREGATION_CIVIL_TIME_MANAGER_H_ |
| #define COBALT_SRC_LOCAL_AGGREGATION_CIVIL_TIME_MANAGER_H_ |
| |
| #include "src/lib/util/datetime_util.h" |
| #include "src/public/lib/clock_interfaces.h" |
| #include "src/public/lib/statusor/status_macros.h" |
| #include "src/public/lib/statusor/statusor.h" |
| #include "src/registry/metric_definition.pb.h" |
| |
| namespace cobalt::local_aggregation { |
| |
| // A CivilTimeManager converts a specific initial time point to `TimeInfo`s for given time |
| // zones. It also provides and caches the `TimeInfo`s corresponding to time points at hourly |
| // increments before the initial time. |
| class CivilTimeManager { |
| public: |
| CivilTimeManager(std::chrono::system_clock::time_point initial_time, |
| const util::CivilTimeConverterInterface& civil_time_converter) |
| : initial_time_(initial_time), civil_time_converter_(civil_time_converter) { |
| cache_["UTC"][0] = util::TimeInfo::FromTimePointUtc(initial_time); |
| } |
| |
| // Returns the `TimeInfo` at the initial time with respect to UTC. |
| util::TimeInfo GetInitialUtc() { return cache_["UTC"][0]; } |
| |
| // Returns the `TimeInfo` at the initial time minus `past_hours`, with respect to the time zone |
| // policy of `metric`. |
| lib::statusor::StatusOr<util::TimeInfo> GetTimeInfo(int past_hours, |
| const MetricDefinition& metric) { |
| std::string time_zone_id = GetTimeZoneId(metric); |
| if (cache_[time_zone_id].count(past_hours) == 0) { |
| CB_ASSIGN_OR_RETURN(util::TimeInfo time_info, |
| util::TimeInfo::FromTimePoint(initial_time_ - util::kOneHour * past_hours, |
| civil_time_converter_, metric)); |
| cache_[time_zone_id].try_emplace(past_hours, time_info); |
| return time_info; |
| } |
| return cache_[time_zone_id][past_hours]; |
| } |
| |
| private: |
| static std::string GetTimeZoneId(const MetricDefinition& metric) { |
| switch (metric.time_zone_policy()) { |
| case MetricDefinition::UTC: |
| return "UTC"; |
| case MetricDefinition::LOCAL: |
| return "LOCAL"; |
| case MetricDefinition::OTHER_TIME_ZONE: |
| return metric.other_time_zone(); |
| default: |
| return ""; |
| } |
| } |
| |
| std::chrono::system_clock::time_point initial_time_; |
| const util::CivilTimeConverterInterface& civil_time_converter_; |
| // The top-level keys are time zone identifiers. For each time zone id, the entry at index `i` |
| // is the TimeInfo corresponding to the hour ID of `initial_time_` minus `i` hours. |
| std::map<std::string, std::map<int, util::TimeInfo>> cache_; |
| }; |
| |
| } // namespace cobalt::local_aggregation |
| |
| #endif // COBALT_SRC_LOCAL_AGGREGATION_CIVIL_TIME_MANAGER_H_ |