1// Copyright 2016 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "cctz/time_zone.h"
16
17#include <cstdlib>
18#include <cstring>
19#include <string>
20
21#include "time_zone_fixed.h"
22#include "time_zone_impl.h"
23
24namespace cctz {
25
26std::string time_zone::name() const {
27 return time_zone::Impl::get(*this).name();
28}
29
30time_zone::absolute_lookup time_zone::lookup(
31 const time_point<sys_seconds>& tp) const {
32 return time_zone::Impl::get(*this).BreakTime(tp);
33}
34
35time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const {
36 return time_zone::Impl::get(*this).MakeTime(cs);
37}
38
39bool operator==(time_zone lhs, time_zone rhs) {
40 return &time_zone::Impl::get(lhs) == &time_zone::Impl::get(rhs);
41}
42
43bool load_time_zone(const std::string& name, time_zone* tz) {
44 return time_zone::Impl::LoadTimeZone(name, tz);
45}
46
47time_zone utc_time_zone() {
48 return time_zone::Impl::UTC(); // avoid name lookup
49}
50
51time_zone fixed_time_zone(const sys_seconds& offset) {
52 time_zone tz;
53 load_time_zone(FixedOffsetToName(offset), &tz);
54 return tz;
55}
56
57time_zone local_time_zone() {
58 const char* zone = ":localtime";
59
60 // Allow ${TZ} to override to default zone.
61 char* tz_env = nullptr;
62#if defined(_MSC_VER)
63 _dupenv_s(&tz_env, nullptr, "TZ");
64#else
65 tz_env = std::getenv("TZ");
66#endif
67 if (tz_env) zone = tz_env;
68
69 // We only support the "[:]<zone-name>" form.
70 if (*zone == ':') ++zone;
71
72 // Map "localtime" to a system-specific name, but
73 // allow ${LOCALTIME} to override the default name.
74 char* localtime_env = nullptr;
75 if (strcmp(zone, "localtime") == 0) {
76#if defined(_MSC_VER)
77 // System-specific default is just "localtime".
78 _dupenv_s(&localtime_env, nullptr, "LOCALTIME");
79#else
80 zone = "/etc/localtime"; // System-specific default.
81 localtime_env = std::getenv("LOCALTIME");
82#endif
83 if (localtime_env) zone = localtime_env;
84 }
85
86 const std::string name = zone;
87#if defined(_MSC_VER)
88 free(localtime_env);
89 free(tz_env);
90#endif
91
92 time_zone tz;
93 load_time_zone(name, &tz); // Falls back to UTC.
94 return tz;
95}
96
97} // namespace cctz
98