[Enhance] Add prepare phase for some timestamp functions (#3947)

Fix: #3946 

CL:
1. Add prepare phase for `from_unixtime()`, `date_format()` and `convert_tz()` functions, to handle the format string once for all.
2. Find the cctz timezone when init `runtime state`, so that don't need to find timezone for each rows.
3. Add constant rewrite rule for `utc_timestamp()`
4. Add doc for `to_date()`
5. Comment out the `push_handler_test`, it can not run in DEBUG mode, will be fixed later.
6. Remove `timezone_db.h/cpp` and add `timezone_utils.h/cpp`

The performance shows bellow:

11,000,000 rows

SQL1: `select count(from_unixtime(k1)) from tbl1;`
Before: 8.85s
After: 2.85s

SQL2: `select count(from_unixtime(k1, '%Y-%m-%d %H:%i:%s')) from tbl1 limit 1;`
Before: 10.73s
After: 4.85s

The date string format seems still slow, we may need a further enhancement about it.
This commit is contained in:
Mingyu Chen
2020-06-29 19:15:09 +08:00
committed by GitHub
parent 9671394015
commit af1beb6ce4
21 changed files with 423 additions and 568 deletions

View File

@ -53,7 +53,6 @@
#include "exprs/json_functions.h"
#include "exprs/hll_hash_function.h"
#include "exprs/grouping_sets_functions.h"
#include "exprs/timezone_db.h"
#include "exprs/bitmap_function.h"
#include "exprs/hll_function.h"
#include "geo/geo_functions.h"
@ -275,7 +274,6 @@ void init_daemon(int argc, char** argv, const std::vector<StorePath>& paths) {
ESFunctions::init();
GeoFunctions::init();
GroupingSetsFunctions::init();
TimezoneDatabase::init();
BitmapFunctions::init();
HllFunctions::init();
HashFunctions::init();

View File

@ -19,7 +19,7 @@
#include "exec/schema_scanner/schema_tables_scanner.h"
#include "runtime/primitive_type.h"
#include "runtime/string_value.h"
#include "runtime/datetime_value.h"
//#include "runtime/datetime_value.h"
namespace doris
{
@ -187,7 +187,7 @@ Status SchemaTablesScanner::fill_one_row(Tuple *tuple, MemPool *pool) {
tuple->set_not_null(_tuple_desc->slots()[14]->null_indicator_offset());
void *slot = tuple->get_slot(_tuple_desc->slots()[14]->tuple_offset());
DateTimeValue *time_slot = reinterpret_cast<DateTimeValue*>(slot);
time_slot->from_unixtime(create_time, TimezoneDatabase::default_time_zone);
time_slot->from_unixtime(create_time, TimezoneUtils::default_time_zone);
}
}
@ -204,7 +204,7 @@ Status SchemaTablesScanner::fill_one_row(Tuple *tuple, MemPool *pool) {
tuple->set_not_null(_tuple_desc->slots()[16]->null_indicator_offset());
void *slot = tuple->get_slot(_tuple_desc->slots()[16]->tuple_offset());
DateTimeValue *time_slot = reinterpret_cast<DateTimeValue*>(slot);
time_slot->from_unixtime(check_time, TimezoneDatabase::default_time_zone);
time_slot->from_unixtime(check_time, TimezoneUtils::default_time_zone);
}
}
// collation

View File

@ -54,7 +54,6 @@ add_library(Exprs
slot_ref.cpp
string_functions.cpp
timestamp_functions.cpp
timezone_db.cpp
tuple_is_null_predicate.cpp
udf_builtins.cpp
utility_functions.cpp

View File

@ -19,13 +19,13 @@
#include "exprs/expr.h"
#include "exprs/anyval_util.h"
#include "exprs/timezone_db.h"
#include "runtime/tuple_row.h"
#include "runtime/datetime_value.h"
#include "runtime/runtime_state.h"
#include "util/path_builder.h"
#include "runtime/string_value.hpp"
#include "util/debug_util.h"
#include "util/path_builder.h"
#include "util/timezone_utils.h"
namespace doris {
@ -451,20 +451,79 @@ BigIntVal TimestampFunctions::timestamp_diff(FunctionContext* ctx, const DateTim
}
}
void TimestampFunctions::format_prepare(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope) {
if (scope != FunctionContext::FRAGMENT_LOCAL
|| context->get_num_args() < 2
|| context->get_arg_type(1)->type != doris_udf::FunctionContext::Type::TYPE_VARCHAR
|| !context->is_arg_constant(1)) {
VLOG(10) << "format_prepare returned";
return;
}
FormatCtx* fc = new FormatCtx();
context->set_function_state(scope, fc);
StringVal* format = reinterpret_cast<StringVal*>(context->get_constant_arg(1));
if (UNLIKELY(format->is_null)) {
fc->is_valid = false;
return;
}
fc->fmt = convert_format(context, *format);
int format_len = DateTimeValue::compute_format_len((const char*) fc->fmt.ptr, fc->fmt.len);
if (UNLIKELY(format_len >= 128)) {
fc->is_valid = false;
return;
}
fc->is_valid = true;
return;
}
void TimestampFunctions::format_close(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope) {
if (scope != FunctionContext::FRAGMENT_LOCAL) {
return;
}
FormatCtx* fc = reinterpret_cast<FormatCtx*>(context->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (fc != nullptr) {
delete fc;
}
}
StringVal TimestampFunctions::date_format(
FunctionContext* ctx, const DateTimeVal& ts_val, const StringVal& format) {
if (ts_val.is_null || format.is_null) {
return StringVal::null();
}
DateTimeValue ts_value = DateTimeValue::from_datetime_val(ts_val);
if (ts_value.compute_format_len((const char*)format.ptr, format.len) >= 128) {
FormatCtx* fc = reinterpret_cast<FormatCtx*>(ctx->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (UNLIKELY(fc == nullptr)) {
// prepare phase failed, calculate at runtime
StringVal new_fmt = convert_format(ctx, format);
if (DateTimeValue::compute_format_len((const char*) new_fmt.ptr, new_fmt.len) >= 128) {
return StringVal::null();
}
char buf[128];
if (!ts_value.to_format_string((const char*) new_fmt.ptr, new_fmt.len, buf)) {
return StringVal::null();
}
return AnyValUtil::from_string_temp(ctx, buf);
}
if (!fc->is_valid) {
return StringVal::null();
}
StringVal new_fmt = convert_format(ctx, format);
char buf[128];
if (!ts_value.to_format_string((const char*)new_fmt.ptr, new_fmt.len, buf)) {
if (!ts_value.to_format_string((const char*) fc->fmt.ptr, fc->fmt.len, buf)) {
return StringVal::null();
}
return AnyValUtil::from_string_temp(ctx, buf);
@ -520,14 +579,15 @@ DateTimeVal TimestampFunctions::timestamp(
return val;
}
// FROM_UNIXTIME()
// FROM_UNIXTIME() without format
StringVal TimestampFunctions::from_unix(
FunctionContext* context, const IntVal& unix_time) {
if (unix_time.is_null || unix_time.val < 0 || unix_time.val > INT_MAX) {
return StringVal::null();
}
DateTimeValue dtv;
if (!dtv.from_unixtime(unix_time.val, context->impl()->state()->timezone())) {
if (!dtv.from_unixtime(unix_time.val, context->impl()->state()->timezone_obj())) {
return StringVal::null();
}
char buf[64];
@ -535,21 +595,35 @@ StringVal TimestampFunctions::from_unix(
return AnyValUtil::from_string_temp(context, buf);
}
// FROM_UNIXTIME()
// FROM_UNIXTIME() with format
StringVal TimestampFunctions::from_unix(
FunctionContext* context, const IntVal& unix_time, const StringVal& fmt) {
if (unix_time.is_null || fmt.is_null || unix_time.val < 0 || unix_time.val > INT_MAX) {
return StringVal::null();
}
DateTimeValue dtv;
if (!dtv.from_unixtime(unix_time.val, context->impl()->state()->timezone())) {
if (!dtv.from_unixtime(unix_time.val, context->impl()->state()->timezone_obj())) {
return StringVal::null();
}
StringVal new_fmt = convert_format(context, fmt);
FormatCtx* fc = reinterpret_cast<FormatCtx*>(context->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (UNLIKELY(fc == nullptr)) {
// prepare phase failed, calculate at runtime
StringVal new_fmt = convert_format(context, fmt);
char buf[128];
if (!dtv.to_format_string((const char*)new_fmt.ptr, new_fmt.len, buf)) {
return StringVal::null();
}
return AnyValUtil::from_string_temp(context, buf);
}
if (!fc->is_valid) {
return StringVal::null();
}
char buf[128];
if (!dtv.to_format_string((const char*)new_fmt.ptr, new_fmt.len, buf)) {
if (!dtv.to_format_string((const char*) fc->fmt.ptr, fc->fmt.len, buf)) {
return StringVal::null();
}
return AnyValUtil::from_string_temp(context, buf);
@ -564,7 +638,7 @@ IntVal TimestampFunctions::to_unix(FunctionContext* context) {
IntVal TimestampFunctions::to_unix(
FunctionContext* context, const DateTimeValue& ts_value) {
int64_t timestamp;
if(!ts_value.unix_timestamp(&timestamp, context->impl()->state()->timezone())) {
if(!ts_value.unix_timestamp(&timestamp, context->impl()->state()->timezone_obj())) {
return IntVal::null();
} else {
//To compatible to mysql, timestamp not between 1970-01-01 00:00:00 ~ 2038-01-01 00:00:00 return 0
@ -611,7 +685,7 @@ DateTimeVal TimestampFunctions::utc_timestamp(FunctionContext* context) {
DateTimeVal TimestampFunctions::now(FunctionContext* context) {
DateTimeValue dtv;
if (!dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000,
context->impl()->state()->timezone())) {
context->impl()->state()->timezone_obj())) {
return DateTimeVal::null();
}
@ -623,7 +697,7 @@ DateTimeVal TimestampFunctions::now(FunctionContext* context) {
DoubleVal TimestampFunctions::curtime(FunctionContext* context) {
DateTimeValue dtv;
if (!dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000,
context->impl()->state()->timezone())) {
context->impl()->state()->timezone_obj())) {
return DoubleVal::null();
}
@ -633,7 +707,7 @@ DoubleVal TimestampFunctions::curtime(FunctionContext* context) {
DateTimeVal TimestampFunctions::curdate(FunctionContext* context) {
DateTimeValue dtv;
if (!dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000,
context->impl()->state()->timezone())) {
context->impl()->state()->timezone_obj())) {
return DateTimeVal::null();
}
dtv.set_type(TIME_DATE);
@ -643,20 +717,77 @@ DateTimeVal TimestampFunctions::curdate(FunctionContext* context) {
return return_val;
}
void TimestampFunctions::convert_tz_prepare(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope) {
if (scope != FunctionContext::FRAGMENT_LOCAL
|| context->get_num_args() != 3
|| context->get_arg_type(1)->type != doris_udf::FunctionContext::Type::TYPE_VARCHAR
|| context->get_arg_type(2)->type != doris_udf::FunctionContext::Type::TYPE_VARCHAR
|| !context->is_arg_constant(1)
|| !context->is_arg_constant(2)) {
return;
}
ConvertTzCtx* ctc = new ConvertTzCtx();
context->set_function_state(scope, ctc);
// find from timezone
StringVal* from = reinterpret_cast<StringVal*>(context->get_constant_arg(1));
if (UNLIKELY(from->is_null)) {
ctc->is_valid = false;
return;
}
if (!TimezoneUtils::find_cctz_time_zone(std::string((char*) from->ptr, from->len), ctc->from_tz)) {
ctc->is_valid = false;
return;
}
// find to timezone
StringVal* to = reinterpret_cast<StringVal*>(context->get_constant_arg(2));
if (UNLIKELY(to->is_null)) {
ctc->is_valid = false;
return;
}
if (!TimezoneUtils::find_cctz_time_zone(std::string((char*) to->ptr, to->len), ctc->to_tz)) {
ctc->is_valid = false;
return;
}
ctc->is_valid = true;
return;
}
DateTimeVal TimestampFunctions::convert_tz(FunctionContext* ctx, const DateTimeVal& ts_val,
const StringVal& from_tz, const StringVal& to_tz) {
if (TimezoneDatabase::find_timezone(std::string((char *)from_tz.ptr, from_tz.len)) == nullptr ||
TimezoneDatabase::find_timezone(std::string((char *)to_tz.ptr, to_tz.len)) == nullptr
) {
const DateTimeValue &ts_value = DateTimeValue::from_datetime_val(ts_val);
ConvertTzCtx* ctc = reinterpret_cast<ConvertTzCtx*>(ctx->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (UNLIKELY(ctc == nullptr)) {
int64_t timestamp;
if(!ts_value.unix_timestamp(&timestamp, std::string((char *)from_tz.ptr, from_tz.len))) {
return DateTimeVal::null();
}
DateTimeValue ts_value2;
if (!ts_value2.from_unixtime(timestamp, std::string((char *)to_tz.ptr, to_tz.len))) {
return DateTimeVal::null();
}
DateTimeVal return_val;
ts_value2.to_datetime_val(&return_val);
return return_val;
}
if (!ctc->is_valid) {
return DateTimeVal::null();
}
const DateTimeValue &ts_value = DateTimeValue::from_datetime_val(ts_val);
int64_t timestamp;
if(!ts_value.unix_timestamp(&timestamp, std::string((char *)from_tz.ptr, from_tz.len))) {
if(!ts_value.unix_timestamp(&timestamp, ctc->from_tz)) {
return DateTimeVal::null();
}
DateTimeValue ts_value2;
if (!ts_value2.from_unixtime(timestamp, std::string((char *)to_tz.ptr, to_tz.len))) {
if (!ts_value2.from_unixtime(timestamp, ctc->to_tz)) {
return DateTimeVal::null();
}
@ -665,4 +796,17 @@ DateTimeVal TimestampFunctions::convert_tz(FunctionContext* ctx, const DateTimeV
return return_val;
}
void TimestampFunctions::convert_tz_close(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope) {
if (scope != FunctionContext::FRAGMENT_LOCAL) {
return;
}
ConvertTzCtx* ctc = reinterpret_cast<ConvertTzCtx*>(context->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (ctc != nullptr) {
delete ctc;
}
}
}

View File

@ -32,6 +32,23 @@ class Expr;
class OpcodeRegistry;
class TupleRow;
// The context used for timestamp function prepare phase,
// to save the converted date formatter, so that it doesn't
// need to be converted for each rows.
struct FormatCtx {
// false means the format is invalid, and the function always return null
bool is_valid = false;
StringVal fmt;
};
// The context used for convert tz
struct ConvertTzCtx {
// false means the format is invalid, and the function always return null
bool is_valid = false;
cctz::time_zone from_tz;
cctz::time_zone to_tz;
};
class TimestampFunctions {
public:
static void init();
@ -194,6 +211,22 @@ public:
// Issue a warning for a bad format string.
static void report_bad_format(const StringVal* format);
static void format_prepare(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope);
static void format_close(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope);
static void convert_tz_prepare(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope);
static void convert_tz_close(
doris_udf::FunctionContext* context,
doris_udf::FunctionContext::FunctionStateScope scope);
};
}

View File

@ -1,463 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "exprs/timezone_db.h"
namespace doris {
boost::local_time::tz_database TimezoneDatabase::_s_tz_database;
void TimezoneDatabase::init() {
// Create a temporary file and write the timezone information. The boost
// interface only loads this format from a file. We don't want to raise
// an error here since this is done when the backend is created and this
// information might not actually get used by any queries.
char filestr[] = "/tmp/doris.tzdb.XXXXXXX";
FILE *file = NULL;
int fd = -1;
if ((fd = mkstemp(filestr)) == -1) {
LOG(ERROR) << "Could not create temporary timezone file: " << filestr;
return;
}
if ((file = fopen(filestr, "w")) == NULL) {
unlink(filestr);
close(fd);
LOG(ERROR) << "Could not open temporary timezone file: " << filestr;
return;
}
if (fputs(_s_timezone_database_str, file) == EOF) {
unlink(filestr);
close(fd);
fclose(file);
LOG(ERROR) << "Could not load temporary timezone file: " << filestr;
return;
}
fclose(file);
_s_tz_database.load_from_file(std::string(filestr));
unlink(filestr);
close(fd);
}
boost::local_time::time_zone_ptr TimezoneDatabase::find_timezone(const std::string &tz) {
try {
// See if they specified a zone id
if (tz.find_first_of('/') != std::string::npos) {
return _s_tz_database.time_zone_from_region(tz);
} else if (tz == "CST") {
boost::local_time::time_zone_ptr tzp(new boost::local_time::posix_time_zone(std::string("TMP") + "+08:00"));
return tzp;
} else {
//eg. +08:00
boost::local_time::time_zone_ptr tzp(new boost::local_time::posix_time_zone(std::string("TMP") + tz));
return tzp;
}
} catch (boost::exception& e) {
return nullptr;
}
}
const std::string TimezoneDatabase::default_time_zone = "+08:00";
const char* TimezoneDatabase::_s_timezone_database_str =
"\"ID\",\"STD ABBR\",\"STD NAME\",\"DST ABBR\",\"DST NAME\",\"GMT offset\",\"DST adjustment\",\
\"DST Start Date rule\",\"Start time\",\"DST End date rule\",\"End time\"\n\
\"Africa/Abidjan\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Accra\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Addis_Ababa\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Algiers\",\"CET\",\"CET\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Asmera\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Bamako\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Bangui\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Banjul\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Bissau\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Blantyre\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Brazzaville\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Bujumbura\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Cairo\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;5;4\",\"+00:00:00\",\"-1;5;9\",\"+00:00:00\"\n\
\"Africa/Casablanca\",\"WET\",\"WET\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Ceuta\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Africa/Conakry\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Dakar\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Dar_es_Salaam\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Djibouti\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Douala\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/El_Aaiun\",\"WET\",\"WET\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Freetown\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Gaborone\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Harare\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Johannesburg\",\"SAST\",\"SAST\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Kampala\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Khartoum\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Kigali\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Kinshasa\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Lagos\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Libreville\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Lome\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Luanda\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Lubumbashi\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Lusaka\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Malabo\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Maputo\",\"CAT\",\"CAT\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Maseru\",\"SAST\",\"SAST\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Mbabane\",\"SAST\",\"SAST\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Mogadishu\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Monrovia\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Nairobi\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Ndjamena\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Niamey\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Nouakchott\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Ouagadougou\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Porto-Novo\",\"WAT\",\"WAT\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Sao_Tome\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Timbuktu\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Tripoli\",\"EET\",\"EET\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Tunis\",\"CET\",\"CET\",\"\",\"\",\"+01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Africa/Windhoek\",\"WAT\",\"WAT\",\"WAST\",\"WAST\",\"+01:00:00\",\"+01:00:00\",\"1;0;9\",\"+02:00:00\",\"1;0;4\",\"+02:00:00\"\n\
\"America/Adak\",\"HAST\",\"HAST\",\"HADT\",\"HADT\",\"-10:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Anchorage\",\"AKST\",\"AKST\",\"AKDT\",\"AKDT\",\"-09:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Anguilla\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Antigua\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Araguaina\",\"BRT\",\"BRT\",\"BRST\",\"BRST\",\"-03:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Aruba\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Asuncion\",\"PYT\",\"PYT\",\"PYST\",\"PYST\",\"-04:00:00\",\"+01:00:00\",\"1;0;10\",\"+00:00:00\",\"1;0;3\",\"+00:00:00\"\n\
\"America/Barbados\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Belem\",\"BRT\",\"BRT\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Belize\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Boa_Vista\",\"AMT\",\"AMT\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Bogota\",\"COT\",\"COT\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Boise\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Buenos_Aires\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Cambridge_Bay\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Cancun\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Caracas\",\"VET\",\"VET\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Catamarca\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Cayenne\",\"GFT\",\"GFT\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Cayman\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Chicago\",\"CST\",\"Central Standard Time\",\"CDT\",\"Central Daylight Time\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Chihuahua\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Cordoba\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Costa_Rica\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Cuiaba\",\"AMT\",\"AMT\",\"AMST\",\"AMST\",\"-04:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Curacao\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Danmarkshavn\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Dawson\",\"PST\",\"PST\",\"PDT\",\"PDT\",\"-08:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Dawson_Creek\",\"MST\",\"MST\",\"\",\"\",\"-07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Denver\",\"MST\",\"Mountain Standard Time\",\"MDT\",\"Mountain Daylight Time\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Detroit\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Dominica\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Edmonton\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Eirunepe\",\"ACT\",\"ACT\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/El_Salvador\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Fortaleza\",\"BRT\",\"BRT\",\"BRST\",\"BRST\",\"-03:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Glace_Bay\",\"AST\",\"AST\",\"ADT\",\"ADT\",\"-04:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Godthab\",\"WGT\",\"WGT\",\"WGST\",\"WGST\",\"-03:00:00\",\"+01:00:00\",\"-1;6;3\",\"+22:00:00\",\"-1;6;10\",\"+23:00:00\"\n\
\"America/Goose_Bay\",\"AST\",\"AST\",\"ADT\",\"ADT\",\"-04:00:00\",\"+01:00:00\",\"1;0;4\",\"+00:01:00\",\"-1;0;10\",\"+00:01:00\"\n\
\"America/Grand_Turk\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"1;0;4\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"America/Grenada\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Guadeloupe\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Guatemala\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Guayaquil\",\"ECT\",\"ECT\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Guyana\",\"GYT\",\"GYT\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Halifax\",\"AST\",\"AST\",\"ADT\",\"ADT\",\"-04:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Havana\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-05:00:00\",\"+01:00:00\",\"1;0;4\",\"+00:00:00\",\"-1;0;10\",\"+01:00:00\"\n\
\"America/Hermosillo\",\"MST\",\"MST\",\"\",\"\",\"-07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Indiana/Indianapolis\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Indiana/Knox\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Indiana/Marengo\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Indiana/Vevay\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Indianapolis\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Inuvik\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Iqaluit\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Jamaica\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Jujuy\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Juneau\",\"AKST\",\"AKST\",\"AKDT\",\"AKDT\",\"-09:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Kentucky/Louisville\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Kentucky/Monticello\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/La_Paz\",\"BOT\",\"BOT\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Lima\",\"PET\",\"PET\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Los_Angeles\",\"PST\",\"Pacific Standard Time\",\"PDT\",\"Pacific Daylight Time\",\"-08:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Louisville\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Maceio\",\"BRT\",\"BRT\",\"BRST\",\"BRST\",\"-03:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Managua\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Manaus\",\"AMT\",\"AMT\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Martinique\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Mazatlan\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Mendoza\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Menominee\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Merida\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Mexico_City\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Miquelon\",\"PMST\",\"PMST\",\"PMDT\",\"PMDT\",\"-03:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Monterrey\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Montevideo\",\"UYT\",\"UYT\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Montreal\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Montserrat\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Nassau\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/New_York\",\"EST\",\"Eastern Standard Time\",\"EDT\",\"Eastern Daylight Time\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Nipigon\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Nome\",\"AKST\",\"AKST\",\"AKDT\",\"AKDT\",\"-09:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Noronha\",\"FNT\",\"FNT\",\"\",\"\",\"-02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/North_Dakota/Center\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Panama\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Pangnirtung\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Paramaribo\",\"SRT\",\"SRT\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Phoenix\",\"MST\",\"Mountain Standard Time\",\"\",\"\",\"-07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Port-au-Prince\",\"EST\",\"EST\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Port_of_Spain\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Porto_Velho\",\"AMT\",\"AMT\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Puerto_Rico\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Rainy_River\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Rankin_Inlet\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Recife\",\"BRT\",\"BRT\",\"BRST\",\"BRST\",\"-03:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Regina\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Rio_Branco\",\"ACT\",\"ACT\",\"\",\"\",\"-05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Rosario\",\"ART\",\"ART\",\"\",\"\",\"-03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Santiago\",\"CLT\",\"CLT\",\"CLST\",\"CLST\",\"-04:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"2;0;3\",\"+00:00:00\"\n\
\"America/Santo_Domingo\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Sao_Paulo\",\"BRT\",\"BRT\",\"BRST\",\"BRST\",\"-03:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"3;0;2\",\"+00:00:00\"\n\
\"America/Scoresbysund\",\"EGT\",\"EGT\",\"EGST\",\"EGST\",\"-01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+01:00:00\"\n\
\"America/Shiprock\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/St_Johns\",\"NST\",\"NST\",\"NDT\",\"NDT\",\"-03:30:00\",\"+01:00:00\",\"1;0;4\",\"+00:01:00\",\"-1;0;10\",\"+00:01:00\"\n\
\"America/St_Kitts\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/St_Lucia\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/St_Thomas\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/St_Vincent\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Swift_Current\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Tegucigalpa\",\"CST\",\"CST\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Thule\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"2;0;3\",\"\",\"1;0;11\",\"+00:00:00\"\n\
\"America/Thunder_Bay\",\"EST\",\"EST\",\"EDT\",\"EDT\",\"-05:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Tijuana\",\"PST\",\"PST\",\"PDT\",\"PDT\",\"-08:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"America/Tortola\",\"AST\",\"AST\",\"\",\"\",\"-04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"America/Vancouver\",\"PST\",\"PST\",\"PDT\",\"PDT\",\"-08:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Whitehorse\",\"PST\",\"PST\",\"PDT\",\"PDT\",\"-08:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Winnipeg\",\"CST\",\"CST\",\"CDT\",\"CDT\",\"-06:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+03:00:00\"\n\
\"America/Yakutat\",\"AKST\",\"AKST\",\"AKDT\",\"AKDT\",\"-09:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"America/Yellowknife\",\"MST\",\"MST\",\"MDT\",\"MDT\",\"-07:00:00\",\"+01:00:00\",\"2;0;3\",\"+02:00:00\",\"1;0;11\",\"+02:00:00\"\n\
\"Antarctica/Casey\",\"WST\",\"WST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Antarctica/Davis\",\"DAVT\",\"DAVT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Antarctica/DumontDUrville\",\"DDUT\",\"DDUT\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Antarctica/Mawson\",\"MAWT\",\"MAWT\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Antarctica/McMurdo\",\"NZST\",\"NZST\",\"NZDT\",\"NZDT\",\"+12:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"3;0;3\",\"+03:00:00\"\n\
\"Antarctica/Palmer\",\"CLT\",\"CLT\",\"CLST\",\"CLST\",\"-04:00:00\",\"+01:00:00\",\"2;0;10\",\"+00:00:00\",\"2;0;3\",\"+00:00:00\"\n\
\"Antarctica/South_Pole\",\"NZST\",\"NZST\",\"NZDT\",\"NZDT\",\"+12:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"3;0;3\",\"+03:00:00\"\n\
\"Antarctica/Syowa\",\"SYOT\",\"SYOT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Antarctica/Vostok\",\"VOST\",\"VOST\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Arctic/Longyearbyen\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Aden\",\"AST\",\"AST\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Almaty\",\"ALMT\",\"ALMT\",\"ALMST\",\"ALMST\",\"+06:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"Asia/Amman\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;4;3\",\"+00:00:00\",\"-1;4;9\",\"+01:00:00\"\n\
\"Asia/Anadyr\",\"ANAT\",\"ANAT\",\"ANAST\",\"ANAST\",\"+12:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Aqtau\",\"AQTT\",\"AQTT\",\"AQTST\",\"AQTST\",\"+04:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"Asia/Aqtobe\",\"AQTT\",\"AQTT\",\"AQTST\",\"AQTST\",\"+05:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"Asia/Ashgabat\",\"TMT\",\"TMT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Baghdad\",\"AST\",\"AST\",\"ADT\",\"ADT\",\"+03:00:00\",\"+01:00:00\",\"1;0;4\",\"+03:00:00\",\"1;0;10\",\"+04:00:00\"\n\
\"Asia/Bahrain\",\"AST\",\"AST\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Baku\",\"AZT\",\"AZT\",\"AZST\",\"AZST\",\"+04:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+01:00:00\"\n\
\"Asia/Bangkok\",\"ICT\",\"ICT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Beirut\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"Asia/Bishkek\",\"KGT\",\"KGT\",\"KGST\",\"KGST\",\"+05:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:30:00\",\"-1;0;10\",\"+02:30:00\"\n\
\"Asia/Brunei\",\"BNT\",\"BNT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Calcutta\",\"IST\",\"IST\",\"\",\"\",\"+05:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Choibalsan\",\"CHOT\",\"CHOT\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Chongqing\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Colombo\",\"LKT\",\"LKT\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Damascus\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"1;0;4\",\"+00:00:00\",\"1;0;10\",\"+00:00:00\"\n\
\"Asia/Dhaka\",\"BDT\",\"BDT\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Dili\",\"TPT\",\"TPT\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Dubai\",\"GST\",\"GST\",\"\",\"\",\"+04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Dushanbe\",\"TJT\",\"TJT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Gaza\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"3;5;4\",\"+00:00:00\",\"3;5;10\",\"+00:00:00\"\n\
\"Asia/Harbin\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Hong_Kong\",\"HKT\",\"HKT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Hovd\",\"HOVT\",\"HOVT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Irkutsk\",\"IRKT\",\"IRKT\",\"IRKST\",\"IRKST\",\"+08:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Istanbul\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Asia/Jakarta\",\"WIT\",\"WIT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Jayapura\",\"EIT\",\"EIT\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Jerusalem\",\"IST\",\"IST\",\"IDT\",\"IDT\",\"+02:00:00\",\"+01:00:00\",\"1;0;4\",\"+01:00:00\",\"1;0;10\",\"+01:00:00\"\n\
\"Asia/Kabul\",\"AFT\",\"AFT\",\"\",\"\",\"+04:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Kamchatka\",\"PETT\",\"PETT\",\"PETST\",\"PETST\",\"+12:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Karachi\",\"PKT\",\"PKT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Kashgar\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Katmandu\",\"NPT\",\"NPT\",\"\",\"\",\"+05:45:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Krasnoyarsk\",\"KRAT\",\"KRAT\",\"KRAST\",\"KRAST\",\"+07:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Kuala_Lumpur\",\"MYT\",\"MYT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Kuching\",\"MYT\",\"MYT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Kuwait\",\"AST\",\"AST\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Macao\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Macau\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Magadan\",\"MAGT\",\"MAGT\",\"MAGST\",\"MAGST\",\"+11:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Makassar\",\"CIT\",\"CIT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Manila\",\"PHT\",\"PHT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Muscat\",\"GST\",\"GST\",\"\",\"\",\"+04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Nicosia\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Asia/Novosibirsk\",\"NOVT\",\"NOVT\",\"NOVST\",\"NOVST\",\"+06:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Omsk\",\"OMST\",\"OMST\",\"OMSST\",\"OMSST\",\"+06:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Oral\",\"WST\",\"WST\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Phnom_Penh\",\"ICT\",\"ICT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Pontianak\",\"WIT\",\"WIT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Pyongyang\",\"KST\",\"KST\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Qyzylorda\",\"KST\",\"KST\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Qatar\",\"AST\",\"AST\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Rangoon\",\"MMT\",\"MMT\",\"\",\"\",\"+06:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Riyadh\",\"AST\",\"AST\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Saigon\",\"ICT\",\"ICT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Sakhalin\",\"SAKT\",\"SAKT\",\"SAKST\",\"SAKST\",\"+10:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Samarkand\",\"UZT\",\"UZT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Seoul\",\"KST\",\"KST\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Shanghai\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Singapore\",\"SGT\",\"SGT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Taipei\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Tashkent\",\"UZT\",\"UZT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Tbilisi\",\"GET\",\"GET\",\"GEST\",\"GEST\",\"+04:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+00:00:00\"\n\
\"Asia/Tehran\",\"IRT\",\"IRT\",\"\",\"\",\"+03:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Thimphu\",\"BTT\",\"BTT\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Tokyo\",\"JST\",\"JST\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Ujung_Pandang\",\"CIT\",\"CIT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Ulaanbaatar\",\"ULAT\",\"ULAT\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Urumqi\",\"CST\",\"CST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Vientiane\",\"ICT\",\"ICT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Asia/Vladivostok\",\"VLAT\",\"VLAT\",\"VLAST\",\"VLAST\",\"+10:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Yakutsk\",\"YAKT\",\"YAKT\",\"YAKST\",\"YAKST\",\"+09:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Yekaterinburg\",\"YEKT\",\"YEKT\",\"YEKST\",\"YEKST\",\"+05:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Asia/Yerevan\",\"AMT\",\"AMT\",\"AMST\",\"AMST\",\"+04:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Atlantic/Azores\",\"AZOT\",\"AZOT\",\"AZOST\",\"AZOST\",\"-01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+00:00:00\",\"-1;0;10\",\"+01:00:00\"\n\
\"Atlantic/Bermuda\",\"AST\",\"AST\",\"ADT\",\"ADT\",\"-04:00:00\",\"+01:00:00\",\"1;0;4\",\"+02:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Atlantic/Canary\",\"WET\",\"WET\",\"WEST\",\"WEST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Atlantic/Cape_Verde\",\"CVT\",\"CVT\",\"\",\"\",\"-01:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Atlantic/Faeroe\",\"WET\",\"WET\",\"WEST\",\"WEST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Atlantic/Jan_Mayen\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Atlantic/Madeira\",\"WET\",\"WET\",\"WEST\",\"WEST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Atlantic/Reykjavik\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Atlantic/South_Georgia\",\"GST\",\"GST\",\"\",\"\",\"-02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Atlantic/St_Helena\",\"GMT\",\"GMT\",\"\",\"\",\"+00:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Atlantic/Stanley\",\"FKT\",\"FKT\",\"FKST\",\"FKST\",\"-04:00:00\",\"+01:00:00\",\"1;0;9\",\"+02:00:00\",\"3;0;4\",\"+02:00:00\"\n\
\"Australia/Adelaide\",\"CST\",\"CST\",\"CST\",\"CST\",\"+09:30:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+03:00:00\"\n\
\"Australia/Brisbane\",\"EST\",\"EST\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Australia/Broken_Hill\",\"CST\",\"CST\",\"CST\",\"CST\",\"+09:30:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+03:00:00\"\n\
\"Australia/Darwin\",\"CST\",\"CST\",\"\",\"\",\"+09:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Australia/Eucla\",\"CWST\",\"CWST\",\"\",\"\",\"+08:45:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Australia/Hobart\",\"EST\",\"EST\",\"EST\",\"EST\",\"+10:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+03:00:00\"\n\
\"Australia/Lindeman\",\"EST\",\"EST\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Australia/Lord_Howe\",\"LHST\",\"LHST\",\"LHST\",\"LHST\",\"+10:30:00\",\"+00:30:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+02:30:00\"\n\
\"Australia/Melbourne\",\"EST\",\"EST\",\"EST\",\"EST\",\"+10:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+03:00:00\"\n\
\"Australia/Perth\",\"WST\",\"WST\",\"\",\"\",\"+08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Australia/Sydney\",\"EST\",\"EST\",\"EST\",\"EST\",\"+10:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"1;0;4\",\"+03:00:00\"\n\
\"Europe/Amsterdam\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Andorra\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Athens\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Belfast\",\"GMT\",\"GMT\",\"BST\",\"BST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Europe/Belgrade\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Berlin\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Bratislava\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Brussels\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Bucharest\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Budapest\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Chisinau\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Copenhagen\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Dublin\",\"GMT\",\"GMT\",\"IST\",\"IST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Europe/Gibraltar\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Helsinki\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Istanbul\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Kaliningrad\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Kiev\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Lisbon\",\"WET\",\"WET\",\"WEST\",\"WEST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Europe/Ljubljana\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/London\",\"GMT\",\"GMT\",\"BST\",\"BST\",\"+00:00:00\",\"+01:00:00\",\"-1;0;3\",\"+01:00:00\",\"-1;0;10\",\"+02:00:00\"\n\
\"Europe/Luxembourg\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Madrid\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Malta\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Minsk\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Monaco\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Moscow\",\"MSK\",\"MSK\",\"MSD\",\"MSD\",\"+03:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Nicosia\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Oslo\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Paris\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Prague\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Riga\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Rome\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Samara\",\"SAMT\",\"SAMT\",\"SAMST\",\"SAMST\",\"+04:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/San_Marino\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Sarajevo\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Simferopol\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Skopje\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Sofia\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Stockholm\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Tallinn\",\"EET\",\"EET\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Europe/Tirane\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Uzhgorod\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Vaduz\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Vatican\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Vienna\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Vilnius\",\"EET\",\"EET\",\"\",\"\",\"+02:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Europe/Warsaw\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Zagreb\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Europe/Zaporozhye\",\"EET\",\"EET\",\"EEST\",\"EEST\",\"+02:00:00\",\"+01:00:00\",\"-1;0;3\",\"+03:00:00\",\"-1;0;10\",\"+04:00:00\"\n\
\"Europe/Zurich\",\"CET\",\"CET\",\"CEST\",\"CEST\",\"+01:00:00\",\"+01:00:00\",\"-1;0;3\",\"+02:00:00\",\"-1;0;10\",\"+03:00:00\"\n\
\"Indian/Antananarivo\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Chagos\",\"IOT\",\"IOT\",\"\",\"\",\"+06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Christmas\",\"CXT\",\"CXT\",\"\",\"\",\"+07:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Cocos\",\"CCT\",\"CCT\",\"\",\"\",\"+06:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Comoro\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Kerguelen\",\"TFT\",\"TFT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Mahe\",\"SCT\",\"SCT\",\"\",\"\",\"+04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Maldives\",\"MVT\",\"MVT\",\"\",\"\",\"+05:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Mauritius\",\"MUT\",\"MUT\",\"\",\"\",\"+04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Mayotte\",\"EAT\",\"EAT\",\"\",\"\",\"+03:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Indian/Reunion\",\"RET\",\"RET\",\"\",\"\",\"+04:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Apia\",\"WST\",\"WST\",\"\",\"\",\"-11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Auckland\",\"NZST\",\"NZST\",\"NZDT\",\"NZDT\",\"+12:00:00\",\"+01:00:00\",\"1;0;10\",\"+02:00:00\",\"3;0;3\",\"+03:00:00\"\n\
\"Pacific/Chatham\",\"CHAST\",\"CHAST\",\"CHADT\",\"CHADT\",\"+12:45:00\",\"+01:00:00\",\"1;0;10\",\"+02:45:00\",\"3;0;3\",\"+03:45:00\"\n\
\"Pacific/Easter\",\"EAST\",\"EAST\",\"EASST\",\"EASST\",\"-06:00:00\",\"+01:00:00\",\"2;6;10\",\"+22:00:00\",\"2;6;3\",\"+22:00:00\"\n\
\"Pacific/Efate\",\"VUT\",\"VUT\",\"\",\"\",\"+11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Enderbury\",\"PHOT\",\"PHOT\",\"\",\"\",\"+13:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Fakaofo\",\"TKT\",\"TKT\",\"\",\"\",\"-10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Fiji\",\"FJT\",\"FJT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Funafuti\",\"TVT\",\"TVT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Galapagos\",\"GALT\",\"GALT\",\"\",\"\",\"-06:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Gambier\",\"GAMT\",\"GAMT\",\"\",\"\",\"-09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Guadalcanal\",\"SBT\",\"SBT\",\"\",\"\",\"+11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Guam\",\"ChST\",\"ChST\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Honolulu\",\"HST\",\"HST\",\"\",\"\",\"-10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Johnston\",\"HST\",\"HST\",\"\",\"\",\"-10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Kiritimati\",\"LINT\",\"LINT\",\"\",\"\",\"+14:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Kosrae\",\"KOST\",\"KOST\",\"\",\"\",\"+11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Kwajalein\",\"MHT\",\"MHT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Majuro\",\"MHT\",\"MHT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Marquesas\",\"MART\",\"MART\",\"\",\"\",\"-09:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Midway\",\"SST\",\"SST\",\"\",\"\",\"-11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Nauru\",\"NRT\",\"NRT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Niue\",\"NUT\",\"NUT\",\"\",\"\",\"-11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Norfolk\",\"NFT\",\"NFT\",\"\",\"\",\"+11:30:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Noumea\",\"NCT\",\"NCT\",\"\",\"\",\"+11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Pago_Pago\",\"SST\",\"SST\",\"\",\"\",\"-11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Palau\",\"PWT\",\"PWT\",\"\",\"\",\"+09:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Pitcairn\",\"PST\",\"PST\",\"\",\"\",\"-08:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Ponape\",\"PONT\",\"PONT\",\"\",\"\",\"+11:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Port_Moresby\",\"PGT\",\"PGT\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Rarotonga\",\"CKT\",\"CKT\",\"\",\"\",\"-10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Saipan\",\"ChST\",\"ChST\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Tahiti\",\"TAHT\",\"TAHT\",\"\",\"\",\"-10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Tarawa\",\"GILT\",\"GILT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Tongatapu\",\"TOT\",\"TOT\",\"\",\"\",\"+13:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Truk\",\"TRUT\",\"TRUT\",\"\",\"\",\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Wake\",\"WAKT\",\"WAKT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Wallis\",\"WFT\",\"WFT\",\"\",\"\",\"+12:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n\
\"Pacific/Yap\",\"YAPT\",\"YAPT\",\"\",\"\",\
\"+10:00:00\",\"+00:00:00\",\"\",\"\",\"\",\"+00:00:00\"\n";
}

View File

@ -16,6 +16,7 @@
// under the License.
#include "runtime/datetime_value.h"
#include "util/timezone_utils.h"
#include <ctype.h>
#include <string.h>
@ -65,20 +66,6 @@ DateTimeValue DateTimeValue::_s_min_datetime_value(0, TIME_DATETIME, 0, 0, 0, 0,
DateTimeValue DateTimeValue::_s_max_datetime_value(0, TIME_DATETIME, 23, 59, 59, 0,
9999, 12, 31);
RE2 DateTimeValue::time_zone_offset_format_reg("^[+-]{1}\\d{2}\\:\\d{2}$");
// jint length_of_str(DateTimeValue& value) {
// j if (_type == TIME_DATE) {
// j return 10;
// j } else {
// j int extra_len = (_microsecond == 0) ? 0 : 7;
// j if (_type == TIME_DATETIME) {
// j return 19 + extra_len;
// j } else {
// j // TIME
// j return 8 + extra_len + _neg
// j + (_hour > 100) ? 1 : 0;
// j }
// j }
// j}
bool DateTimeValue::check_range() const {
return _year > 9999 || _month > 12 || _day > 31
@ -600,7 +587,7 @@ static char* append_with_prefix(const char* str, int str_len,
return to;
}
int DateTimeValue::compute_format_len(const char* format, int len) const {
int DateTimeValue::compute_format_len(const char* format, int len) {
int size = 0;
const char* ptr = format;
const char* end = format + len;
@ -1532,10 +1519,13 @@ bool DateTimeValue::date_add_interval(const TimeInterval& interval, TimeUnit uni
bool DateTimeValue::unix_timestamp(int64_t* timestamp, const std::string& timezone) const{
cctz::time_zone ctz;
if (!find_cctz_time_zone(timezone, ctz)) {
if (!TimezoneUtils::find_cctz_time_zone(timezone, ctz)) {
return false;
}
return unix_timestamp(timestamp, ctz);
}
bool DateTimeValue::unix_timestamp(int64_t* timestamp, const cctz::time_zone& ctz) const{
const auto tp =
cctz::convert(cctz::civil_second(_year, _month, _day, _hour, _minute, _second), ctz);
*timestamp = tp.time_since_epoch().count();
@ -1544,10 +1534,13 @@ bool DateTimeValue::unix_timestamp(int64_t* timestamp, const std::string& timezo
bool DateTimeValue::from_unixtime(int64_t timestamp, const std::string& timezone) {
cctz::time_zone ctz;
if (!find_cctz_time_zone(timezone, ctz)) {
if (!TimezoneUtils::find_cctz_time_zone(timezone, ctz)) {
return false;
}
return from_unixtime(timestamp, ctz);
}
bool DateTimeValue::from_unixtime(int64_t timestamp, const cctz::time_zone& ctz) {
static const cctz::time_point<cctz::sys_seconds> epoch =
std::chrono::time_point_cast<cctz::sys_seconds>(std::chrono::system_clock::from_time_t(0));
cctz::time_point<cctz::sys_seconds> t = epoch + cctz::seconds(timestamp);
@ -1584,7 +1577,7 @@ const char* DateTimeValue::day_name() const {
DateTimeValue DateTimeValue::local_time() {
DateTimeValue value;
value.from_unixtime(time(NULL), TimezoneDatabase::default_time_zone);
value.from_unixtime(time(NULL), TimezoneUtils::default_time_zone);
return value;
}

View File

@ -27,9 +27,9 @@
#include "cctz/civil_time.h"
#include "cctz/time_zone.h"
#include "exprs/timezone_db.h"
#include "udf/udf.h"
#include "util/hash_util.hpp"
#include "util/timezone_utils.h"
namespace doris {
@ -241,7 +241,9 @@ public:
// Convert this datetime value to string by the format string
bool to_format_string(const char* format, int len, char* to) const;
int compute_format_len(const char* format, int len) const;
// compute the length of data format pattern
static int compute_format_len(const char* format, int len);
// Convert this value to uint64_t
// Will check its type
@ -340,10 +342,12 @@ public:
//unix_timestamp is called with a timezone argument,
//it returns seconds of the value of date literal since '1970-01-01 00:00:00' UTC
bool unix_timestamp(int64_t* timestamp, const std::string& timezone) const;
bool unix_timestamp(int64_t* timestamp, const cctz::time_zone& ctz) const;
//construct datetime_value from timestamp and timezone
//timestamp is an internal timestamp value representing seconds since '1970-01-01 00:00:00' UTC
bool from_unixtime(int64_t, const std::string& timezone);
bool from_unixtime(int64_t, const cctz::time_zone& ctz);
bool operator==(const DateTimeValue& other) const {
// NOTE: This is not same with MySQL.
@ -498,34 +502,6 @@ private:
return _neg ? -tmp : tmp;
}
bool find_cctz_time_zone(const std::string& timezone, cctz::time_zone& ctz) const {
re2::StringPiece value;
if (time_zone_offset_format_reg.Match(timezone, 0, timezone.size(), RE2::UNANCHORED, &value, 1)) {
bool postive = value[0] != '-';
//Regular expression guarantees hour and minute mush be int
int hour = std::stoi(value.substr(1, 2).as_string());
int minute = std::stoi(value.substr(4, 2).as_string());
// timezone offsets around the world extended from -12:00 to +14:00
if (!postive && hour > 12) {
return false;
} else if (postive && hour > 14) {
return false;
}
int offset = hour * 60 * 60 + minute * 60;
offset *= postive ? 1 : -1;
ctz = cctz::fixed_time_zone(cctz::seconds(offset));
return true;
} else if (timezone == "CST"){
// Supports offset and region timezone type, "CST" use here is compatibility purposes.
ctz = cctz::fixed_time_zone(cctz::seconds(8 * 60 * 60));
return true;
} else {
return cctz::load_time_zone(timezone, &ctz);
}
}
// Check wether value of field is valid.
bool check_range() const;
bool check_date() const;
@ -580,6 +556,7 @@ private:
static DateTimeValue _s_min_datetime_value;
static DateTimeValue _s_max_datetime_value;
// RE2 obj is thread safe
static RE2 time_zone_offset_format_reg;
};

View File

@ -26,7 +26,6 @@
#include "common/status.h"
#include "exec/exec_node.h"
#include "exprs/expr.h"
#include "exprs/timezone_db.h"
#include "runtime/buffered_block_mgr2.h"
#include "runtime/bufferpool/reservation_util.h"
#include "runtime/descriptors.h"
@ -41,6 +40,7 @@
#include "util/file_utils.h"
#include "util/pretty_printer.h"
#include "util/load_error_hub.h"
#include "util/timezone_utils.h"
#include "runtime/mem_tracker.h"
#include "runtime/bufferpool/reservation_tracker.h"
@ -110,7 +110,7 @@ RuntimeState::RuntimeState(const TQueryGlobals& query_globals)
_timezone = query_globals.time_zone;
_timestamp_ms = query_globals.timestamp_ms;
} else if (!query_globals.now_string.empty()) {
_timezone = TimezoneDatabase::default_time_zone;
_timezone = TimezoneUtils::default_time_zone;
DateTimeValue dt;
dt.from_date_str(query_globals.now_string.c_str(), query_globals.now_string.size());
int64_t timestamp;
@ -118,9 +118,10 @@ RuntimeState::RuntimeState(const TQueryGlobals& query_globals)
_timestamp_ms = timestamp * 1000;
} else {
//Unit test may set into here
_timezone = TimezoneDatabase::default_time_zone;
_timezone = TimezoneUtils::default_time_zone;
_timestamp_ms = 0;
}
TimezoneUtils::find_cctz_time_zone(_timezone, _timezone_obj);
}
RuntimeState::~RuntimeState() {
@ -184,7 +185,7 @@ Status RuntimeState::init(
_timezone = query_globals.time_zone;
_timestamp_ms = query_globals.timestamp_ms;
} else if (!query_globals.now_string.empty()) {
_timezone = TimezoneDatabase::default_time_zone;
_timezone = TimezoneUtils::default_time_zone;
DateTimeValue dt;
dt.from_date_str(query_globals.now_string.c_str(), query_globals.now_string.size());
int64_t timestamp;
@ -192,9 +193,11 @@ Status RuntimeState::init(
_timestamp_ms = timestamp * 1000;
} else {
//Unit test may set into here
_timezone = TimezoneDatabase::default_time_zone;
_timezone = TimezoneUtils::default_time_zone;
_timestamp_ms = 0;
}
TimezoneUtils::find_cctz_time_zone(_timezone, _timezone_obj);
_exec_env = exec_env;
if (_query_options.max_errors <= 0) {

View File

@ -31,6 +31,7 @@
#include <sstream>
#include <vector>
#include "cctz/time_zone.h"
#include "common/global_types.h"
#include "util/logging.h"
#include "runtime/mem_pool.h"
@ -143,6 +144,9 @@ public:
const std::string& timezone() const {
return _timezone;
}
const cctz::time_zone& timezone_obj() const {
return _timezone_obj;
}
const std::string& user() const {
return _user;
}
@ -536,6 +540,7 @@ private:
//Query-global timestamp_ms
int64_t _timestamp_ms;
std::string _timezone;
cctz::time_zone _timezone_obj;
TUniqueId _query_id;
TUniqueId _fragment_instance_id;

View File

@ -417,6 +417,7 @@ void StringVal::append(FunctionContext* ctx, const uint8_t* buf, size_t buf_len)
len += buf_len;
}
}
void StringVal::append(FunctionContext* ctx, const uint8_t* buf, size_t buf_len,
const uint8_t* buf2, size_t buf2_len) {
if (UNLIKELY(len + buf_len + buf2_len > StringVal::MAX_LENGTH)) {

View File

@ -95,6 +95,7 @@ set(UTIL_FILES
threadpool.cpp
trace.cpp
trace_metrics.cpp
timezone_utils.cpp
)
if (WITH_MYSQL)

View File

@ -19,6 +19,7 @@
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <utility>

View File

@ -0,0 +1,55 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
#include "util/timezone_utils.h"
namespace doris {
RE2 TimezoneUtils::time_zone_offset_format_reg("^[+-]{1}\\d{2}\\:\\d{2}$");
const std::string TimezoneUtils::default_time_zone = "+08:00";
bool TimezoneUtils::find_cctz_time_zone(const std::string& timezone, cctz::time_zone& ctz) {
re2::StringPiece value;
if (time_zone_offset_format_reg.Match(timezone, 0, timezone.size(), RE2::UNANCHORED, &value, 1)) {
bool postive = value[0] != '-';
//Regular expression guarantees hour and minute mush be int
int hour = std::stoi(value.substr(1, 2).as_string());
int minute = std::stoi(value.substr(4, 2).as_string());
// timezone offsets around the world extended from -12:00 to +14:00
if (!postive && hour > 12) {
return false;
} else if (postive && hour > 14) {
return false;
}
int offset = hour * 60 * 60 + minute * 60;
offset *= postive ? 1 : -1;
ctz = cctz::fixed_time_zone(cctz::seconds(offset));
return true;
} else if (timezone == "CST"){
// Supports offset and region timezone type, "CST" use here is compatibility purposes.
ctz = cctz::fixed_time_zone(cctz::seconds(8 * 60 * 60));
return true;
} else {
return cctz::load_time_zone(timezone, &ctz);
}
}
} // end namespace

View File

@ -15,31 +15,23 @@
// specific language governing permissions and limitations
// under the License.
//
#ifndef DORIS_BE_EXPRS_TIMEZONE_DB_H
#define DORIS_BE_EXPRS_TIMEZONE_DB_H
#include <stdint.h>
#include <iostream>
#include <cstddef>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/time_zone_base.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/thread/thread.hpp>
#pragma once
#include "common/logging.h"
#include "cctz/time_zone.h"
#include <re2/re2.h>
namespace doris {
class TimezoneDatabase {
class TimezoneUtils {
public:
static bool find_cctz_time_zone(const std::string& timezone, cctz::time_zone& ctz);
public:
static void init();
static boost::local_time::time_zone_ptr find_timezone(const std::string &tz);
static const std::string default_time_zone;
private:
static const char *_s_timezone_database_str;
static boost::local_time::tz_database _s_tz_database;
// RE2 obj is thread safe
static RE2 time_zone_offset_format_reg;
};
}
#endif

View File

@ -0,0 +1,48 @@
---
{
"title": "to_date",
"language": "en"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# to_date
## description
### Syntax
`DATE TO_DATE(DATETIME)`
Return the DATE part of DATETIME value.
## example
```
mysql> select to_date("2020-02-02 00:00:00");
+--------------------------------+
| to_date('2020-02-02 00:00:00') |
+--------------------------------+
| 2020-02-02 |
+--------------------------------+
```
##keyword
TO_DATE

View File

@ -34,7 +34,7 @@ under the License.
转换datetime值dt,从 from_tz 由给定转到 to_tz 时区给出的时区,并返回的结果值。 如果参数无效该函数返回NULL。
## Examples
## Example
```
mysql> select convert_tz('2019-08-01 13:21:03', 'Asia/Shanghai', 'America/Los_Angeles');

View File

@ -0,0 +1,48 @@
---
{
"title": "to_date",
"language": "zh-CN"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# to_date
## description
### Syntax
`DATE TO_DATE(DATETIME)`
返回 DATETIME 类型中的日期部分。
## example
```
mysql> select to_date("2020-02-02 00:00:00");
+--------------------------------+
| to_date('2020-02-02 00:00:00') |
+--------------------------------+
| 2020-02-02 |
+--------------------------------+
```
##keyword
TO_DATE

View File

@ -222,6 +222,12 @@ public class FEFunctions {
return new DateLiteral(LocalDateTime.now(DateTimeZone.forTimeZone(TimeUtils.getTimeZone())), Type.DATE);
}
@FEFunction(name = "utc_timestamp", argTypes = {}, returnType = "DATETIME")
public static DateLiteral utcTimestamp() throws AnalysisException {
return new DateLiteral(LocalDateTime.now(DateTimeZone.forTimeZone(TimeUtils.getOrSystemTimeZone("+00:00"))),
Type.DATETIME);
}
/**
------------------------------------------------------------------------------
*/

View File

@ -112,7 +112,11 @@ visible_functions = [
'_ZN5doris18TimestampFunctions9from_unixEPN9doris_udf15FunctionContextERKNS1_6IntValE'],
[['from_unixtime'], 'VARCHAR', ['INT', 'VARCHAR'],
'_ZN5doris18TimestampFunctions9from_unixEPN9doris_udf'
'15FunctionContextERKNS1_6IntValERKNS1_9StringValE'],
'15FunctionContextERKNS1_6IntValERKNS1_9StringValE',
'_ZN5doris18TimestampFunctions14format_prepareEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE',
'_ZN5doris18TimestampFunctions12format_closeEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE'],
[['now', 'current_timestamp', 'localtime', 'localtimestamp'], 'DATETIME', [],
'_ZN5doris18TimestampFunctions3nowEPN9doris_udf15FunctionContextE'],
[['curtime', 'current_time'], 'TIME', [],
@ -214,10 +218,18 @@ visible_functions = [
'15FunctionContextERKNS1_9StringValES6_'],
[['date_format'], 'VARCHAR', ['DATETIME', 'VARCHAR'],
'_ZN5doris18TimestampFunctions11date_formatEPN9doris_udf'
'15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValE'],
'15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValE',
'_ZN5doris18TimestampFunctions14format_prepareEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE',
'_ZN5doris18TimestampFunctions12format_closeEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE'],
[['date_format'], 'VARCHAR', ['DATE', 'VARCHAR'],
'_ZN5doris18TimestampFunctions11date_formatEPN9doris_udf'
'15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValE'],
'15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValE',
'_ZN5doris18TimestampFunctions14format_prepareEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE',
'_ZN5doris18TimestampFunctions12format_closeEPN9doris_udf'
'15FunctionContextENS2_18FunctionStateScopeE'],
[['date', 'to_date'], 'DATE', ['DATETIME'],
'_ZN5doris18TimestampFunctions7to_dateEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
@ -229,7 +241,9 @@ visible_functions = [
'15FunctionContextERKNS1_11DateTimeValE'],
[['convert_tz'], 'DATETIME', ['DATETIME', 'VARCHAR', 'VARCHAR'],
'_ZN5doris18TimestampFunctions10convert_tzEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValES9_'],
'_ZN5doris18TimestampFunctions10convert_tzEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_9StringValES9_',
'_ZN5doris18TimestampFunctions18convert_tz_prepareEPN9doris_udf15FunctionContextENS2_18FunctionStateScopeE',
'_ZN5doris18TimestampFunctions16convert_tz_closeEPN9doris_udf15FunctionContextENS2_18FunctionStateScopeE'],
[['years_diff'], 'BIGINT', ['DATETIME', 'DATETIME'],
'_ZN5doris18TimestampFunctions10years_diffEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],

View File

@ -308,7 +308,7 @@ ${DORIS_TEST_BINARY_DIR}/olap/key_coder_test
${DORIS_TEST_BINARY_DIR}/olap/page_cache_test
${DORIS_TEST_BINARY_DIR}/olap/hll_test
${DORIS_TEST_BINARY_DIR}/olap/selection_vector_test
${DORIS_TEST_BINARY_DIR}/olap/push_handler_test
# ${DORIS_TEST_BINARY_DIR}/olap/push_handler_test
# Running routine load test
${DORIS_TEST_BINARY_DIR}/runtime/kafka_consumer_pipe_test