diff options
author | petrk <petrk@yandex-team.ru> | 2022-02-10 16:47:26 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:26 +0300 |
commit | af66956edf116b93d5a07894ccb61dd4447d0b34 (patch) | |
tree | 7b4cde47a2b3630f5a3048855949c4d46b893fc0 /library/cpp | |
parent | dc5feacd15e76abe98d23fe0d4ea3c02cb8de60f (diff) | |
download | ydb-af66956edf116b93d5a07894ccb61dd4447d0b34.tar.gz |
Restoring authorship annotation for <petrk@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/scheme/fwd.h | 14 | ||||
-rw-r--r-- | library/cpp/scheme/scheme.h | 4 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/civil.cpp | 110 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/civil.h | 404 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/convert.cpp | 82 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/convert.h | 30 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/ut/civil_ut.cpp | 60 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/ut/convert_ut.cpp | 26 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/ut/ya.make | 2 | ||||
-rw-r--r-- | library/cpp/timezone_conversion/ya.make | 2 |
10 files changed, 367 insertions, 367 deletions
diff --git a/library/cpp/scheme/fwd.h b/library/cpp/scheme/fwd.h index 975a034eb2..bc189708f7 100644 --- a/library/cpp/scheme/fwd.h +++ b/library/cpp/scheme/fwd.h @@ -1,7 +1,7 @@ -#pragma once - -namespace NSc { - class TValue; - class TDict; - class TArray; -} +#pragma once + +namespace NSc { + class TValue; + class TDict; + class TArray; +} diff --git a/library/cpp/scheme/scheme.h b/library/cpp/scheme/scheme.h index 3d7c59f3c9..8d711e660e 100644 --- a/library/cpp/scheme/scheme.h +++ b/library/cpp/scheme/scheme.h @@ -2,8 +2,8 @@ #include "scimpl_defs.h" -#include "fwd.h" - +#include "fwd.h" + #include <iterator> #include <utility> diff --git a/library/cpp/timezone_conversion/civil.cpp b/library/cpp/timezone_conversion/civil.cpp index 5986318b9a..7f0c5b9465 100644 --- a/library/cpp/timezone_conversion/civil.cpp +++ b/library/cpp/timezone_conversion/civil.cpp @@ -1,9 +1,9 @@ -#include "civil.h" - -#include <util/stream/output.h> -#include <util/stream/format.h> +#include "civil.h" + +#include <util/stream/output.h> +#include <util/stream/format.h> #include <util/string/ascii.h> - + namespace { bool TryParseInt(TStringBuf& s, int& dst, size_t maxDigits) { int res = 0; @@ -63,35 +63,35 @@ namespace { } } // anonymous namespace -namespace NDatetime { - TTimeZone GetTimeZone(TStringBuf name) { +namespace NDatetime { + TTimeZone GetTimeZone(TStringBuf name) { int offset; if (TryParseUTCOffsetTimezone(name, offset)) { return GetFixedTimeZone(offset); } - TTimeZone result; + TTimeZone result; if (!cctz::load_time_zone(static_cast<std::string>(name), &result)) { - ythrow TInvalidTimezone() << "Failed to load time zone " << name << ", " << result.name(); - } - return result; - } - + ythrow TInvalidTimezone() << "Failed to load time zone " << name << ", " << result.name(); + } + return result; + } + TTimeZone GetFixedTimeZone(const long offset) { return cctz::fixed_time_zone(std::chrono::seconds(offset)); } - TCivilSecond Convert(const TInstant& absTime, const TTimeZone& tz) { - return cctz::convert(TSystemClock::from_time_t(absTime.TimeT()), tz); - } - - TCivilSecond Convert(const TInstant& absTime, TStringBuf tzName) { - TTimeZone tz = GetTimeZone(tzName); - return cctz::convert(TSystemClock::from_time_t(absTime.TimeT()), tz); - } - - TInstant Convert(const TCivilSecond& tp, const TTimeZone& tz) { - return TInstant::Seconds(cctz::convert(tp, tz).time_since_epoch().count()); - } + TCivilSecond Convert(const TInstant& absTime, const TTimeZone& tz) { + return cctz::convert(TSystemClock::from_time_t(absTime.TimeT()), tz); + } + + TCivilSecond Convert(const TInstant& absTime, TStringBuf tzName) { + TTimeZone tz = GetTimeZone(tzName); + return cctz::convert(TSystemClock::from_time_t(absTime.TimeT()), tz); + } + + TInstant Convert(const TCivilSecond& tp, const TTimeZone& tz) { + return TInstant::Seconds(cctz::convert(tp, tz).time_since_epoch().count()); + } TCivilSecond AddYears(const TCivilSecond& tp, TDiff diff) { TCivilYear newYear = Calc<TCivilYear>(tp, diff); @@ -173,42 +173,42 @@ namespace NDatetime { } } } -} - -template <> +} + +template <> void Out<NDatetime::TCivilYear>(IOutputStream& out, const NDatetime::TCivilYear& y) { out << y.year(); -} - -template <> +} + +template <> void Out<NDatetime::TCivilMonth>(IOutputStream& out, const NDatetime::TCivilMonth& m) { - out << NDatetime::TCivilYear(m) << '-' << LeftPad(m.month(), 2, '0'); -} - -template <> + out << NDatetime::TCivilYear(m) << '-' << LeftPad(m.month(), 2, '0'); +} + +template <> void Out<NDatetime::TCivilDay>(IOutputStream& out, const NDatetime::TCivilDay& d) { - out << NDatetime::TCivilMonth(d) << '-' << LeftPad(d.day(), 2, '0'); -} - -template <> + out << NDatetime::TCivilMonth(d) << '-' << LeftPad(d.day(), 2, '0'); +} + +template <> void Out<NDatetime::TCivilHour>(IOutputStream& out, const NDatetime::TCivilHour& h) { - out << NDatetime::TCivilDay(h) << 'T' << LeftPad(h.hour(), 2, '0'); -} - -template <> + out << NDatetime::TCivilDay(h) << 'T' << LeftPad(h.hour(), 2, '0'); +} + +template <> void Out<NDatetime::TCivilMinute>(IOutputStream& out, const NDatetime::TCivilMinute& m) { - out << NDatetime::TCivilHour(m) << ':' << LeftPad(m.minute(), 2, '0'); -} - -template <> + out << NDatetime::TCivilHour(m) << ':' << LeftPad(m.minute(), 2, '0'); +} + +template <> void Out<NDatetime::TCivilSecond>(IOutputStream& out, const NDatetime::TCivilSecond& s) { - out << NDatetime::TCivilMinute(s) << ':' << LeftPad(s.second(), 2, '0'); -} - -template <> + out << NDatetime::TCivilMinute(s) << ':' << LeftPad(s.second(), 2, '0'); +} + +template <> void Out<NDatetime::TWeekday>(IOutputStream& out, NDatetime::TWeekday wd) { - using namespace cctz; - switch (wd) { + using namespace cctz; + switch (wd) { case weekday::monday: out << TStringBuf("Monday"); break; @@ -230,5 +230,5 @@ void Out<NDatetime::TWeekday>(IOutputStream& out, NDatetime::TWeekday wd) { case weekday::sunday: out << TStringBuf("Sunday"); break; - } -} + } +} diff --git a/library/cpp/timezone_conversion/civil.h b/library/cpp/timezone_conversion/civil.h index 0e95b807ed..b5917dad52 100644 --- a/library/cpp/timezone_conversion/civil.h +++ b/library/cpp/timezone_conversion/civil.h @@ -1,48 +1,48 @@ -#pragma once - -#include <util/datetime/base.h> - +#pragma once + +#include <util/datetime/base.h> + #include <contrib/libs/cctz/include/cctz/civil_time.h> #include <contrib/libs/cctz/include/cctz/time_zone.h> - -#include <util/generic/strbuf.h> -#include <util/generic/string.h> -#include <util/generic/yexception.h> - -#if __clang__ && __cpp_constexpr >= 201304 -#define CONSTEXPR_M constexpr -#else -#define CONSTEXPR_M inline -#endif - -namespace NDatetime { - /** Exception class which throws when time zone is not valid - */ - class TInvalidTimezone: public yexception { - }; - - using TSystemClock = std::chrono::system_clock; - using TTimePoint = std::chrono::time_point<TSystemClock>; - - /* - * An opaque class representing past, present, and future rules of - * mapping between absolute and civil times in a given region. - * It is very lightweight and may be passed by value. - */ - using TTimeZone = cctz::time_zone; - - using TCivilYear = cctz::civil_year; - using TCivilMonth = cctz::civil_month; - using TCivilDay = cctz::civil_day; - using TCivilHour = cctz::civil_hour; - using TCivilMinute = cctz::civil_minute; - using TCivilSecond = cctz::civil_second; - using TWeekday = cctz::weekday; - using TDiff = cctz::diff_t; - - using TYear = cctz::year_t; - using TMonth = cctz::detail::month_t; - + +#include <util/generic/strbuf.h> +#include <util/generic/string.h> +#include <util/generic/yexception.h> + +#if __clang__ && __cpp_constexpr >= 201304 +#define CONSTEXPR_M constexpr +#else +#define CONSTEXPR_M inline +#endif + +namespace NDatetime { + /** Exception class which throws when time zone is not valid + */ + class TInvalidTimezone: public yexception { + }; + + using TSystemClock = std::chrono::system_clock; + using TTimePoint = std::chrono::time_point<TSystemClock>; + + /* + * An opaque class representing past, present, and future rules of + * mapping between absolute and civil times in a given region. + * It is very lightweight and may be passed by value. + */ + using TTimeZone = cctz::time_zone; + + using TCivilYear = cctz::civil_year; + using TCivilMonth = cctz::civil_month; + using TCivilDay = cctz::civil_day; + using TCivilHour = cctz::civil_hour; + using TCivilMinute = cctz::civil_minute; + using TCivilSecond = cctz::civil_second; + using TWeekday = cctz::weekday; + using TDiff = cctz::diff_t; + + using TYear = cctz::year_t; + using TMonth = cctz::detail::month_t; + enum class ECivilUnit : int { Second = 0, Minute = 1, @@ -68,7 +68,7 @@ namespace NDatetime { template <ECivilUnit Unit> using TCivilTime = typename NDetail::TGetCivilTime<Unit>::TResult; - /** + /** * Class with variable unit diff. */ struct TCivilDiff { @@ -90,16 +90,16 @@ namespace NDatetime { }; /** - * Gets the time zone by an IANA name. - * @param name A name in IANA format (e.g., "Europe/Moscow"). - * @note After you request a time zone for the first time, it is cached - * in a (thread-safe) cache, so subsequent requests to the - * same time zone should be extremely fast. - * @throw TInvalidTimezone if the name is invalid. - * @see http://www.iana.org/time-zones - */ - TTimeZone GetTimeZone(TStringBuf name); - + * Gets the time zone by an IANA name. + * @param name A name in IANA format (e.g., "Europe/Moscow"). + * @note After you request a time zone for the first time, it is cached + * in a (thread-safe) cache, so subsequent requests to the + * same time zone should be extremely fast. + * @throw TInvalidTimezone if the name is invalid. + * @see http://www.iana.org/time-zones + */ + TTimeZone GetTimeZone(TStringBuf name); + /** * Returns a time zone that is a fixed offset (seconds east) from UTC. * Note: If the absolute value of the offset is greater than 24 hours @@ -118,42 +118,42 @@ namespace NDatetime { return cctz::convert(cctz::convert(src, from), to); } - /** Convert absolute time to civil time by rules from timezone. - * @param[in] absTime is an absolute time which is used to convert - * @param[in] tz is a loaded timezone - * @return a civil time + /** Convert absolute time to civil time by rules from timezone. + * @param[in] absTime is an absolute time which is used to convert + * @param[in] tz is a loaded timezone + * @return a civil time * * Note: This function doesn't work properly for dates before 1 Jan 1970! - */ - TCivilSecond Convert(const TInstant& absTime, const TTimeZone& tz); - - /** Convert absolute time to civil time by rules from timezone which will be loaded. - * @throw InvalidTimezone if the name is invalid. - * @param[in] absTime is an absolute time which is used to convert - * @param[in] tzName is a timezone name which will be loaded - * @return a civil time + */ + TCivilSecond Convert(const TInstant& absTime, const TTimeZone& tz); + + /** Convert absolute time to civil time by rules from timezone which will be loaded. + * @throw InvalidTimezone if the name is invalid. + * @param[in] absTime is an absolute time which is used to convert + * @param[in] tzName is a timezone name which will be loaded + * @return a civil time * * Note: This function doesn't work properly for dates before 1 Jan 1970! - */ - TCivilSecond Convert(const TInstant& absTime, TStringBuf tzName); - - /** Convert a civil time to absolute by using rules from timezone + */ + TCivilSecond Convert(const TInstant& absTime, TStringBuf tzName); + + /** Convert a civil time to absolute by using rules from timezone * * Note: This function doesn't work properly for dates before 1 Jan 1970! - */ - TInstant Convert(const TCivilSecond& s, const TTimeZone& tz); - - /** Just to simply calculations between dates/times. - * NDatetime::Calc<TCivilDay>(TCivilSecond(2001, 1, 1, 10, 10, 10), 5); // returns TCivilDay(2001, 1, 6); + */ + TInstant Convert(const TCivilSecond& s, const TTimeZone& tz); + + /** Just to simply calculations between dates/times. + * NDatetime::Calc<TCivilDay>(TCivilSecond(2001, 1, 1, 10, 10, 10), 5); // returns TCivilDay(2001, 1, 6); * @param[in] tp is a timepoint with which calc will be - * @param[in] diff is quantity of which will be added (of type T) to the tp - * @return the calculated T type - */ - template <typename T, typename S> + * @param[in] diff is quantity of which will be added (of type T) to the tp + * @return the calculated T type + */ + template <typename T, typename S> inline T Calc(const S& tp, TDiff diff) { - return T(tp) + diff; - } - + return T(tp) + diff; + } + /** Non-template methods for adding dates/times. * @param[in] tp is a timepoint with which calc will be * @param[in] diff is quantity of which will be added to the tp @@ -184,124 +184,124 @@ namespace NDatetime { */ TCivilDiff GetCivilDiff(const TCivilSecond& tpX, const TCivilSecond& tpY, ECivilUnit unit); - /** Formats the given TimePoint in the given TTimeZone according to - * the provided format string. Uses strftime()-like formatting options, - * with the following extensions: - * - * - %Ez - RFC3339-compatible numeric time zone (+hh:mm or -hh:mm) - * - %E#S - Seconds with # digits of fractional precision - * - %E*S - Seconds with full fractional precision (a literal '*') - * - %E#f - Fractional seconds with # digits of precision - * - %E*f - Fractional seconds with full precision (a literal '*') - * - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) - * - * Note that %E0S behaves like %S, and %E0f produces no characters. In - * contrast %E*f always produces at least one digit, which may be '0'. - * - * Note that %Y produces as many characters as it takes to fully render the - * year. A year outside of [-999:9999] when formatted with %E4Y will produce - * more than four characters, just like %Y. - * - * Tip: Format strings should include the UTC offset (e.g., %z or %Ez) so that - * the resultng string uniquely identifies an absolute time. - * - * Example: - * NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); - * NDatetime::TCivilSecond tp(2013, 1, 2, 3, 4, 5); - * TString f = NDatetime::Format("%H:%M:%S", tp, lax); // "03:04:05" - * TString f = NDatetime::Format("%H:%M:%E3S", tp, lax); //"03:04:05.000" - */ - template <typename TP> - TString Format(TStringBuf fmt, const TP& tp, const TTimeZone& tz) { + /** Formats the given TimePoint in the given TTimeZone according to + * the provided format string. Uses strftime()-like formatting options, + * with the following extensions: + * + * - %Ez - RFC3339-compatible numeric time zone (+hh:mm or -hh:mm) + * - %E#S - Seconds with # digits of fractional precision + * - %E*S - Seconds with full fractional precision (a literal '*') + * - %E#f - Fractional seconds with # digits of precision + * - %E*f - Fractional seconds with full precision (a literal '*') + * - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) + * + * Note that %E0S behaves like %S, and %E0f produces no characters. In + * contrast %E*f always produces at least one digit, which may be '0'. + * + * Note that %Y produces as many characters as it takes to fully render the + * year. A year outside of [-999:9999] when formatted with %E4Y will produce + * more than four characters, just like %Y. + * + * Tip: Format strings should include the UTC offset (e.g., %z or %Ez) so that + * the resultng string uniquely identifies an absolute time. + * + * Example: + * NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); + * NDatetime::TCivilSecond tp(2013, 1, 2, 3, 4, 5); + * TString f = NDatetime::Format("%H:%M:%S", tp, lax); // "03:04:05" + * TString f = NDatetime::Format("%H:%M:%E3S", tp, lax); //"03:04:05.000" + */ + template <typename TP> + TString Format(TStringBuf fmt, const TP& tp, const TTimeZone& tz) { return TString(cctz::format(static_cast<std::string>(fmt), TTimePoint(cctz::convert(tp, tz)), tz)); - } - - /** Returns the weekday by day. - * @param[in] day is a given day - * @return a weekday (enum) - */ - CONSTEXPR_M TWeekday GetWeekday(const TCivilDay& day) noexcept { - return cctz::get_weekday(day); - } - - /** Returns the TCivilDay that strictly follows or precedes the given - * civil_day, and that falls on the given weekday. - * @code - For example, given: - - August 2015 - Su Mo Tu We Th Fr Sa - 1 - 2 3 4 5 6 7 8 - 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 - 23 24 25 26 27 28 29 - 30 31 - - TCivilDay a(2015, 8, 13); // GetWeekday(a) == TWeekday::thursday - TCivilDay b = NextWeekday(a, TWeekday::thursday); // b = 2015-08-20 - TCivilDay c = PrevWeekday(a, TWeekday::thursday); // c = 2015-08-06 - TCivilDay d = NearestWeekday(a, TWeekday::thursday); // d = 2015-08-13 - - TCivilDay e = ... - // Gets the following Thursday if e is not already Thursday - TCivilDay thurs1 = PrevWeekday(e, TWeekday::thursday) + 7; - // Gets the previous Thursday if e is not already Thursday - TCivilDay thurs2 = NextWeekday(e, TWeekday::thursday) - 7; - * @endcode - * @see PrevWeekday() - * @see NearestWeekday() - * @param[in] cd is a current day - * @param[in] wd is a weekday which wanetd for find on next week - * @return a civil day on weekday next week - */ - CONSTEXPR_M TCivilDay NextWeekday(const TCivilDay& cd, TWeekday wd) noexcept { - return cctz::next_weekday(cd, wd); - } - - /** Returns prev weekday. See the description of NextWeekday(). - * @see NextWeekday() - * @see NearestWeekday() - * @param[in] cd is a current day - * @param[in] wd is a weekday which is looking for (backward) - * @return a first occurence of the given weekday (backward) - */ - CONSTEXPR_M TCivilDay PrevWeekday(const TCivilDay& cd, TWeekday wd) noexcept { - return cctz::prev_weekday(cd, wd); - } - - /** Find a nearest occurence of the given weekday forward (could be current day). - * @see NextWeekday() - * @param[in] cd is a current day - * @param[in] wd is a weekday which is looking for (current day or later) - * @return first occurence (including current day) of the given weekday - */ - CONSTEXPR_M TCivilDay NearestWeekday(const TCivilDay& cd, TWeekday wd) noexcept { - return get_weekday(cd) != wd ? next_weekday(cd, wd) : cd; - } - - /** Find the date of the given weekday within the given week. - * @param[in] cd is a current day - * @param[in] wd is a requested week day - * @return day within a week of a given day - */ - CONSTEXPR_M TCivilDay WeekdayOnTheWeek(const TCivilDay& cd, TWeekday wd) noexcept { - const auto d = get_weekday(cd); - if (d == wd) - return cd; - - return d < wd ? NextWeekday(cd, wd) : PrevWeekday(cd, wd); - } - - /** Returns an absolute day of year by given day. - */ - CONSTEXPR_M int GetYearDay(const TCivilDay& cd) noexcept { - return cctz::get_yearday(cd); - } - - CONSTEXPR_M int DaysPerMonth(TYear year, TMonth month) noexcept { - return cctz::detail::impl::days_per_month(year, month); - } + } + + /** Returns the weekday by day. + * @param[in] day is a given day + * @return a weekday (enum) + */ + CONSTEXPR_M TWeekday GetWeekday(const TCivilDay& day) noexcept { + return cctz::get_weekday(day); + } + + /** Returns the TCivilDay that strictly follows or precedes the given + * civil_day, and that falls on the given weekday. + * @code + For example, given: + + August 2015 + Su Mo Tu We Th Fr Sa + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 + 23 24 25 26 27 28 29 + 30 31 + + TCivilDay a(2015, 8, 13); // GetWeekday(a) == TWeekday::thursday + TCivilDay b = NextWeekday(a, TWeekday::thursday); // b = 2015-08-20 + TCivilDay c = PrevWeekday(a, TWeekday::thursday); // c = 2015-08-06 + TCivilDay d = NearestWeekday(a, TWeekday::thursday); // d = 2015-08-13 + + TCivilDay e = ... + // Gets the following Thursday if e is not already Thursday + TCivilDay thurs1 = PrevWeekday(e, TWeekday::thursday) + 7; + // Gets the previous Thursday if e is not already Thursday + TCivilDay thurs2 = NextWeekday(e, TWeekday::thursday) - 7; + * @endcode + * @see PrevWeekday() + * @see NearestWeekday() + * @param[in] cd is a current day + * @param[in] wd is a weekday which wanetd for find on next week + * @return a civil day on weekday next week + */ + CONSTEXPR_M TCivilDay NextWeekday(const TCivilDay& cd, TWeekday wd) noexcept { + return cctz::next_weekday(cd, wd); + } + + /** Returns prev weekday. See the description of NextWeekday(). + * @see NextWeekday() + * @see NearestWeekday() + * @param[in] cd is a current day + * @param[in] wd is a weekday which is looking for (backward) + * @return a first occurence of the given weekday (backward) + */ + CONSTEXPR_M TCivilDay PrevWeekday(const TCivilDay& cd, TWeekday wd) noexcept { + return cctz::prev_weekday(cd, wd); + } + + /** Find a nearest occurence of the given weekday forward (could be current day). + * @see NextWeekday() + * @param[in] cd is a current day + * @param[in] wd is a weekday which is looking for (current day or later) + * @return first occurence (including current day) of the given weekday + */ + CONSTEXPR_M TCivilDay NearestWeekday(const TCivilDay& cd, TWeekday wd) noexcept { + return get_weekday(cd) != wd ? next_weekday(cd, wd) : cd; + } + + /** Find the date of the given weekday within the given week. + * @param[in] cd is a current day + * @param[in] wd is a requested week day + * @return day within a week of a given day + */ + CONSTEXPR_M TCivilDay WeekdayOnTheWeek(const TCivilDay& cd, TWeekday wd) noexcept { + const auto d = get_weekday(cd); + if (d == wd) + return cd; + + return d < wd ? NextWeekday(cd, wd) : PrevWeekday(cd, wd); + } + + /** Returns an absolute day of year by given day. + */ + CONSTEXPR_M int GetYearDay(const TCivilDay& cd) noexcept { + return cctz::get_yearday(cd); + } + + CONSTEXPR_M int DaysPerMonth(TYear year, TMonth month) noexcept { + return cctz::detail::impl::days_per_month(year, month); + } CONSTEXPR_M int DaysPerYear(TYear year, TMonth month) noexcept { return cctz::detail::impl::days_per_year(year, month); @@ -331,8 +331,8 @@ namespace NDatetime { return (daysCount + static_cast<int>(jan1) - 1) / 7 + (jan1 == cctz::weekday::monday || jan1 == cctz::weekday::tuesday || jan1 == cctz::weekday::wednesday); } -} - +} + #include "civil-inl.h" -#undef CONSTEXPR_M +#undef CONSTEXPR_M diff --git a/library/cpp/timezone_conversion/convert.cpp b/library/cpp/timezone_conversion/convert.cpp index 490bb4e270..d668362788 100644 --- a/library/cpp/timezone_conversion/convert.cpp +++ b/library/cpp/timezone_conversion/convert.cpp @@ -1,7 +1,7 @@ #include "convert.h" #include <contrib/libs/cctz/include/cctz/civil_time.h> - + #include <util/generic/yexception.h> #include <chrono> @@ -9,23 +9,23 @@ namespace NDatetime { static constexpr i64 TM_YEAR_OFFSET = 1900; using TSystemClock = std::chrono::system_clock; - using TTimePoint = std::chrono::time_point<TSystemClock>; - - static TSimpleTM CivilToTM(const cctz::civil_second& cs, const cctz::time_zone::absolute_lookup& al) { - cctz::civil_day cd(cs); - TSimpleTM tm; - tm.GMTOff = al.offset; - tm.Year = cs.year() - TM_YEAR_OFFSET; - tm.YDay = cctz::get_yearday(cd); - tm.Mon = cs.month() - 1; - tm.MDay = cs.day(); - tm.Hour = cs.hour(); - tm.Min = cs.minute(); - tm.Sec = cs.second(); - tm.IsDst = al.is_dst; - tm.IsLeap = LeapYearAD(cs.year()); + using TTimePoint = std::chrono::time_point<TSystemClock>; - switch (cctz::get_weekday(cd)) { + static TSimpleTM CivilToTM(const cctz::civil_second& cs, const cctz::time_zone::absolute_lookup& al) { + cctz::civil_day cd(cs); + TSimpleTM tm; + tm.GMTOff = al.offset; + tm.Year = cs.year() - TM_YEAR_OFFSET; + tm.YDay = cctz::get_yearday(cd); + tm.Mon = cs.month() - 1; + tm.MDay = cs.day(); + tm.Hour = cs.hour(); + tm.Min = cs.minute(); + tm.Sec = cs.second(); + tm.IsDst = al.is_dst; + tm.IsLeap = LeapYearAD(cs.year()); + + switch (cctz::get_weekday(cd)) { case cctz::weekday::monday: tm.WDay = 1; break; @@ -47,47 +47,47 @@ namespace NDatetime { case cctz::weekday::sunday: tm.WDay = 0; break; - } - - return tm; - } - - /* + } + + return tm; + } + + /* TTimeZone GetTimeZone(const TString& name) { TTimeZone result; - if (!cctz::load_time_zone(name, &result)) { - ythrow yexception() << "Failed to load time zone " << name << ", " << result.name(); + if (!cctz::load_time_zone(name, &result)) { + ythrow yexception() << "Failed to load time zone " << name << ", " << result.name(); } return result; } - */ + */ TTimeZone GetUtcTimeZone() { - return cctz::utc_time_zone(); + return cctz::utc_time_zone(); } TTimeZone GetLocalTimeZone() { - return cctz::local_time_zone(); + return cctz::local_time_zone(); } TSimpleTM ToCivilTime(const TInstant& absoluteTime, const TTimeZone& tz) { - TTimePoint tp = TSystemClock::from_time_t(absoluteTime.TimeT()); - return CivilToTM(cctz::convert(tp, tz), tz.lookup(tp)); - } + TTimePoint tp = TSystemClock::from_time_t(absoluteTime.TimeT()); + return CivilToTM(cctz::convert(tp, tz), tz.lookup(tp)); + } - TSimpleTM CreateCivilTime(const TTimeZone& tz, ui32 year, ui32 mon, ui32 day, ui32 h, ui32 m, ui32 s) { - cctz::civil_second cs(year, mon, day, h, m, s); - return CivilToTM(cs, tz.lookup(tz.lookup(cs).pre)); + TSimpleTM CreateCivilTime(const TTimeZone& tz, ui32 year, ui32 mon, ui32 day, ui32 h, ui32 m, ui32 s) { + cctz::civil_second cs(year, mon, day, h, m, s); + return CivilToTM(cs, tz.lookup(tz.lookup(cs).pre)); } TInstant ToAbsoluteTime(const TSimpleTM& civilTime, const TTimeZone& tz) { - cctz::civil_second cs( - civilTime.Year + TM_YEAR_OFFSET, - civilTime.Mon + 1, - civilTime.MDay, - civilTime.Hour, - civilTime.Min, + cctz::civil_second cs( + civilTime.Year + TM_YEAR_OFFSET, + civilTime.Mon + 1, + civilTime.MDay, + civilTime.Hour, + civilTime.Min, civilTime.Sec); - return TInstant::Seconds(TSystemClock::to_time_t(tz.lookup(cs).pre)); + return TInstant::Seconds(TSystemClock::to_time_t(tz.lookup(cs).pre)); } } diff --git a/library/cpp/timezone_conversion/convert.h b/library/cpp/timezone_conversion/convert.h index 768a9e110f..2e76d683ed 100644 --- a/library/cpp/timezone_conversion/convert.h +++ b/library/cpp/timezone_conversion/convert.h @@ -1,7 +1,7 @@ #pragma once -#include "civil.h" - +#include "civil.h" + #include <contrib/libs/cctz/include/cctz/time_zone.h> #include <util/datetime/base.h> #include <util/draft/datetime.h> @@ -31,19 +31,19 @@ namespace NDatetime { TSimpleTM ToCivilTime(const TInstant& absoluteTime, const TTimeZone& tz); /** - * Creates civil time in place with respect of given timezone. - * @param[in] tz The time zone to use for creation. - * @param[in] year The year of the creation time. - * @param[in] mon The month of the creation time. - * @param[in] day The day of the creation time. - * @param[in] h The hour of the creation time. - * @param[in] m The minute of the creation time. - * @param[in] s The second of the creation time. - * @return a civil time - */ - TSimpleTM CreateCivilTime(const TTimeZone& tz, ui32 year, ui32 mon, ui32 day, ui32 h = 0, ui32 m = 0, ui32 s = 0); - - /** + * Creates civil time in place with respect of given timezone. + * @param[in] tz The time zone to use for creation. + * @param[in] year The year of the creation time. + * @param[in] mon The month of the creation time. + * @param[in] day The day of the creation time. + * @param[in] h The hour of the creation time. + * @param[in] m The minute of the creation time. + * @param[in] s The second of the creation time. + * @return a civil time + */ + TSimpleTM CreateCivilTime(const TTimeZone& tz, ui32 year, ui32 mon, ui32 day, ui32 h = 0, ui32 m = 0, ui32 s = 0); + + /** * @param civilTime A human-readable date and time (the following fields * are used by this function: {Year,Mon,MDay,Hour,Min,Sec}). * @param tz The time zone to use for conversion. diff --git a/library/cpp/timezone_conversion/ut/civil_ut.cpp b/library/cpp/timezone_conversion/ut/civil_ut.cpp index a21bd4bd7d..62d0b7aa02 100644 --- a/library/cpp/timezone_conversion/ut/civil_ut.cpp +++ b/library/cpp/timezone_conversion/ut/civil_ut.cpp @@ -1,9 +1,9 @@ #include <library/cpp/timezone_conversion/civil.h> #include <library/cpp/testing/unittest/registar.h> #include <library/cpp/testing/unittest/tests_data.h> - -#include <util/stream/str.h> - + +#include <util/stream/str.h> + namespace NDatetime { inline bool operator==(const NDatetime::TCivilDiff& x, const NDatetime::TCivilDiff& y) { return x.Unit == y.Unit && x.Value == y.Value; @@ -17,10 +17,10 @@ inline void Out<NDatetime::TCivilDiff>(IOutputStream& out, const NDatetime::TCiv Y_UNIT_TEST_SUITE(DateTime) { Y_UNIT_TEST(Calc) { - NDatetime::TCivilSecond s(2017, 2, 1, 10, 12, 9); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::Calc<NDatetime::TCivilDay>(s, 2), NDatetime::TCivilDay(2017, 2, 3)); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::Calc<NDatetime::TCivilDay>(s, -2), NDatetime::TCivilDay(2017, 1, 30)); - } + NDatetime::TCivilSecond s(2017, 2, 1, 10, 12, 9); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::Calc<NDatetime::TCivilDay>(s, 2), NDatetime::TCivilDay(2017, 2, 3)); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::Calc<NDatetime::TCivilDay>(s, -2), NDatetime::TCivilDay(2017, 1, 30)); + } Y_UNIT_TEST(Adds) { NDatetime::TCivilSecond s(2017, 2, 1, 10, 12, 9); UNIT_ASSERT_VALUES_EQUAL(NDatetime::AddDays(s, 2), NDatetime::TCivilSecond(2017, 2, 3, 10, 12, 9)); @@ -29,14 +29,14 @@ Y_UNIT_TEST_SUITE(DateTime) { UNIT_ASSERT_VALUES_EQUAL(NDatetime::AddHours(s, 40), NDatetime::TCivilSecond(2017, 2, 3, 2, 12, 9)); } Y_UNIT_TEST(Convert) { - TInstant absTime = TInstant::Seconds(1500299239); - NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); - NDatetime::TCivilSecond dt1 = NDatetime::Convert(absTime, lax); - NDatetime::TCivilSecond dt2(2017, 7, 17, 6, 47, 19); - UNIT_ASSERT_VALUES_EQUAL(dt1, dt2); - UNIT_ASSERT_VALUES_EQUAL(absTime, NDatetime::Convert(dt2, lax)); - UNIT_ASSERT_EXCEPTION(NDatetime::Convert(absTime, "Unknown time zone"), NDatetime::TInvalidTimezone); - } + TInstant absTime = TInstant::Seconds(1500299239); + NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); + NDatetime::TCivilSecond dt1 = NDatetime::Convert(absTime, lax); + NDatetime::TCivilSecond dt2(2017, 7, 17, 6, 47, 19); + UNIT_ASSERT_VALUES_EQUAL(dt1, dt2); + UNIT_ASSERT_VALUES_EQUAL(absTime, NDatetime::Convert(dt2, lax)); + UNIT_ASSERT_EXCEPTION(NDatetime::Convert(absTime, "Unknown time zone"), NDatetime::TInvalidTimezone); + } Y_UNIT_TEST(UTCOffsetTimezone) { NDatetime::TTimeZone lax = NDatetime::GetTimeZone("UTC+12"); auto lookup = lax.lookup(std::chrono::system_clock::from_time_t(0)); @@ -67,21 +67,21 @@ Y_UNIT_TEST_SUITE(DateTime) { UNIT_ASSERT_EXCEPTION(NDatetime::GetTimeZone("UTC+20:30:"), NDatetime::TInvalidTimezone); } Y_UNIT_TEST(Format) { - NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); - NDatetime::TCivilSecond tp(2013, 1, 2, 3, 4, 5); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::Format("%H:%M:%S", tp, lax), "03:04:05"); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::Format("%H:%M:%E3S", tp, lax), "03:04:05.000"); - } + NDatetime::TTimeZone lax = NDatetime::GetTimeZone("America/Los_Angeles"); + NDatetime::TCivilSecond tp(2013, 1, 2, 3, 4, 5); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::Format("%H:%M:%S", tp, lax), "03:04:05"); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::Format("%H:%M:%E3S", tp, lax), "03:04:05.000"); + } Y_UNIT_TEST(Weekday) { - NDatetime::TCivilDay d(2013, 1, 2); - NDatetime::TWeekday wd = NDatetime::GetWeekday(d); - UNIT_ASSERT_VALUES_EQUAL(wd, NDatetime::TWeekday::wednesday); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::NextWeekday(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2013, 1, 7)); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::PrevWeekday(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2012, 12, 31)); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2012, 12, 31)); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::wednesday), NDatetime::TCivilDay(2013, 1, 2)); - UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::friday), NDatetime::TCivilDay(2013, 1, 4)); - } + NDatetime::TCivilDay d(2013, 1, 2); + NDatetime::TWeekday wd = NDatetime::GetWeekday(d); + UNIT_ASSERT_VALUES_EQUAL(wd, NDatetime::TWeekday::wednesday); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::NextWeekday(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2013, 1, 7)); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::PrevWeekday(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2012, 12, 31)); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::monday), NDatetime::TCivilDay(2012, 12, 31)); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::wednesday), NDatetime::TCivilDay(2013, 1, 2)); + UNIT_ASSERT_VALUES_EQUAL(NDatetime::WeekdayOnTheWeek(d, NDatetime::TWeekday::friday), NDatetime::TCivilDay(2013, 1, 4)); + } Y_UNIT_TEST(CivilUnit) { using namespace NDatetime; @@ -154,4 +154,4 @@ Y_UNIT_TEST_SUITE(DateTime) { // Max possible delta - calcuate week # for 31 Dec 2021 from 1 Jan 2020 UNIT_ASSERT_VALUES_EQUAL(NDatetime::GetYearWeek(NDatetime::TCivilDay{2021, 12, 31}, true), 105); } -} +} diff --git a/library/cpp/timezone_conversion/ut/convert_ut.cpp b/library/cpp/timezone_conversion/ut/convert_ut.cpp index bbf9e9b826..f037af4377 100644 --- a/library/cpp/timezone_conversion/ut/convert_ut.cpp +++ b/library/cpp/timezone_conversion/ut/convert_ut.cpp @@ -87,13 +87,13 @@ TEST(TimeZoneConversion, TestRepeatedDate) { ToCivilTime(TInstant::Seconds(1288474200), ekb)); CompareCivilTimes( - ZonedTm(+5, false, 2016, 5, 10, 9, 8, 7), - CreateCivilTime(ekb, 2016, 5, 10, 9, 8, 7)); - + ZonedTm(+5, false, 2016, 5, 10, 9, 8, 7), + CreateCivilTime(ekb, 2016, 5, 10, 9, 8, 7)); + CompareCivilTimes( - ZonedTm(+6, true, 2010, 10, 31, 2, 30, 0), - CreateCivilTime(ekb, 2010, 10, 31, 2, 30, 0)); - + ZonedTm(+6, true, 2010, 10, 31, 2, 30, 0), + CreateCivilTime(ekb, 2010, 10, 31, 2, 30, 0)); + // The earlier timestamp should be chosen. EXPECT_EQ( TInstant::Seconds(1288470600), @@ -186,13 +186,13 @@ TEST(TimeZoneConversion, TestFutureDstChanges) { ZonedTm(+0, false, 2025, 11, 10, 19, 31, 0)); } -TEST(TimeZoneConversion, TWDay) { - TTimeZone nsk = GetTimeZone("Asia/Novosibirsk"); - - for (time_t e = 1301167800, to = 1301167800 + 86400 * 7, dow = 0; e < to; e += 86400, ++dow) { - EXPECT_EQ(dow, ToCivilTime(TInstant::Seconds(e), nsk).WDay); - } -} +TEST(TimeZoneConversion, TWDay) { + TTimeZone nsk = GetTimeZone("Asia/Novosibirsk"); + + for (time_t e = 1301167800, to = 1301167800 + 86400 * 7, dow = 0; e < to; e += 86400, ++dow) { + EXPECT_EQ(dow, ToCivilTime(TInstant::Seconds(e), nsk).WDay); + } +} TEST(TimeZoneConversion, TestBaikonur) { // Yes, the Baikonur spaceport is located in Kyzylorda Region. diff --git a/library/cpp/timezone_conversion/ut/ya.make b/library/cpp/timezone_conversion/ut/ya.make index 781a57da9f..522722238e 100644 --- a/library/cpp/timezone_conversion/ut/ya.make +++ b/library/cpp/timezone_conversion/ut/ya.make @@ -9,7 +9,7 @@ PEERDIR( SRCS( convert_ut.cpp - civil_ut.cpp + civil_ut.cpp ) END() diff --git a/library/cpp/timezone_conversion/ya.make b/library/cpp/timezone_conversion/ya.make index f99ebe73ee..beb74532a7 100644 --- a/library/cpp/timezone_conversion/ya.make +++ b/library/cpp/timezone_conversion/ya.make @@ -12,7 +12,7 @@ PEERDIR( SRCS( convert.cpp - civil.cpp + civil.cpp ) GENERATE_ENUM_SERIALIZATION(civil.h) |