OEMCrypto and OPK v20 prerelease initial commit
This commit is contained in:
223
util/include/wv_date_time.h
Normal file
223
util/include/wv_date_time.h
Normal file
@@ -0,0 +1,223 @@
|
||||
// Copyright 2025 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#ifndef WVCDM_UTIL_DATE_TIME_H_
|
||||
#define WVCDM_UTIL_DATE_TIME_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "wv_class_utils.h"
|
||||
#include "wv_duration.h"
|
||||
#include "wv_timestamp.h"
|
||||
|
||||
namespace wvutil {
|
||||
// The DateTime class represents a time point measured in UTC
|
||||
// Gregorian calendar dates and 24-hour timekeeping system.
|
||||
//
|
||||
// Internally, the time is measured in Unix Time (milliseconds
|
||||
// since January 1st, 1970 (epoch)).
|
||||
//
|
||||
// For the CDM, we are not concerned about time points before
|
||||
// January 1st, 1970; this class does not support negative epoch
|
||||
// seconds. In addition, zero is treated as a special value
|
||||
// which indicates an uninitialized time point.
|
||||
//
|
||||
// Min DateTime: 1970-01-01 00:00:00.001 (epoch ms = 1)
|
||||
// Max DateTime: 9999-12-31 23:59:59.999 (epoch ms = 253402300799999)
|
||||
//
|
||||
// Converting from Unix Time to datetime components is a potentially
|
||||
// expensive operation for their amount of utility; to reduce this
|
||||
// overhead date components are calculated once per change, and stored
|
||||
// individually.
|
||||
//
|
||||
// For testing, use the DateTime::Builder class for create DateTime
|
||||
// instances from their individual components.
|
||||
//
|
||||
// The DateTime class provides a PrintTo()/ToString() method which
|
||||
// returns an initialized DateTime in ISO 8601 format without timezone
|
||||
// indicator and with milliseconds only being printed if non-zero.
|
||||
// Use DateTime::Formatter for specific formatting needs.
|
||||
class DateTime {
|
||||
public:
|
||||
constexpr DateTime() = default; // Uninitialized DateTime.
|
||||
WVCDM_CONSTEXPR_DEFAULT_COPY_AND_MOVE(DateTime);
|
||||
|
||||
private:
|
||||
// Note: This private section is needed here.
|
||||
// clang++ with -Wundefined-inline will complain about certain
|
||||
// inline members not being declared before use in other inline
|
||||
// methods.
|
||||
template <class ToDuration>
|
||||
constexpr ToDuration EpochFloor() const {
|
||||
return std::chrono::floor<ToDuration>(epoch_milliseconds());
|
||||
}
|
||||
|
||||
public:
|
||||
static DateTime FromTimestamp(const Timestamp& timestamp);
|
||||
|
||||
// Create a DateTime instance from Unix Time in epoch seconds.
|
||||
// Optionally allowed to include |millisecond| (0 to 999).
|
||||
// If |epoch_seconds| or |millisecond| are invalid values, then an
|
||||
// uninitlaized DateTime instance is returned.
|
||||
static DateTime FromUnixSeconds(uint64_t epoch_seconds,
|
||||
uint32_t milliseconds = 0) {
|
||||
return FromTimestamp(
|
||||
Timestamp::FromUnixSeconds(epoch_seconds, milliseconds));
|
||||
}
|
||||
static DateTime FromUnixSeconds(const Seconds& epoch_seconds,
|
||||
uint32_t milliseconds = 0) {
|
||||
return FromTimestamp(
|
||||
Timestamp::FromUnixSeconds(epoch_seconds, milliseconds));
|
||||
}
|
||||
|
||||
// Create a DateTime instance from Unix Time in epoch milliseconds.
|
||||
// If |epoch_milliseconds| is an invalid value (zero), then an
|
||||
// uninitlaized DateTime instance is returned.
|
||||
static DateTime FromUnixMilliseconds(uint64_t epoch_milliseconds) {
|
||||
return FromTimestamp(Timestamp::FromUnixMilliseconds(epoch_milliseconds));
|
||||
}
|
||||
static DateTime FromUnixMilliseconds(const Milliseconds& epoch_milliseconds) {
|
||||
return FromTimestamp(Timestamp::FromUnixMilliseconds(epoch_milliseconds));
|
||||
}
|
||||
|
||||
// Obtain the minimum and maximum representable DateTime.
|
||||
static DateTime Min() { return FromTimestamp(Timestamp::Min()); }
|
||||
static DateTime Max() { return FromTimestamp(Timestamp::Max()); }
|
||||
|
||||
constexpr const Timestamp& timestamp() const { return timestamp_; }
|
||||
|
||||
// == Epoch Accessors ==
|
||||
constexpr Seconds epoch_seconds() const { return timestamp_.epoch_seconds(); }
|
||||
constexpr Milliseconds epoch_milliseconds() const {
|
||||
return timestamp_.epoch_milliseconds();
|
||||
}
|
||||
|
||||
// == Component Accessors ==
|
||||
// Year on Gregorian calendar (1970 - 9999; 0 if unset)
|
||||
constexpr uint32_t year() const { return year_; }
|
||||
// Month of the year (January = 1, December = 12; 0 if unset)
|
||||
constexpr uint32_t month() const { return month_; }
|
||||
// Day of the month (1 - 28/29/30/31; 0 if unset)
|
||||
constexpr uint32_t day() const { return day_; }
|
||||
// Day of the year (1 - 365/366; 0 if unset)
|
||||
constexpr uint32_t day_of_year() const { return day_of_year_; }
|
||||
// Day of the week (1 (Sunday) - 7 (Saturday); 0 if unset)
|
||||
constexpr uint32_t day_of_week() const { return day_of_week_; }
|
||||
|
||||
// Time component accessors.
|
||||
// Hour of day (0 - 23; 0 if unset)
|
||||
constexpr uint32_t hour() const {
|
||||
if (!IsSet()) return 0;
|
||||
return static_cast<uint32_t>(
|
||||
(EpochFloor<Hours>() - EpochFloor<Days>()).count());
|
||||
}
|
||||
// Minute of hour (0 - 59; 0 if unset)
|
||||
constexpr uint32_t minute() const {
|
||||
if (!IsSet()) return 0;
|
||||
return static_cast<uint32_t>(
|
||||
(EpochFloor<Minutes>() - EpochFloor<Hours>()).count());
|
||||
}
|
||||
// Second of minute (0 - 59; 0 if unset)
|
||||
constexpr uint32_t second() const {
|
||||
if (!IsSet()) return 0;
|
||||
return static_cast<uint32_t>(
|
||||
(EpochFloor<Seconds>() - EpochFloor<Minutes>()).count());
|
||||
}
|
||||
// Millisecond of second (0 - 999; 0 if unset)
|
||||
constexpr uint32_t millisecond() const { return timestamp_.milliseconds(); }
|
||||
|
||||
// Checks if the DateTime instance is set.
|
||||
constexpr bool IsSet() const { return timestamp_.IsSet(); }
|
||||
constexpr explicit operator bool() const { return IsSet(); }
|
||||
|
||||
constexpr void Clear() {
|
||||
timestamp_.Clear();
|
||||
ClearComponents();
|
||||
}
|
||||
|
||||
// == Comparison Operators ==
|
||||
constexpr bool IsEqualTo(const DateTime& other) const {
|
||||
return timestamp_.IsEqualTo(other.timestamp_);
|
||||
}
|
||||
constexpr int64_t CompareTo(const DateTime& other) const {
|
||||
return timestamp_.CompareTo(other.timestamp_);
|
||||
}
|
||||
WVCDM_DEFINE_CONSTEXPR_EQ_AND_CMP_OPERATORS(DateTime);
|
||||
|
||||
constexpr bool IsEqualTo(const Timestamp& other) const {
|
||||
return timestamp_.IsEqualTo(other);
|
||||
}
|
||||
constexpr int64_t CompareTo(const Timestamp& other) const {
|
||||
return timestamp_.CompareTo(other);
|
||||
}
|
||||
WVCDM_DEFINE_CONSTEXPR_EQ_AND_CMP_OPERATORS(Timestamp);
|
||||
|
||||
// == Duration Operators ==
|
||||
// Duration-based addition/subtraction operations.
|
||||
// Returns a new DateTime instance with time point adjusted by
|
||||
// the provided Duration.
|
||||
// If current DateTime instance is unset, or if result value
|
||||
// is outside the range of valid DateTime values, then an unset
|
||||
// DateTime is returned.
|
||||
DateTime operator+(const Duration& duration) const;
|
||||
DateTime operator-(const Duration& duration) const;
|
||||
|
||||
// DateTime difference.
|
||||
// Returns the duration between the two provided DateTime
|
||||
// instances.
|
||||
// If either DateTime instance is unset, then the resulting
|
||||
// Duration is zero.
|
||||
Duration operator-(const DateTime& other) const;
|
||||
|
||||
// Duration-based increment/decrement operators.
|
||||
// Increment or decrement the DateTime by the provided Duration
|
||||
// amount.
|
||||
// If current DateTime instance is unset, then no action will
|
||||
// occur. If result value is outside the range of valid DateTime
|
||||
// values, then DateTime will be unset.
|
||||
DateTime& operator+=(const Duration& duration);
|
||||
DateTime& operator-=(const Duration& duration);
|
||||
|
||||
// For initialized DateTime instances, returns the datetime
|
||||
// in ISO 8601 format. Milliseconds are only printed
|
||||
// if non-zero.
|
||||
// An uninitialized DateTime will return an empty string.
|
||||
// Ex:
|
||||
// Without milli: 2024-01-19T14:49:13Z
|
||||
// With milli: 2024-01-19T14:49:13.507Z
|
||||
// Use DateTime::Formatter for more formatting options.
|
||||
bool PrintTo(std::ostream* out) const;
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
// Special constructor.
|
||||
explicit DateTime(const Timestamp& timestamp);
|
||||
|
||||
// Attempts to calculate subcomponents.
|
||||
// Failure to calculate subcomponents will clear |timestamp_|.
|
||||
void UpdateTimestamp(const Timestamp& new_timestamp);
|
||||
|
||||
constexpr void ClearComponents() {
|
||||
year_ = month_ = day_ = day_of_year_ = day_of_week_ = 0;
|
||||
}
|
||||
|
||||
// Source of truth for DateTime class.
|
||||
Timestamp timestamp_;
|
||||
|
||||
// Components (derived from |timestamp_|).
|
||||
uint16_t year_ = 0;
|
||||
uint8_t month_ = 0;
|
||||
uint8_t day_ = 0;
|
||||
uint16_t day_of_year_ = 0;
|
||||
uint8_t day_of_week_ = 0;
|
||||
}; // class DateTime
|
||||
|
||||
// == GTest Printer ==
|
||||
void PrintTo(const DateTime& date_time, std::ostream* out);
|
||||
} // namespace wvutil
|
||||
#endif // WVCDM_UTIL_DATE_TIME_H_
|
||||
Reference in New Issue
Block a user