The implementation here was adapted from https://github.com/HowardHinnant/date/blob/040eed838bb1f695c31c6016dbe74bddc0302bb8/ src/tz.cpp#L3652 available under MIT license.
| 120 | // src/tz.cpp#L3652 |
| 121 | // available under MIT license. |
| 122 | string TimezoneDatabase::LocalZoneName() { |
| 123 | { |
| 124 | // Allow ${TZ} to override the default zone. |
| 125 | const char* zone = ":localtime"; |
| 126 | |
| 127 | char* tz_env = nullptr; |
| 128 | tz_env = getenv("TZ"); |
| 129 | if (tz_env) zone = tz_env; |
| 130 | |
| 131 | // We only support the "[:]<zone-name>" form. |
| 132 | if (*zone == ':') ++zone; |
| 133 | |
| 134 | if (strcmp(zone, "localtime") != 0) return string(zone); |
| 135 | |
| 136 | // Fall through to try other means. |
| 137 | } |
| 138 | |
| 139 | { |
| 140 | // Check /etc/localtime. |
| 141 | // - If it exists and is a symlink it should point to the current timezone file in the |
| 142 | // zoneinfo directory. |
| 143 | // - If it doesn't exist or is not a symlink we want to try other means. |
| 144 | const char* localtime = "/etc/localtime"; |
| 145 | bool is_symbolic_link; |
| 146 | string canonical_path; |
| 147 | Status status = FileSystemUtil::IsSymbolicLink(localtime, &is_symbolic_link, |
| 148 | &canonical_path); |
| 149 | if (!status.ok()) { |
| 150 | LOG(WARNING) << status.GetDetail(); |
| 151 | } else if (is_symbolic_link) { |
| 152 | string linked_tz; |
| 153 | if (FileSystemUtil::GetRelativePath(canonical_path, ZONE_INFO_DIR, &linked_tz) |
| 154 | && !linked_tz.empty()) { |
| 155 | return linked_tz; |
| 156 | } |
| 157 | |
| 158 | LOG(WARNING) << "Symbolic link " << localtime << " resolved to the wrong path: " |
| 159 | << canonical_path; |
| 160 | } |
| 161 | // Fall through to try other means. |
| 162 | } |
| 163 | |
| 164 | { |
| 165 | // On some versions of some linux distro's (e.g. Ubuntu), the current timezone might |
| 166 | // be in the first line of the /etc/timezone file. |
| 167 | ifstream timezone_file("/etc/timezone"); |
| 168 | if (timezone_file.is_open()) { |
| 169 | string result; |
| 170 | getline(timezone_file, result); |
| 171 | if (!result.empty()) return result; |
| 172 | } |
| 173 | // Fall through to try other means. |
| 174 | } |
| 175 | |
| 176 | { |
| 177 | // On some versions of some linux distro's (e.g. Red Hat), the current timezone might |
| 178 | // be in the first line of the /etc/sysconfig/clock file as: ZONE="US/Eastern" |
| 179 | ifstream timezone_file("/etc/sysconfig/clock"); |