TimeTrex/classes/modules/users/UserPreferenceFactory.class.php

2677 lines
145 KiB
PHP

<?php
/*********************************************************************************
*
* TimeTrex is a Workforce Management program developed by
* TimeTrex Software Inc. Copyright (C) 2003 - 2021 TimeTrex Software Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY TIMETREX, TIMETREX DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
*
* You should have received a copy of the GNU Affero General Public License along
* with this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
*
* You can contact TimeTrex headquarters at Unit 22 - 2475 Dobbin Rd. Suite
* #292 West Kelowna, BC V4T 2E9, Canada or at email address info@timetrex.com.
*
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by TimeTrex" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by TimeTrex".
*
********************************************************************************/
/**
* @package Modules\Users
*/
class UserPreferenceFactory extends Factory {
protected $table = 'user_preference';
protected $pk_sequence_name = 'user_preference_id_seq'; //PK Sequence name
var $user_obj = null;
/**
* @param $name
* @param array $params
* @return array|bool|null
*/
function _getFactoryOptions( $name, $params = null ) {
$retval = null;
switch ( $name ) {
// I18n: No need to use gettext because these options only appear for english.
case 'date_format':
$retval = [
'd-M-y' => TTi18n::gettext( '25-Feb-01 (dd-mmm-yy)' ),
'd-M-Y' => TTi18n::gettext( '25-Feb-2001 (dd-mmm-yyyy)' ),
//PHP 5.1.2 fails to parse these with strtotime it looks like
//'d/M/y' => '25/Feb/01 (dd/mmm/yy)',
//'d/M/Y' => '25/Feb/2001 (dd/mmm/yyyy)',
'dMY' => TTi18n::gettext( '25Feb2001 (ddmmmyyyy)' ),
'd/m/Y' => '25/02/2001 (dd/mm/yyyy)',
'd/m/y' => '25/02/01 (dd/mm/yy)',
'd-m-y' => '25-02-01 (dd-mm-yy)',
'd-m-Y' => '25-02-2001 (dd-mm-yyyy)',
'm/d/y' => '02/25/01 (mm/dd/yy)',
'm/d/Y' => '02/25/2001 (mm/dd/yyyy)',
'm-d-y' => '02-25-01 (mm-dd-yy)',
'm-d-Y' => '02-25-2001 (mm-dd-yyyy)',
'Y-m-d' => '2001-02-25 (yyyy-mm-dd)',
//'Ymd' => '20010225 (yyyymmdd)', //This can't be parsed properly due to all integer values, parseDateTime() thinks its an epoch.
'M-d-y' => TTi18n::gettext( 'Feb-25-01 (mmm-dd-yy)' ),
'M-d-Y' => TTi18n::gettext( 'Feb-25-2001 (mmm-dd-yyyy)' ),
'l, F d Y' => TTi18n::gettext( 'Sunday, February 25 2001' ),
'D, F d Y' => TTi18n::gettext( 'Sun, February 25 2001' ),
'D, M d Y' => TTi18n::gettext( 'Sun, Feb 25 2001' ),
'D, d-M-Y' => TTi18n::gettext( 'Sun, 25-Feb-2001' ),
'D, dMY' => TTi18n::gettext( 'Sun, 25Feb2001' ),
];
if ( defined( 'TIMETREX_API' ) == true && TIMETREX_API == true ) {
$retval = Misc::addSortPrefix( $retval );
}
break;
// I18n: We use fewer calendar options for non-en langs, as otherwise strtotime chokes.
case 'date_format_example':
$retval = [
'd-M-y' => TTi18n::gettext( 'dd-mmm-yy' ),
'd-M-Y' => TTi18n::gettext( 'dd-mmm-yyyy' ),
'dMY' => TTi18n::gettext( 'ddmmmyyyy' ),
'd/m/Y' => 'dd/mm/yyyy',
'd/m/y' => 'dd/mm/yy',
'd-m-y' => 'dd-mm-yy',
'd-m-Y' => 'dd-mm-yyyy',
'm/d/y' => 'mm/dd/yy',
'm/d/Y' => 'mm/dd/yyyy',
'm-d-y' => 'mm-dd-yy',
'm-d-Y' => 'mm-dd-yyyy',
'Y-m-d' => 'yyyy-mm-dd',
'M-d-y' => TTi18n::gettext( 'mmm-dd-yy' ),
'M-d-Y' => TTi18n::gettext( 'mmm-dd-yyyy' ),
'l, F d Y' => TTi18n::gettext( 'mmmmmmmm dd yyyy' ),
'D, F d Y' => TTi18n::gettext( 'mmmmmmmm dd yyyy' ),
'D, M d Y' => TTi18n::gettext( 'mm dd yyyy' ),
'D, d-M-Y' => TTi18n::gettext( 'dd-mmm-yy' ),
'D, dMY' => TTi18n::gettext( 'ddmmmyyyy' ),
];
break;
case 'other_date_format':
$retval = [
'd/m/Y' => '25/02/2001 (dd/mm/yyyy)',
'd/m/y' => '25/02/01 (dd/mm/yy)',
'd-m-y' => '25-02-01 (dd-mm-yy)',
'd-m-Y' => '25-02-2001 (dd-mm-yyyy)',
'm/d/y' => '02/25/01 (mm/dd/yy)',
'm/d/Y' => '02/25/2001 (mm/dd/yyyy)',
'm-d-y' => '02-25-01 (mm-dd-yy)',
'm-d-Y' => '02-25-2001 (mm-dd-yyyy)',
'Y-m-d' => '2001-02-25 (yyyy-mm-dd)',
];
if ( defined( 'TIMETREX_API' ) == true && TIMETREX_API == true ) {
$retval = Misc::addSortPrefix( $retval );
}
break;
case 'moment_date_format':
//NOTICE: When changing these, we may need to update the mobile app as it has them hardcoded there too.
$retval = [
'D, F d Y' => 'ddd, MMMM DD YYYY',
'D, M d Y' => 'ddd, MMM DD YYYY',
'D, d-M-Y' => 'ddd, DD-MMM-YYYY',
'D, dMY' => 'ddd, DDMMMYYYY',
'M-d-Y' => 'MMM-DD-YYYY',
'M-d-y' => 'MMM-DD-YY',
'Y-m-d' => 'YYYY-MM-DD',
'd-M-Y' => 'DD-MMM-YYYY',
'd-M-y' => 'DD-MMM-YY',
'd-m-Y' => 'DD-MM-YYYY',
'd-m-y' => 'DD-MM-YY',
'd/m/Y' => 'DD/MM/YYYY',
'd/m/y' => 'DD/MM/YY',
'dMY' => 'DDMMMYYYY',
'l, F d Y' => 'dddd, MMMM DD YYYY',
'm-d-Y' => 'MM-DD-YYYY',
'm-d-y' => 'MM-DD-YY',
'm/d/Y' => 'MM/DD/YYYY',
'm/d/y' => 'MM/DD/YY',
];
break;
case 'time_format':
$retval = [
'g:i A' => TTi18n::gettext( '8:09 PM' ),
'g:i a' => TTi18n::gettext( '8:09 pm' ),
'G:i' => TTi18n::gettext( '20:09' ),
'g:i A T' => TTi18n::gettext( '8:09 PM GMT' ),
'G:i T' => TTi18n::gettext( '20:09 GMT' ),
//Include seconds so they can properly validate rounding policies and such.
'g:i:s A' => TTi18n::gettext( '8:09:11 PM' ),
'g:i:s a' => TTi18n::gettext( '8:09:11 pm' ),
'G:i:s' => TTi18n::gettext( '20:09:11' ),
'g:i:s A T' => TTi18n::gettext( '8:09:11 PM GMT' ),
'G:i:s T' => TTi18n::gettext( '20:09:11 GMT' ),
];
break;
case 'time_format_example':
$retval = [
'g:i A' => TTi18n::gettext( 'HH:MM AM' ),
'g:i a' => TTi18n::gettext( 'HH:MM am' ),
'G:i' => TTi18n::gettext( 'HH:MM' ),
'g:i A T' => TTi18n::gettext( 'HH:MM AM TZ' ),
'G:i T' => TTi18n::gettext( 'HH:MM TZ' ),
'g:i:s A' => TTi18n::gettext( 'HH:MM:SS AM' ),
'g:i:s a' => TTi18n::gettext( 'HH:MM:SS am' ),
'G:i:s' => TTi18n::gettext( 'HH:MM:SS' ),
'g:i:s A T' => TTi18n::gettext( 'HH:MM:SS AM TZ' ),
'G:i:s T' => TTi18n::gettext( 'HH:MM:SS TZ' ),
];
break;
case 'moment_time_format':
$retval = [
'g:i A' => 'hh:mm A',
'g:i a' => 'hh:mm a',
'G:i' => 'HH:mm',
'g:i A T' => 'hh:mm A Z',
'G:i T' => 'HH:mm Z',
//Include seconds so they can properly validate rounding policies and such.
'g:i:s A' => 'hh:mm:ss A',
'g:i:s a' => 'hh:mm:ss a',
'G:i:s' => 'HH:mm:ss',
'g:i:s A T' => 'hh:mm:ss A Z',
'G:i:s T' => 'HH:mm:ss Z',
];
break;
case 'date_time_format':
//Merge Date and Time formats together.
$date_formats = $this->getOptions( 'date_format' );
$time_formats = $this->getOptions( 'time_format' );
if ( is_array( $date_formats ) && is_array( $time_formats ) ) {
foreach ( $date_formats as $date_format => $date_format_name ) {
foreach ( $time_formats as $time_format => $time_format_name ) {
//Use "|" as a separate so we can later split them back into separate date/time formats.
$retval[$date_format . '_' . $time_format] = trim( preg_replace( '/\(.*\)/i', '', $date_format_name ) ) . ' ' . $time_format_name;
}
}
}
break;
case 'time_unit_format':
$retval = [
10 => TTi18n::gettext( 'hh:mm (2:15)' ),
12 => TTi18n::gettext( 'hh:mm:ss (2:15:59)' ),
20 => TTi18n::gettext( 'Hours (2.25)' ),
22 => TTi18n::gettext( 'Hours (2.141)' ),
23 => TTi18n::gettext( 'Hours (2.3587)' ),
30 => TTi18n::gettext( 'Minutes (135)' ),
40 => TTi18n::gettext( 'Seconds (3600)' ),
];
break;
case 'distance_format':
$retval = [
10 => TTi18n::gettext( 'Kilometers' ),
20 => TTi18n::gettext( 'Miles' ),
30 => TTi18n::gettext( 'Meters' ),
];
break;
// I18n: These timezones probably should be translated, but doing so would add ~550
// lines to the translator's workload for each lang. And these are hard to translate.
// Probably better to use an already translated timezone class, if one exists.
//
//Commented out timezones do not work in PostgreSQL 8.2, as they hardcode timezone data into versions.
case 'time_zone':
$retval = [
'America/Adak' => 'America/Adak',
'America/Anchorage' => 'America/Anchorage',
'America/Anguilla' => 'America/Anguilla',
'America/Antigua' => 'America/Antigua',
'America/Araguaina' => 'America/Araguaina',
'America/Aruba' => 'America/Aruba',
'America/Asuncion' => 'America/Asuncion',
'America/Barbados' => 'America/Barbados',
'America/Belem' => 'America/Belem',
'America/Belize' => 'America/Belize',
'America/Boa_Vista' => 'America/Boa Vista',
'America/Bogota' => 'America/Bogota',
'America/Boise' => 'America/Boise',
'America/Buenos_Aires' => 'America/Buenos Aires',
'America/Cambridge_Bay' => 'America/Cambridge Bay',
'America/Cancun' => 'America/Cancun',
'America/Caracas' => 'America/Caracas',
'America/Catamarca' => 'America/Catamarca',
'America/Cayenne' => 'America/Cayenne',
'America/Cayman' => 'America/Cayman',
'America/Chicago' => 'America/Chicago',
'America/Chihuahua' => 'America/Chihuahua',
'America/Cordoba' => 'America/Cordoba',
'America/Costa_Rica' => 'America/Costa Rica',
'America/Cuiaba' => 'America/Cuiaba',
'America/Curacao' => 'America/Curacao',
'America/Danmarkshavn' => 'America/Danmarkshavn',
'America/Dawson' => 'America/Dawson',
'America/Dawson_Creek' => 'America/Dawson Creek',
'America/Denver' => 'America/Denver',
'America/Detroit' => 'America/Detroit',
'America/Dominica' => 'America/Dominica',
'America/Edmonton' => 'America/Edmonton',
'America/Eirunepe' => 'America/Eirunepe',
'America/El_Salvador' => 'America/El Salvador',
'America/Ensenada' => 'America/Ensenada',
'America/Fort_Wayne' => 'America/Fort Wayne',
'America/Fortaleza' => 'America/Fortaleza',
'America/Glace_Bay' => 'America/Glace Bay',
'America/Godthab' => 'America/Godthab',
'America/Goose_Bay' => 'America/Goose Bay',
'America/Grand_Turk' => 'America/Grand Turk',
'America/Grenada' => 'America/Grenada',
'America/Guadeloupe' => 'America/Guadeloupe',
'America/Guatemala' => 'America/Guatemala',
'America/Guayaquil' => 'America/Guayaquil',
'America/Guyana' => 'America/Guyana',
'America/Halifax' => 'America/Halifax',
'America/Havana' => 'America/Havana',
'America/Hermosillo' => 'America/Hermosillo',
'America/Indiana/Indianapolis' => 'America/Indiana/Indianapolis',
'America/Indiana/Knox' => 'America/Indiana/Knox',
'America/Indiana/Marengo' => 'America/Indiana/Marengo',
'America/Indiana/Vevay' => 'America/Indiana/Vevay',
'America/Indianapolis' => 'America/Indianapolis',
'America/Inuvik' => 'America/Inuvik',
'America/Iqaluit' => 'America/Iqaluit',
'America/Jamaica' => 'America/Jamaica',
'America/Jujuy' => 'America/Jujuy',
'America/Juneau' => 'America/Juneau',
'America/Kentucky/Louisville' => 'America/Kentucky/Louisville',
'America/Kentucky/Monticello' => 'America/Kentucky/Monticello',
'America/Knox_IN' => 'America/Knox IN',
'America/La_Paz' => 'America/La Paz',
'America/Lima' => 'America/Lima',
'America/Los_Angeles' => 'America/Los Angeles',
'America/Louisville' => 'America/Louisville',
'America/Maceio' => 'America/Maceio',
'America/Managua' => 'America/Managua',
'America/Manaus' => 'America/Manaus',
'America/Martinique' => 'America/Martinique',
'America/Mazatlan' => 'America/Mazatlan',
'America/Mendoza' => 'America/Mendoza',
'America/Menominee' => 'America/Menominee',
'America/Merida' => 'America/Merida',
'America/Mexico_City' => 'America/Mexico City',
'America/Miquelon' => 'America/Miquelon',
'America/Moncton' => 'America/Moncton',
'America/Monterrey' => 'America/Monterrey',
'America/Montevideo' => 'America/Montevideo',
'America/Montreal' => 'America/Montreal',
'America/Montserrat' => 'America/Montserrat',
'America/Nassau' => 'America/Nassau',
'America/New_York' => 'America/New York',
'America/Nipigon' => 'America/Nipigon',
'America/Nome' => 'America/Nome',
'America/Noronha' => 'America/Noronha',
'America/North_Dakota/Center' => 'America/North Dakota/Center',
'America/Panama' => 'America/Panama',
'America/Pangnirtung' => 'America/Pangnirtung',
'America/Paramaribo' => 'America/Paramaribo',
'America/Phoenix' => 'America/Phoenix',
'America/Port-au-Prince' => 'America/Port-au-Prince',
'America/Port_of_Spain' => 'America/Port of Spain',
'America/Porto_Acre' => 'America/Porto Acre',
'America/Porto_Velho' => 'America/Porto Velho',
'America/Puerto_Rico' => 'America/Puerto Rico',
'America/Rainy_River' => 'America/Rainy River',
'America/Rankin_Inlet' => 'America/Rankin Inlet',
'America/Recife' => 'America/Recife',
'America/Regina' => 'America/Regina',
'America/Rio_Branco' => 'America/Rio Branco',
'America/Rosario' => 'America/Rosario',
'America/Santiago' => 'America/Santiago',
'America/Santo_Domingo' => 'America/Santo Domingo',
'America/Sao_Paulo' => 'America/Sao Paulo',
'America/Scoresbysund' => 'America/Scoresbysund',
'America/Shiprock' => 'America/Shiprock',
'America/St_Johns' => 'America/St Johns',
'America/St_Kitts' => 'America/St Kitts',
'America/St_Lucia' => 'America/St Lucia',
'America/St_Thomas' => 'America/St Thomas',
'America/St_Vincent' => 'America/St Vincent',
'America/Swift_Current' => 'America/Swift Current',
'America/Tegucigalpa' => 'America/Tegucigalpa',
'America/Thule' => 'America/Thule',
'America/Thunder_Bay' => 'America/Thunder Bay',
'America/Tijuana' => 'America/Tijuana',
'America/Toronto' => 'America/Toronto',
'America/Tortola' => 'America/Tortola',
'America/Vancouver' => 'America/Vancouver',
'America/Virgin' => 'America/Virgin',
'America/Whitehorse' => 'America/Whitehorse',
'America/Winnipeg' => 'America/Winnipeg',
'America/Yakutat' => 'America/Yakutat',
'America/Yellowknife' => 'America/Yellowknife',
'Africa/Abidjan' => 'Africa/Abidjan',
'Africa/Accra' => 'Africa/Accra',
'Africa/Addis_Ababa' => 'Africa/Addis Ababa',
'Africa/Algiers' => 'Africa/Algiers',
'Africa/Asmera' => 'Africa/Asmera',
'Africa/Bamako' => 'Africa/Bamako',
'Africa/Bangui' => 'Africa/Bangui',
'Africa/Banjul' => 'Africa/Banjul',
'Africa/Bissau' => 'Africa/Bissau',
'Africa/Brazzaville' => 'Africa/Brazzaville',
'Africa/Cairo' => 'Africa/Cairo',
'Africa/Casablanca' => 'Africa/Casablanca',
'Africa/Ceuta' => 'Africa/Ceuta',
'Africa/Conakry' => 'Africa/Conakry',
'Africa/Dakar' => 'Africa/Dakar',
'Africa/Dar_es_Salaam' => 'Africa/Dar es Salaam',
'Africa/Djibouti' => 'Africa/Djibouti',
'Africa/Douala' => 'Africa/Douala',
'Africa/El_Aaiun' => 'Africa/El Aaiun',
'Africa/Freetown' => 'Africa/Freetown',
'Africa/Johannesburg' => 'Africa/Johannesburg',
'Africa/Kampala' => 'Africa/Kampala',
'Africa/Khartoum' => 'Africa/Khartoum',
'Africa/Kinshasa' => 'Africa/Kinshasa',
'Africa/Lagos' => 'Africa/Lagos',
'Africa/Libreville' => 'Africa/Libreville',
'Africa/Lome' => 'Africa/Lome',
'Africa/Luanda' => 'Africa/Luanda',
'Africa/Malabo' => 'Africa/Malabo',
'Africa/Maputo' => 'Africa/Maputo',
'Africa/Maseru' => 'Africa/Maseru',
'Africa/Mbabane' => 'Africa/Mbabane',
'Africa/Mogadishu' => 'Africa/Mogadishu',
'Africa/Monrovia' => 'Africa/Monrovia',
'Africa/Nairobi' => 'Africa/Nairobi',
'Africa/Ndjamena' => 'Africa/Ndjamena',
'Africa/Niamey' => 'Africa/Niamey',
'Africa/Nouakchott' => 'Africa/Nouakchott',
'Africa/Ouagadougou' => 'Africa/Ouagadougou',
'Africa/Porto-Novo' => 'Africa/Porto-Novo',
'Africa/Sao_Tome' => 'Africa/Sao Tome',
'Africa/Timbuktu' => 'Africa/Timbuktu',
'Africa/Tripoli' => 'Africa/Tripoli',
'Africa/Tunis' => 'Africa/Tunis',
'Africa/Windhoek' => 'Africa/Windhoek',
'Asia/Aden' => 'Asia/Aden',
'Asia/Almaty' => 'Asia/Almaty',
'Asia/Amman' => 'Asia/Amman',
'Asia/Anadyr' => 'Asia/Anadyr',
'Asia/Aqtau' => 'Asia/Aqtau',
'Asia/Aqtobe' => 'Asia/Aqtobe',
'Asia/Ashgabat' => 'Asia/Ashgabat',
'Asia/Ashkhabad' => 'Asia/Ashkhabad',
'Asia/Baghdad' => 'Asia/Baghdad',
'Asia/Bahrain' => 'Asia/Bahrain',
'Asia/Baku' => 'Asia/Baku',
'Asia/Bangkok' => 'Asia/Bangkok',
'Asia/Beirut' => 'Asia/Beirut',
'Asia/Bishkek' => 'Asia/Bishkek',
'Asia/Brunei' => 'Asia/Brunei',
'Asia/Calcutta' => 'Asia/Calcutta',
'Asia/Choibalsan' => 'Asia/Choibalsan',
'Asia/Chongqing' => 'Asia/Chongqing',
'Asia/Chungking' => 'Asia/Chungking',
'Asia/Colombo' => 'Asia/Colombo',
'Asia/Dacca' => 'Asia/Dacca',
'Asia/Damascus' => 'Asia/Damascus',
'Asia/Dhaka' => 'Asia/Dhaka',
'Asia/Dili' => 'Asia/Dili',
'Asia/Dubai' => 'Asia/Dubai',
'Asia/Dushanbe' => 'Asia/Dushanbe',
'Asia/Gaza' => 'Asia/Gaza',
'Asia/Harbin' => 'Asia/Harbin',
'Asia/Hong_Kong' => 'Asia/Hong Kong',
'Asia/Hovd' => 'Asia/Hovd',
'Asia/Irkutsk' => 'Asia/Irkutsk',
'Asia/Istanbul' => 'Asia/Istanbul',
'Asia/Jakarta' => 'Asia/Jakarta',
'Asia/Jayapura' => 'Asia/Jayapura',
'Asia/Jerusalem' => 'Asia/Jerusalem', //Offset 10800
'Asia/Kabul' => 'Asia/Kabul',
'Asia/Kamchatka' => 'Asia/Kamchatka',
'Asia/Karachi' => 'Asia/Karachi',
'Asia/Kashgar' => 'Asia/Kashgar',
'Asia/Katmandu' => 'Asia/Katmandu',
'Asia/Kolkata' => 'Asia/Kolkata',
'Asia/Krasnoyarsk' => 'Asia/Krasnoyarsk',
'Asia/Kuala_Lumpur' => 'Asia/Kuala Lumpur',
'Asia/Kuching' => 'Asia/Kuching',
'Asia/Kuwait' => 'Asia/Kuwait',
'Asia/Macao' => 'Asia/Macao',
'Asia/Magadan' => 'Asia/Magadan',
'Asia/Manila' => 'Asia/Manila',
'Asia/Nicosia' => 'Asia/Nicosia',
'Asia/Novosibirsk' => 'Asia/Novosibirsk',
'Asia/Omsk' => 'Asia/Omsk',
'Asia/Phnom_Penh' => 'Asia/Phnom Penh',
'Asia/Pontianak' => 'Asia/Pontianak',
'Asia/Pyongyang' => 'Asia/Pyongyang',
'Asia/Qatar' => 'Asia/Qatar',
'Asia/Rangoon' => 'Asia/Rangoon',
'Asia/Riyadh' => 'Asia/Riyadh',
'Asia/Saigon' => 'Asia/Saigon',
'Asia/Sakhalin' => 'Asia/Sakhalin',
'Asia/Samarkand' => 'Asia/Samarkand',
'Asia/Seoul' => 'Asia/Seoul',
'Asia/Shanghai' => 'Asia/Shanghai',
'Asia/Singapore' => 'Asia/Singapore',
'Asia/Taipei' => 'Asia/Taipei',
'Asia/Tashkent' => 'Asia/Tashkent',
'Asia/Tbilisi' => 'Asia/Tbilisi',
'Asia/Tehran' => 'Asia/Tehran',
'Asia/Thimbu' => 'Asia/Thimbu',
'Asia/Thimphu' => 'Asia/Thimphu',
'Asia/Tokyo' => 'Asia/Tokyo',
'Asia/Ulaanbaatar' => 'Asia/Ulaanbaatar',
'Asia/Ulan_Bator' => 'Asia/Ulan Bator',
'Asia/Urumqi' => 'Asia/Urumqi',
'Asia/Vientiane' => 'Asia/Vientiane',
'Asia/Vladivostok' => 'Asia/Vladivostok',
'Asia/Yakutsk' => 'Asia/Yakutsk',
'Asia/Yekaterinburg' => 'Asia/Yekaterinburg',
'Asia/Yerevan' => 'Asia/Yerevan',
'Atlantic/Azores' => 'Atlantic/Azores',
'Atlantic/Bermuda' => 'Atlantic/Bermuda',
'Atlantic/Canary' => 'Atlantic/Canary',
'Atlantic/Cape_Verde' => 'Atlantic/Cape Verde',
'Atlantic/Jan_Mayen' => 'Atlantic/Jan Mayen',
'Atlantic/Madeira' => 'Atlantic/Madeira',
'Atlantic/Reykjavik' => 'Atlantic/Reykjavik',
'Atlantic/South_Georgia' => 'Atlantic/South Georgia',
'Atlantic/St_Helena' => 'Atlantic/St Helena',
'Atlantic/Stanley' => 'Atlantic/Stanley',
'Australia/Adelaide' => 'Australia/Adelaide',
'Australia/Brisbane' => 'Australia/Brisbane',
'Australia/Broken_Hill' => 'Australia/Broken Hill',
'Australia/Canberra' => 'Australia/Canberra',
'Australia/Darwin' => 'Australia/Darwin',
'Australia/Hobart' => 'Australia/Hobart',
'Australia/Lindeman' => 'Australia/Lindeman',
'Australia/Lord_Howe' => 'Australia/Lord Howe',
'Australia/Melbourne' => 'Australia/Melbourne',
'Australia/Perth' => 'Australia/Perth',
'Australia/Sydney' => 'Australia/Sydney',
'Australia/Yancowinna' => 'Australia/Yancowinna',
'Europe/Amsterdam' => 'Europe/Amsterdam',
'Europe/Andorra' => 'Europe/Andorra',
'Europe/Athens' => 'Europe/Athens',
'Europe/Belfast' => 'Europe/Belfast',
'Europe/Belgrade' => 'Europe/Belgrade',
'Europe/Berlin' => 'Europe/Berlin',
'Europe/Bratislava' => 'Europe/Bratislava',
'Europe/Brussels' => 'Europe/Brussels',
'Europe/Bucharest' => 'Europe/Bucharest',
'Europe/Budapest' => 'Europe/Budapest',
'Europe/Chisinau' => 'Europe/Chisinau',
'Europe/Copenhagen' => 'Europe/Copenhagen',
'Europe/Dublin' => 'Europe/Dublin',
'Europe/Gibraltar' => 'Europe/Gibraltar',
'Europe/Helsinki' => 'Europe/Helsinki',
'Europe/Istanbul' => 'Europe/Istanbul',
'Europe/Kaliningrad' => 'Europe/Kaliningrad',
'Europe/Kiev' => 'Europe/Kiev',
'Europe/Lisbon' => 'Europe/Lisbon',
'Europe/Ljubljana' => 'Europe/Ljubljana',
'Europe/London' => 'Europe/London',
'Europe/Luxembourg' => 'Europe/Luxembourg',
'Europe/Madrid' => 'Europe/Madrid',
'Europe/Malta' => 'Europe/Malta',
'Europe/Minsk' => 'Europe/Minsk',
'Europe/Monaco' => 'Europe/Monaco',
'Europe/Moscow' => 'Europe/Moscow',
'Europe/Nicosia' => 'Europe/Nicosia',
'Europe/Oslo' => 'Europe/Oslo',
'Europe/Paris' => 'Europe/Paris',
'Europe/Prague' => 'Europe/Prague',
'Europe/Riga' => 'Europe/Riga',
'Europe/Rome' => 'Europe/Rome',
'Europe/Samara' => 'Europe/Samara',
'Europe/San_Marino' => 'Europe/San Marino',
'Europe/Sarajevo' => 'Europe/Sarajevo',
'Europe/Simferopol' => 'Europe/Simferopol',
'Europe/Skopje' => 'Europe/Skopje',
'Europe/Sofia' => 'Europe/Sofia',
'Europe/Stockholm' => 'Europe/Stockholm',
'Europe/Tallinn' => 'Europe/Tallinn',
'Europe/Tirane' => 'Europe/Tirane',
'Europe/Tiraspol' => 'Europe/Tiraspol',
'Europe/Uzhgorod' => 'Europe/Uzhgorod',
'Europe/Vaduz' => 'Europe/Vaduz',
'Europe/Vatican' => 'Europe/Vatican',
'Europe/Vienna' => 'Europe/Vienna',
'Europe/Vilnius' => 'Europe/Vilnius',
'Europe/Warsaw' => 'Europe/Warsaw',
'Europe/Zagreb' => 'Europe/Zagreb',
'Europe/Zaporozhye' => 'Europe/Zaporozhye',
'Europe/Zurich' => 'Europe/Zurich',
'-1000-Asia/Calcutta' => 'India', //GMT+5:30, same as Asia Calcutta
'Indian/Antananarivo' => 'Indian/Antananarivo',
'Indian/Chagos' => 'Indian/Chagos',
'Indian/Christmas' => 'Indian/Christmas',
'Indian/Cocos' => 'Indian/Cocos',
'Indian/Comoro' => 'Indian/Comoro',
'Indian/Kerguelen' => 'Indian/Kerguelen',
'Indian/Mahe' => 'Indian/Mahe',
'Indian/Maldives' => 'Indian/Maldives',
'Indian/Mauritius' => 'Indian/Mauritius',
'Indian/Mayotte' => 'Indian/Mayotte',
'Indian/Reunion' => 'Indian/Reunion',
'Pacific/Apia' => 'Pacific/Apia',
'Pacific/Auckland' => 'Pacific/Auckland',
'Pacific/Chatham' => 'Pacific/Chatham',
'Pacific/Easter' => 'Pacific/Easter',
'Pacific/Efate' => 'Pacific/Efate',
'Pacific/Enderbury' => 'Pacific/Enderbury',
'Pacific/Fakaofo' => 'Pacific/Fakaofo',
'Pacific/Fiji' => 'Pacific/Fiji',
'Pacific/Funafuti' => 'Pacific/Funafuti',
'Pacific/Galapagos' => 'Pacific/Galapagos',
'Pacific/Gambier' => 'Pacific/Gambier',
'Pacific/Guadalcanal' => 'Pacific/Guadalcanal',
'Pacific/Guam' => 'Pacific/Guam',
'Pacific/Honolulu' => 'Pacific/Honolulu',
'Pacific/Johnston' => 'Pacific/Johnston',
'Pacific/Kiritimati' => 'Pacific/Kiritimati',
'Pacific/Kosrae' => 'Pacific/Kosrae',
'Pacific/Kwajalein' => 'Pacific/Kwajalein',
'Pacific/Majuro' => 'Pacific/Majuro',
'Pacific/Marquesas' => 'Pacific/Marquesas',
'Pacific/Nauru' => 'Pacific/Nauru',
'Pacific/Niue' => 'Pacific/Niue',
'Pacific/Norfolk' => 'Pacific/Norfolk',
'Pacific/Noumea' => 'Pacific/Noumea',
'Pacific/Pago_Pago' => 'Pacific/Pago Pago',
'Pacific/Palau' => 'Pacific/Palau',
'Pacific/Pitcairn' => 'Pacific/Pitcairn',
'Pacific/Ponape' => 'Pacific/Ponape',
'Pacific/Port_Moresby' => 'Pacific/Port Moresby',
'Pacific/Rarotonga' => 'Pacific/Rarotonga',
'Pacific/Tahiti' => 'Pacific/Tahiti',
'Pacific/Tarawa' => 'Pacific/Tarawa',
'Pacific/Tongatapu' => 'Pacific/Tongatapu',
'Pacific/Truk' => 'Pacific/Truk',
'Pacific/Wake' => 'Pacific/Wake',
'Pacific/Wallis' => 'Pacific/Wallis',
'Pacific/Yap' => 'Pacific/Yap',
'Antarctica/Casey' => 'Antarctica/Casey',
'Antarctica/Davis' => 'Antarctica/Davis',
'Antarctica/DumontDUrville' => 'Antarctica/DumontDUrville',
'Antarctica/Mawson' => 'Antarctica/Mawson',
'Antarctica/McMurdo' => 'Antarctica/McMurdo',
'Antarctica/Palmer' => 'Antarctica/Palmer',
'Antarctica/South_Pole' => 'Antarctica/South Pole',
'Antarctica/Syowa' => 'Antarctica/Syowa',
'Antarctica/Vostok' => 'Antarctica/Vostok',
'Arctic/Longyearbyen' => 'Arctic/Longyearbyen',
//POSIX standard states to invert the signs, so do this here for our users.
'Etc/GMT' => 'GMT',
'Etc/GMT-0' => 'GMT+0',
'Etc/GMT-1' => 'GMT+1',
'Etc/GMT-2' => 'GMT+2',
'Etc/GMT-3' => 'GMT+3',
'Etc/GMT-4' => 'GMT+4',
'Etc/GMT-5' => 'GMT+5',
'Etc/GMT-6' => 'GMT+6',
'Etc/GMT-7' => 'GMT+7',
'Etc/GMT-8' => 'GMT+8',
'Etc/GMT-9' => 'GMT+9',
'Etc/GMT-10' => 'GMT+10',
'Etc/GMT-11' => 'GMT+11',
'Etc/GMT-12' => 'GMT+12',
'Etc/GMT-13' => 'GMT+13',
'Etc/GMT-14' => 'GMT+14',
'Etc/GMT+0' => 'GMT-0',
'Etc/GMT+1' => 'GMT-1',
'Etc/GMT+2' => 'GMT-2',
'Etc/GMT+3' => 'GMT-3',
'Etc/GMT+4' => 'GMT-4',
'Etc/GMT+5' => 'GMT-5',
'Etc/GMT+6' => 'GMT-6',
'Etc/GMT+7' => 'GMT-7',
'Etc/GMT+8' => 'GMT-8',
'Etc/GMT+9' => 'GMT-9',
'Etc/GMT+10' => 'GMT-10',
'Etc/GMT+11' => 'GMT-11',
'Etc/GMT+12' => 'GMT-12',
'GMT' => 'GMT',
'UTC' => 'UTC',
];
if ( defined( 'TIMETREX_API' ) == true && TIMETREX_API == true ) {
$retval = Misc::addSortPrefix( $retval );
}
break;
case 'deprecated_timezone':
$retval = [
'YST9YDT' => 'America/Yakutat',
'SystemV/YST9YDT' => 'America/Yakutat',
'AST4ADT' => 'Atlantic/Bermuda',
'SystemV/AST4ADT' => 'Atlantic/Bermuda',
'Australia/ACT' => 'Australia/Sydney',
'Australia/LHI' => 'Australia/Lord_Howe',
'Australia/North' => 'Australia/Darwin',
'Australia/NSW' => 'Australia/Sydney',
'Australia/Queensland' => 'Australia/Brisbane',
'Australia/South' => 'Australia/Adelaide',
'Australia/Tasmania' => 'Australia/Hobart',
'Australia/Victoria' => 'Australia/Melbourne',
'Australia/West' => 'Australia/Perth',
'Brazil/Acre' => 'America/Rio_Branco',
'Brazil/DeNoronha' => 'America/Noronha',
'Brazil/East' => 'America/Sao_Paulo',
'Brazil/West' => 'America/Manaus',
'Canada/Atlantic' => 'America/Halifax',
'Canada/Central' => 'America/Winnipeg',
'Canada/Eastern' => 'America/Toronto',
'Canada/Mountain' => 'America/Edmonton',
'Canada/Newfoundland' => 'America/St_Johns',
'Canada/Pacific' => 'America/Vancouver',
'Canada/Saskatchewan' => 'America/Regina',
'Canada/East-Saskatchewan' => 'America/Regina',
'Canada/Yukon' => 'America/Whitehorse',
'CET' => 'Europe/Paris',
'Chile/Continental' => 'America/Santiago',
'Chile/EasterIsland' => 'Pacific/Easter',
'CST5CDT' => 'America/Chicago', //Bogus timezone that was in use briefly.
'CST6CDT' => 'America/Chicago',
'Cuba' => 'America/Havana',
'EET' => 'Europe/Sofia',
'Egypt' => 'Africa/Cairo',
'Eire' => 'Europe/Dublin',
'EST' => 'America/Cancun',
'EST5EDT' => 'America/New_York',
'Etc/Greenwich' => 'GMT',
'Etc/UCT' => 'UTC',
'Etc/Universal' => 'UTC',
'Etc/Zulu' => 'UTC',
'GB' => 'Europe/London',
'GB-Eire' => 'Europe/London',
'GMT+0' => 'GMT',
'GMT0' => 'GMT',
'GMT-0' => 'GMT',
'Greenwich' => 'GMT',
'Hongkong' => 'Asia/Hong_Kong',
'HST' => 'Pacific/Honolulu',
'Iceland' => 'Atlantic/Reykjavik',
'Iran' => 'Asia/Tehran',
'Israel' => 'Asia/Jerusalem',
'Jamaica' => 'America/Jamaica',
'Japan' => 'Asia/Tokyo',
'Kwajalein' => 'Pacific/Kwajalein',
'Libya' => 'Africa/Tripoli',
'MET' => 'Europe/Paris',
'Mexico/BajaNorte' => 'America/Tijuana',
'Mexico/BajaSur' => 'America/Mazatlan',
'Mexico/General' => 'America/Mexico_City',
'MST' => 'America/Phoenix',
'MST7MDT' => 'America/Denver',
'Navajo' => 'America/Denver',
'NZ' => 'Pacific/Auckland',
'NZ-CHAT' => 'Pacific/Chatham',
'Poland' => 'Europe/Warsaw',
'Portugal' => 'Europe/Lisbon',
'PRC' => 'Asia/Shanghai',
'PST8PDT' => 'America/Los_Angeles',
'ROC' => 'Asia/Taipei',
'ROK' => 'Asia/Seoul',
'Singapore' => 'Asia/Singapore',
'Turkey' => 'Europe/Istanbul',
'UCT' => 'UTC',
'Universal' => 'UTC',
'US/Alaska' => 'America/Anchorage',
'US/Aleutian' => 'America/Adak',
'US/Arizona' => 'America/Phoenix',
'US/Central' => 'America/Chicago',
'US/Eastern' => 'America/New_York',
'US/East-Indiana' => 'America/Indiana/Indianapolis',
'US/Hawaii' => 'Pacific/Honolulu',
'US/Indiana-Starke' => 'America/Indiana/Knox',
'US/Michigan' => 'America/Detroit',
'US/Mountain' => 'America/Denver',
'US/Pacific' => 'America/Los_Angeles',
'US/Pacific-New' => 'America/Los_Angeles',
'US/Samoa' => 'Pacific/Pago_Pago',
'WET' => 'Europe/Lisbon',
'W-SU' => 'Europe/Moscow',
'Zulu' => 'UTC',
];
//If the parent is specified as a country, use country specific replacements.
if ( is_array( $params ) && isset( $params['country'] ) && strtolower( $params['country'] ) == 'ca' ) {
$retval = array_merge(
$retval,
[
'YST9YDT' => 'America/Whitehorse',
'SystemV/YST9YDT' => 'America/Whitehorse',
'PST8PDT' => 'America/Vancouver',
'MST7MDT' => 'America/Edmonton',
'CST6CDT' => 'America/Winnipeg',
'CST5CDT' => 'America/Winnipeg', //Bogus timezone that was in use briefly.
'EST5EDT' => 'America/Toronto',
'AST4ADT' => 'America/Halifax',
'SystemV/AST4ADT' => 'America/Halifax',
]
);
}
break;
case 'location_timezone':
//Country/Province to TimeZone map.
$retval = [
'CA' => [
'AB' => 'America/Edmonton',
'BC' => 'America/Vancouver',
'SK' => 'America/Regina',
'MB' => 'America/Winnipeg',
'QC' => 'America/Montreal',
'ON' => 'America/Toronto',
'NL' => 'America/St_Johns',
'NB' => 'America/Moncton',
'NS' => 'America/Halifax',
'PE' => 'America/Halifax',
'NT' => 'America/Yellowknife',
'YT' => 'America/Whitehorse',
'NU' => 'America/Toronto',
],
'US' => [
'AL' => 'America/Chicago',
'AK' => 'America/Anchorage', //Hawaii
'AZ' => 'America/Phoenix',
'AR' => 'America/Chicago',
'CA' => 'America/Los_Angeles',
'CO' => 'America/Denver',
'CT' => 'America/New_York',
'DE' => 'America/New_York',
'DC' => 'America/New_York',
'FL' => [ 'America/New_York', 'America/Chicago' ], //Most common timezone first.
'GA' => 'America/New_York',
'HI' => 'Pacific/Honolulu',
'ID' => [ 'America/Denver', 'America/Los_Angeles' ], //Most common timezone first.
'IL' => 'America/Chicago',
'IN' => [ 'America/New_York', 'America/Chicago' ],
'IA' => 'America/Chicago',
'KS' => [ 'America/Chicago', 'America/Denver' ],
'KY' => [ 'America/New_York', 'America/Chicago' ],
'LA' => 'America/Chicago',
'ME' => 'America/New_York',
'MD' => 'America/New_York',
'MA' => 'America/New_York',
'MI' => [ 'America/New_York', 'America/Denver' ],
'MN' => 'America/Chicago',
'MS' => 'America/Chicago',
'MO' => 'America/Chicago',
'MT' => 'America/Denver',
'NE' => [ 'America/Chicago', 'America/Denver' ],
'NV' => 'America/Los_Angeles',
'NH' => 'America/New_York',
'NM' => 'America/Denver',
'NJ' => 'America/New_York',
'NY' => 'America/New_York',
'NC' => 'America/New_York',
'ND' => [ 'America/Chicago', 'America/Denver' ],
'OH' => 'America/New_York',
'OK' => 'America/Chicago',
'OR' => [ 'America/Los_Angeles', 'America/Denver' ],
'PA' => 'America/New_York',
'RI' => 'America/New_York',
'SC' => 'America/New_York',
'SD' => [ 'America/New_York', 'America/Denver' ],
'TN' => [ 'America/Chicago', 'America/New_York' ],
'TX' => [ 'America/Chicago', 'America/Denver' ],
'UT' => 'America/Denver',
'VT' => 'America/New_York',
'VA' => 'America/New_York',
'WA' => 'America/Los_Angeles',
'WV' => 'America/New_York',
'WI' => 'America/Chicago',
'WY' => 'America/Denver',
],
'AG' => 'America/Antigua',
'AI' => 'America/Anguilla',
'AW' => 'America/Aruba',
'BB' => 'America/Barbados',
'BL' => 'America/St_Barthelemy',
'BM' => 'Atlantic/Bermuda',
'BQ' => 'America/Kralendijk',
'BS' => 'America/Nassau',
'CU' => 'America/Havana',
'CW' => 'America/Curacao',
'DM' => 'America/Dominica',
'DO' => 'America/Santo_Domingo',
'GD' => 'America/Grenada',
'GP' => 'America/Guadeloupe',
'HT' => 'America/Port-au-Prince',
'JM' => 'America/Jamaica',
'KN' => 'America/St_Kitts',
'KY' => 'America/Cayman',
'LC' => 'America/St_Lucia',
'MF' => 'America/Marigot',
'MQ' => 'America/Martinique',
'MS' => 'America/Montserrat',
'MX' => 'America/Mexico_City',
'PR' => 'America/Puerto_Rico',
'SX' => 'America/Lower_Princes',
'TC' => 'America/Grand_Turk',
'TT' => 'America/Port_of_Spain',
'VC' => 'America/St_Vincent',
'VG' => 'America/Tortola',
'VI' => 'America/St_Thomas',
];
break;
case 'area_code_timezone':
//Area code to Country/Province/TimeZone map.
$retval = [
//See area code recent changes here: https://www.areacodehelp.com/area-code-news/area-code-changes.shtml
211 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Local community info / referral services
242 => [ 'country' => 'BS', 'province' => null, 'time_zone' => 'America/New_York' ], // Bahamas
246 => [ 'country' => 'BB', 'province' => null, 'time_zone' => 'America/Nassau' ], // Barbados
264 => [ 'country' => 'AI', 'province' => null, 'time_zone' => 'America/Anguilla' ], // Anguilla (split from 809)
268 => [ 'country' => 'AG', 'province' => null, 'time_zone' => 'America/Antigua' ], // Antigua and Barbuda (split from 809)
284 => [ 'country' => 'VG', 'province' => null, 'time_zone' => 'America/Tortola' ], // British Virgin Islands (split from 809)
311 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Reserved for special applications
345 => [ 'country' => 'KY', 'province' => null, 'time_zone' => 'America/New_York' ], // Cayman Islands
411 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Reserved for special applications
441 => [ 'country' => 'BM', 'province' => null, 'time_zone' => 'Atlantic/Bermuda' ], // Bermuda (part of what used to be 809)
456 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Inbound International
473 => [ 'country' => 'GD', 'province' => null, 'time_zone' => 'America/Grenada' ], // Grenada ("new" -- split from 809)
500 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Personal Communication Service
511 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Nationwide travel information
555 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Reserved for directory assistance applications
600 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Canadian Services
611 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Reserved for special applications
649 => [ 'country' => 'TC', 'province' => null, 'time_zone' => 'America/New_York' ], // Turks & Caicos Islands
664 => [ 'country' => 'MS', 'province' => null, 'time_zone' => 'America/Montserrat' ], // Montserrat (split from 809)
684 => [ 'country' => 'AS', 'province' => null, 'time_zone' => null ], //1 American Samoa
700 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Interexchange Carrier Services
710 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US Government
711 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Telecommunications Relay Services
758 => [ 'country' => 'LC', 'province' => null, 'time_zone' => 'America/St_Lucia' ], // St. Lucia (split from 809)
767 => [ 'country' => 'DM', 'province' => null, 'time_zone' => 'America/Dominica' ], // Dominica (split from 809)
784 => [ 'country' => 'VC', 'province' => null, 'time_zone' => 'America/St_Vincent' ], // St. Vincent & Grenadines (split from 809)
800 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free (see 888, 877, 866, 855, 844, 833, 822)
809 => [ 'country' => 'DO', 'province' => null, 'time_zone' => 'America/Santo_Domingo' ], // Dominican Republic (see splits 264, 268, 284, 340, 441, 473, 664, 758, 767, 784, 868, 876; overlay 829)
849 => [ 'country' => 'DO', 'province' => null, 'time_zone' => 'America/Santo_Domingo' ], // Dominican Republic (see splits 264, 268, 284, 340, 441, 473, 664, 758, 767, 784, 868, 876; overlay 829)
811 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Reserved for special applications
822 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free (proposed, may not be in use yet)
829 => [ 'country' => 'DO', 'province' => null, 'time_zone' => 'America/Santo_Domingo' ], // Dominican Republic (perm 1/31/05; mand 8/1/05; overlaid on 809)
833 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free (proposed, may not be in use yet)
844 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free (proposed, may not be in use yet)
855 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free (proposed, may not be in use yet)
866 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free
868 => [ 'country' => 'TT', 'province' => null, 'time_zone' => 'America/Port_of_Spain' ], // Trinidad and Tobago ("new" -- see 809)
869 => [ 'country' => 'KN', 'province' => null, 'time_zone' => 'America/St_Kitts' ], // St. Kitts & Nevis
876 => [ 'country' => 'JM', 'province' => null, 'time_zone' => 'America/New_York' ], // Jamaica (split from 809)
658 => [ 'country' => 'JM', 'province' => null, 'time_zone' => 'America/New_York' ], // Jamaica (split from 876)
877 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free
880 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Paid Toll-Free Service
881 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Paid Toll-Free Service
882 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Paid Toll-Free Service
888 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US/Canada toll free
898 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // VoIP service
900 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // US toll calls -- prices vary with the number called
911 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Emergency
976 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Unassigned
999 => [ 'country' => 'US', 'province' => null, 'time_zone' => null ], // Often used by carriers to indicate that the area code information is unavailable for CNID, even though the rest of the number is present
525 => [ 'country' => 'MX', 'province' => null, 'time_zone' => 'America/Mexico_City' ], //-6 Mexico: Mexico City area (country code + city code)
403 => [ 'country' => 'CA', 'province' => 'AB', 'time_zone' => 'America/Edmonton' ], // Canada: Southern Alberta (see 780, 867)
825 => [ 'country' => 'CA', 'province' => 'AB', 'time_zone' => 'America/Edmonton' ], // Canada: Southern Alberta
780 => [ 'country' => 'CA', 'province' => 'AB', 'time_zone' => 'America/Edmonton' ], // Canada: Northern Alberta, north of Lacombe (see 403)
587 => [ 'country' => 'CA', 'province' => 'AB', 'time_zone' => 'America/Edmonton' ], // Canada: Alberta
250 => [ 'country' => 'CA', 'province' => 'BC', 'time_zone' => 'America/Vancouver' ], ///-7 Canada: British Columbia (see 604)
236 => [ 'country' => 'CA', 'province' => 'BC', 'time_zone' => 'America/Vancouver' ], ///-7 Canada: British Columbia (see 604)
672 => [ 'country' => 'CA', 'province' => 'BC', 'time_zone' => 'America/Vancouver' ], ///-7 Canada: British Columbia (see 604)
604 => [ 'country' => 'CA', 'province' => 'BC', 'time_zone' => 'America/Vancouver' ], // Canada: British Columbia: Greater Vancouver (overlay 778, perm 11/3/01; see 250)
778 => [ 'country' => 'CA', 'province' => 'BC', 'time_zone' => 'America/Vancouver' ], // Canada: British Columbia: Greater Vancouver (overlaid on 604, per 11/3/01; see also 250)
204 => [ 'country' => 'CA', 'province' => 'MB', 'time_zone' => 'America/Winnipeg' ], // Canada: Manitoba
431 => [ 'country' => 'CA', 'province' => 'MB', 'time_zone' => 'America/Winnipeg' ], // Canada: Manitoba
506 => [ 'country' => 'CA', 'province' => 'NB', 'time_zone' => 'America/Moncton' ], // Canada: New Brunswick
226 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: SW Ontario: Windsor (overlaid on 519; eff 6/06)
548 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: SW Ontario
289 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- overlaid on 905, eff 6/9/01)
742 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario
416 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario: Toronto (see overlay 647, eff 3/5/01)
519 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: SW Ontario: Windsor (see overlay 226)
613 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: SE Ontario: Ottawa
343 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: SE Ontario
647 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario: Toronto (overlaid on 416; eff 3/5/01)
437 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario
705 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: NE Ontario: Sault Ste. Marie/N Ontario: N Bay, Sudbury
249 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: NE Ontario
807 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => null ], ///-6 Canada: W Ontario: Thunder Bay region to Manitoba border (**NON-SPECIFIC: EST, CST)
905 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- see overlay 289 [eff 6/9/01], splits 416, 647)
365 => [ 'country' => 'CA', 'province' => 'ON', 'time_zone' => 'America/Toronto' ], // Canada: S Cent. Ontario: Greater Toronto Area
418 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], ///-4 Canada: NE Quebec: Quebec
438 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // Canada: SW Quebec: Montreal city (overlaid on 514, [delayed until 6/06] eff 10/10/03, mand 2/7/04)
450 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], ///-4 Canada: Southeastern Quebec; suburbs outside metro Montreal
579 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], ///-4 Canada: Southeastern Quebec;
514 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // Canada: SW Quebec: Montreal city (see overlay 438, eff 10/10/03, mand 2/7/04)
819 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // NW Quebec: Trois Rivieres, Sherbrooke, Outaouais (Gatineau, Hull), and the Laurentians (up to St Jovite / Tremblant) (see 867)
873 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // NW Quebec
581 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // Quebec
367 => [ 'country' => 'CA', 'province' => 'QC', 'time_zone' => 'America/Montreal' ], // Quebec
306 => [ 'country' => 'CA', 'province' => 'SK', 'time_zone' => 'America/Regina' ], ///-7* Canada: Saskatchewan
474 => [ 'country' => 'CA', 'province' => 'SK', 'time_zone' => 'America/Regina' ], ///-7* Canada: Saskatchewan
639 => [ 'country' => 'CA', 'province' => 'SK', 'time_zone' => 'America/Regina' ], ///-7* Canada: Saskatchewan
867 => [ 'country' => 'CA', 'province' => 'YT', 'time_zone' => null ], ///-6/-7/-8 Canada: Yukon, Northwest Territories, Nunavut (split from 403/819) (**NON-SPECIFIC: CST, MST, PST )
709 => [ 'country' => 'CA', 'province' => 'NL', 'time_zone' => null ], ///-3.5 Canada: Newfoundland and Labrador (**NON-SPECIFIC: NST, AST)
902 => [ 'country' => 'CA', 'province' => 'NS', 'time_zone' => 'America/Halifax' ], // Canada: Nova Scotia, Prince Edward Island
782 => [ 'country' => 'CA', 'province' => 'NS', 'time_zone' => 'America/Halifax' ], // Canada: Nova Scotia, Prince Edward Island
907 => [ 'country' => 'US', 'province' => 'AK', 'time_zone' => 'America/Anchorage' ], // Alaska
205 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // Central Alabama (including Birmingham; excludes the southeastern corner of Alabama and the deep south; see splits 256 and 334)
659 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // Central Alabama
251 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // S Alabama: Mobile and coastal areas, Jackson, Evergreen, Monroeville (split from 334, eff 6/18/01; see also 205, 256)
256 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // E and N Alabama (Huntsville, Florence, Gadsden; split from 205; see also 334)
938 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // Alabama
334 => [ 'country' => 'US', 'province' => 'AL', 'time_zone' => 'America/Chicago' ], // S Alabama: Auburn/Opelika, Montgomery and coastal areas (part of what used to be 205; see also 256, split 251)
479 => [ 'country' => 'US', 'province' => 'AR', 'time_zone' => 'America/Chicago' ], // NW Arkansas: Fort Smith, Fayetteville, Springdale, Bentonville (SPLIt from 501, perm 1/19/02, mand 7/20/02)
501 => [ 'country' => 'US', 'province' => 'AR', 'time_zone' => 'America/Chicago' ], // Central Arkansas: Little Rock, Hot Springs, Conway (see split 479)
870 => [ 'country' => 'US', 'province' => 'AR', 'time_zone' => 'America/Chicago' ], // Arkansas: areas outside of west/central AR: Jonesboro, etc
480 => [ 'country' => 'US', 'province' => 'AZ', 'time_zone' => 'America/Phoenix' ], //* Arizona: East Phoenix (see 520; also Phoenix split 602, 623)
520 => [ 'country' => 'US', 'province' => 'AZ', 'time_zone' => 'America/Phoenix' ], //* SE Arizona: Tucson area (split from 602; see split 928)
602 => [ 'country' => 'US', 'province' => 'AZ', 'time_zone' => 'America/Phoenix' ], //* Arizona: Phoenix (see 520; also Phoenix split 480, 623)
623 => [ 'country' => 'US', 'province' => 'AZ', 'time_zone' => 'America/Phoenix' ], //* Arizona: West Phoenix (see 520; also Phoenix split 480, 602)
928 => [ 'country' => 'US', 'province' => 'AZ', 'time_zone' => 'America/Phoenix' ], //* Central and Northern Arizona: Prescott, Flagstaff, Yuma (split from 520)
209 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Cent. California: Stockton (see split 559)
213 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Los Angeles (see 310, 323, 626, 818)
310 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Beverly Hills, West Hollywood, West Los Angeles (see split 562; overlay 424)
323 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Los Angeles (outside downtown: Hollywood; split from 213)
341 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // (overlay on 510; SUSPENDED)
369 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Solano County (perm 12/2/00, mand 6/2/01)
408 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Cent. Coastal California: San Jose (see overlay 669)
415 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: San Francisco County and Marin County on the north side of the Golden Gate Bridge, extending north to Sonoma County (see 650)
424 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Los Angeles (see split 562; overlaid on 310 mand 7/26/06)
442 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Far north suburbs of San Diego (Oceanside, Escondido, SUSPENDED -- originally perm 10/21/00, mand 4/14/01)
510 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: Oakland, East Bay (see 925)
530 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // NE California: Eldorado County area, excluding Eldorado Hills itself: incl cities of Auburn, Chico, Redding, So. Lake Tahoe, Marysville, Nevada City/Grass Valley (split from 916)
559 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Central California: Fresno (split from 209)
562 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: Long Beach (split from 310 Los Angeles)
619 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: San Diego (see split 760; overlay 858, 935)
626 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // E S California: Pasadena (split from 818 Los Angeles)
627 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // No longer in use [was Napa, Sonoma counties (perm 10/13/01, mand 4/13/02); now 707]
628 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // (Region unknown; perm 10/21/00)
650 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: Peninsula south of San Francisco -- San Mateo County, parts of Santa Clara County (split from 415)
661 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: N Los Angeles, Mckittrick, Mojave, Newhall, Oildale, Palmdale, Taft, Tehachapi, Bakersfield, Earlimart, Lancaster (split from 805)
669 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // Cent. Coastal California: San Jose (rejected was: overlaid on 408)
707 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // NW California: Santa Rosa, Napa, Vallejo, American Canyon, Fairfield
714 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // North and Central Orange County (see split 949)
747 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Los Angeles, Agoura Hills, Calabasas, Hidden Hills, and Westlake Village (see 818; implementation suspended)
760 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: San Diego North County to Sierra Nevada (split from 619)
764 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // (overlay on 650; SUSPENDED)
805 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S Cent. and Cent. Coastal California: Ventura County, Santa Barbara County: San Luis Obispo, Thousand Oaks, Carpinteria, Santa Barbara, Santa Maria, Lompoc, Santa Ynez Valley / Solvang (see 661 split)
820 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S Cent. and Cent. Coastal California
818 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: Los Angeles: San Fernando Valley (see 213, 310, 562, 626, 747)
831 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: central coast area from Santa Cruz through Monterey County
858 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: San Diego (see split 760; overlay 619, 935)
909 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: Inland empire: San Bernardino (see split 951), Riverside
840 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California
916 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // NE California: Sacramento, Walnut Grove, Lincoln, Newcastle and El Dorado Hills (split to 530)
279 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // NE California
925 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: Contra Costa area: Antioch, Concord, Pleasanton, Walnut Creek (split from 510)
935 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // S California: San Diego (see split 760; overlay 858, 619; assigned but not in use)
949 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: S Coastal Orange County (split from 714)
951 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California: W Riverside County (split from 909; eff 7/17/04)
657 => [ 'country' => 'US', 'province' => 'CA', 'time_zone' => 'America/Los_Angeles' ], // California
303 => [ 'country' => 'US', 'province' => 'CO', 'time_zone' => 'America/Denver' ], // Central Colorado: Denver (see 970, also 720 overlay)
719 => [ 'country' => 'US', 'province' => 'CO', 'time_zone' => 'America/Denver' ], // SE Colorado: Pueblo, Colorado Springs
720 => [ 'country' => 'US', 'province' => 'CO', 'time_zone' => 'America/Denver' ], // Central Colorado: Denver (overlaid on 303)
970 => [ 'country' => 'US', 'province' => 'CO', 'time_zone' => 'America/Denver' ], // N and W Colorado (part of what used to be 303)
203 => [ 'country' => 'US', 'province' => 'CT', 'time_zone' => 'America/New_York' ], // Connecticut: Fairfield County and New Haven County; Bridgeport, New Haven (see 860)
475 => [ 'country' => 'US', 'province' => 'CT', 'time_zone' => 'America/New_York' ], // Connecticut: New Haven, Greenwich, southwestern (postponed; was perm 1/6/01; mand 3/1/01???)
860 => [ 'country' => 'US', 'province' => 'CT', 'time_zone' => 'America/New_York' ], // Connecticut: areas outside of Fairfield and New Haven Counties (split from 203, overlay 959)
959 => [ 'country' => 'US', 'province' => 'CT', 'time_zone' => 'America/New_York' ], // Connecticut: Hartford, New London (postponed; was overlaid on 860 perm 1/6/01; mand 3/1/01???)
202 => [ 'country' => 'US', 'province' => 'DC', 'time_zone' => 'America/New_York' ], // Washington, D.C.
302 => [ 'country' => 'US', 'province' => 'DE', 'time_zone' => 'America/New_York' ], // Delaware
239 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida (Lee, Collier, and Monroe Counties, excl the Keys; see 305; eff 3/11/02; mand 3/11/03)
305 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // SE Florida: Miami, the Keys (see 786, 954; 239)
321 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Brevard County, Cape Canaveral area; Metro Orlando (split from 407)
352 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Gainesville area, Ocala, Crystal River (split from 904)
386 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // N central Florida: Lake City (split from 904, perm 2/15/01, mand 11/5/01)
407 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Central Florida: Metro Orlando (see overlay 689, eff 7/02; split 321)
561 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // S. Central Florida: Palm Beach County (West Palm Beach, Boca Raton, Vero Beach; see split 772, eff 2/11/02; mand 11/11/02)
689 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Central Florida: Metro Orlando (see overlay 321; overlaid on 407, assigned but not in use)
727 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida Tampa Metro: Saint Petersburg, Clearwater (Pinellas and parts of Pasco County; split from 813)
754 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Broward County area, incl Ft. Lauderdale (overlaid on 954; perm 8/1/01, mand 9/1/01)
772 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // S. Central Florida: St. Lucie, Martin, and Indian River counties (split from 561; eff 2/11/02; mand 11/11/02)
786 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // SE Florida, Monroe County (Miami; overlaid on 305)
813 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // SW Florida: Tampa Metro (splits 727 St. Petersburg, Clearwater, and 941 Sarasota)
850 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => null ], ///-5 Florida panhandle, from east of Tallahassee to Pensacola (split from 904); western panhandle (Pensacola, Panama City) are UTC-6 (**NON-SPECIFIC: EST, CST)
448 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => null ], ///-5 Florida panhandle, from east of Tallahassee to Pensacola (split from 904); western panhandle (Pensacola, Panama City) are UTC-6 (**NON-SPECIFIC: EST, CST)
863 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Lakeland, Polk County (split from 941)
904 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // N Florida: Jacksonville (see splits 352, 386, 850)
927 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Cellular coverage in Orlando area
941 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // SW Florida: Sarasota and Manatee counties (part of what used to be 813; see split 863)
954 => [ 'country' => 'US', 'province' => 'FL', 'time_zone' => 'America/New_York' ], // Florida: Broward County area, incl Ft. Lauderdale (part of what used to be 305, see overlay 754)
229 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // SW Georgia: Albany (split from 912; see also 478; perm 8/1/00)
404 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // N Georgia: Atlanta and suburbs (see overlay 678, split 770)
470 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // Georgia: Greater Atlanta Metropolitan Area (overlaid on 404/770/678; mand 9/2/01)
478 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // Central Georgia: Macon (split from 912; see also 229; perm 8/1/00; mand 8/1/01)
678 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // N Georgia: metropolitan Atlanta (overlay; see 404, 770)
706 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // N Georgia: Columbus, Augusta (see overlay 762)
762 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // N Georgia: Columbus, Augusta (overlaid on 706)
770 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // Georgia: Atlanta suburbs: outside of I-285 ring road (part of what used to be 404; see also overlay 678)
912 => [ 'country' => 'US', 'province' => 'GA', 'time_zone' => 'America/New_York' ], // SE Georgia: Savannah (see splits 229, 478)
671 => [ 'country' => 'US', 'province' => 'GU', 'time_zone' => 'Pacific/Guam' ], //0* Guam
808 => [ 'country' => 'US', 'province' => 'HI', 'time_zone' => 'Pacific/Honolulu' ], //0* Hawaii
319 => [ 'country' => 'US', 'province' => 'IA', 'time_zone' => 'America/Chicago' ], // E Iowa: Cedar Rapids (see split 563)
515 => [ 'country' => 'US', 'province' => 'IA', 'time_zone' => 'America/Chicago' ], // Cent. Iowa: Des Moines (see split 641)
563 => [ 'country' => 'US', 'province' => 'IA', 'time_zone' => 'America/Chicago' ], // E Iowa: Davenport, Dubuque (split from 319, eff 3/25/01)
641 => [ 'country' => 'US', 'province' => 'IA', 'time_zone' => 'America/Chicago' ], // Iowa: Mason City, Marshalltown, Creston, Ottumwa (split from 515; perm 7/9/00)
712 => [ 'country' => 'US', 'province' => 'IA', 'time_zone' => 'America/Chicago' ], // W Iowa: Council Bluffs
208 => [ 'country' => 'US', 'province' => 'ID', 'time_zone' => null ], ///-8 Idaho (**NON-SPECIFIC: America/Denver, America/Los_Angeles)
986 => [ 'country' => 'US', 'province' => 'ID', 'time_zone' => 'America/Los_Angeles' ], ///-8 Idaho (**NON-SPECIFIC: America/Denver, America/Los_Angeles)
217 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Cent. Illinois: Springfield
447 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Cent. Illinois
224 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Northern NE Illinois: Evanston, Waukegan, Northbrook (overlay on 847, eff 1/5/02)
309 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // W Cent. Illinois: Peoria
312 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Illinois: Chicago (downtown only -- in the loop; see 773; overlay 872)
331 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // W NE Illinois, western suburbs of Chicago (part of what used to be 708; overlaid on 630; eff 7/07)
464 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Illinois: south suburbs of Chicago (see 630; overlaid on 708)
618 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // S Illinois: Centralia
630 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // W NE Illinois, western suburbs of Chicago (part of what used to be 708; overlay 331)
708 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Illinois: southern and western suburbs of Chicago (see 630; overlay 464)
773 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Illinois: city of Chicago, outside the loop (see 312; overlay 872)
779 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // NW Illinois: Rockford, Kankakee (overlaid on 815; eff 8/19/06, mand 2/17/07)
815 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // NW Illinois: Rockford, Kankakee (see overlay 779; eff 8/19/06, mand 2/17/07)
847 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Northern NE Illinois: northwestern suburbs of chicago (Evanston, Waukegan, Northbrook; see overlay 224)
872 => [ 'country' => 'US', 'province' => 'IL', 'time_zone' => 'America/Chicago' ], // Illinois: Chicago (downtown only -- in the loop; see 773; overlaid on 312 and 773)
219 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => null ], ///-5 NW Indiana: Gary (see split 574, 260) (**NON-SPECIFIC: EST, CST)
260 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => 'America/New_York' ], // NE Indiana: Fort Wayne (see 219)
317 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => 'America/New_York' ], // Cent. Indiana: Indianapolis (see 765)
463 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => 'America/New_York' ], // Cent. Indiana
574 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => null ], // N Indiana: Elkhart, South Bend (split from 219) (**NON-SPECIFIC: EST, CST)
765 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => 'America/New_York' ], // Indiana: outside Indianapolis (split from 317)
812 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => null ], ///-5 S Indiana: Evansville, Cincinnati outskirts in IN, Columbus, Bloomington (mostly GMT-5) (**NON-SPECIFIC: EST, CST)
930 => [ 'country' => 'US', 'province' => 'IN', 'time_zone' => 'America/New_York' ], ///-5 S Indiana
316 => [ 'country' => 'US', 'province' => 'KS', 'time_zone' => 'America/Chicago' ], // S Kansas: Wichita (see split 620)
620 => [ 'country' => 'US', 'province' => 'KS', 'time_zone' => null ], // S Kansas: Wichita (split from 316; perm 2/3/01) (**NON-SPECIFIC: CST, MST)
785 => [ 'country' => 'US', 'province' => 'KS', 'time_zone' => null ], // N & W Kansas: Topeka (split from 913) (**NON-SPECIFIC: CST, MST)
913 => [ 'country' => 'US', 'province' => 'KS', 'time_zone' => 'America/Chicago' ], // Kansas: Kansas City area (see 785)
270 => [ 'country' => 'US', 'province' => 'KY', 'time_zone' => null ], // W Kentucky: Bowling Green, Paducah (split from 502) (**NON-SPECIFIC: EST, CST)
502 => [ 'country' => 'US', 'province' => 'KY', 'time_zone' => 'America/New_York' ], // N Central Kentucky: Louisville (see 270)
606 => [ 'country' => 'US', 'province' => 'KY', 'time_zone' => null ], ///-6 E Kentucky: area east of Frankfort: Ashland (see 859) (**NON-SPECIFIC: EST, CST)
859 => [ 'country' => 'US', 'province' => 'KY', 'time_zone' => 'America/New_York' ], // N and Central Kentucky: Lexington; suburban KY counties of Cincinnati OH metro area; Covington, Newport, Ft. Thomas, Ft. Wright, Florence (split from 606)
364 => [ 'country' => 'US', 'province' => 'KY', 'time_zone' => null ], // (**NON-SPECIFIC: EST, CST)
225 => [ 'country' => 'US', 'province' => 'LA', 'time_zone' => 'America/Chicago' ], // Louisiana: Baton Rouge, New Roads, Donaldsonville, Albany, Gonzales, Greensburg, Plaquemine, Vacherie (split from 504)
318 => [ 'country' => 'US', 'province' => 'LA', 'time_zone' => 'America/Chicago' ], // N Louisiana: Shreveport, Ruston, Monroe, Alexandria (see split 337)
337 => [ 'country' => 'US', 'province' => 'LA', 'time_zone' => 'America/Chicago' ], // SW Louisiana: Lake Charles, Lafayette (see split 318)
504 => [ 'country' => 'US', 'province' => 'LA', 'time_zone' => 'America/Chicago' ], // E Louisiana: New Orleans metro area (see splits 225, 985)
985 => [ 'country' => 'US', 'province' => 'LA', 'time_zone' => 'America/Chicago' ], // E Louisiana: SE/N shore of Lake Pontchartrain: Hammond, Slidell, Covington, Amite, Kentwood, area SW of New Orleans, Houma, Thibodaux, Morgan City (split from 504; perm 2/12/01; mand 10/22/01)
339 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: Boston suburbs, to the south and west (see splits 617, 508; overlaid on 781, eff 5/2/01)
351 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: north of Boston to NH, 508, and 781 (overlaid on 978, eff 4/2/01)
413 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // W Massachusetts: Springfield
508 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Cent. Massachusetts: Framingham; Cape Cod (see split 978, overlay 774)
617 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: greater Boston (see overlay 857)
774 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Cent. Massachusetts: Framingham; Cape Cod (see split 978, overlaid on 508, eff 4/2/01)
781 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: Boston surburbs, to the north and west (see splits 617, 508; overlay 339)
857 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: greater Boston (overlaid on 617, eff 4/2/01)
978 => [ 'country' => 'US', 'province' => 'MA', 'time_zone' => 'America/New_York' ], // Massachusetts: north of Boston to NH (see split 978 -- this is the northern half of old 508; see overlay 351)
240 => [ 'country' => 'US', 'province' => 'MD', 'time_zone' => 'America/New_York' ], // W Maryland: Silver Spring, Frederick, Gaithersburg (overlay, see 301)
301 => [ 'country' => 'US', 'province' => 'MD', 'time_zone' => 'America/New_York' ], // W Maryland: Silver Spring, Frederick, Camp Springs, Prince George's County (see 240)
410 => [ 'country' => 'US', 'province' => 'MD', 'time_zone' => 'America/New_York' ], // E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (see 443)
443 => [ 'country' => 'US', 'province' => 'MD', 'time_zone' => 'America/New_York' ], // E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (overlaid on 410)
207 => [ 'country' => 'US', 'province' => 'ME', 'time_zone' => 'America/New_York' ], // Maine
231 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // W Michigan: Northwestern portion of lower Peninsula; Traverse City, Muskegon, Cheboygan, Alanson
248 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Michigan: Oakland County, Pontiac (split from 810; see overlay 947)
269 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // SW Michigan: Kalamazoo, Saugatuck, Hastings, Battle Creek, Sturgis to Lake Michigan (split from 616)
278 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Michigan (overlaid on 734, SUSPENDED)
313 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Michigan: Detroit and suburbs (see 734, overlay 679)
517 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Cent. Michigan: Lansing (see split 989)
586 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Michigan: Macomb County (split from 810; perm 9/22/01, mand 3/23/02)
616 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // W Michigan: Holland, Grand Haven, Greenville, Grand Rapids, Ionia (see split 269)
679 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], ///-6 Michigan: Dearborn area (overlaid on 313; assigned but not in use)
734 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // SE Michigan: west and south of Detroit -- Ann Arbor, Monroe (split from 313)
810 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // E Michigan: Flint, Pontiac (see 248; split 586)
906 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => null ], ///-5 Upper Peninsula Michigan: Sault Ste. Marie, Escanaba, Marquette (UTC-6 towards the WI border) (**NON-SPECIFIC: EST, CST)
947 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], ///-6 Michigan: Oakland County (overlays 248, perm 5/5/01)
989 => [ 'country' => 'US', 'province' => 'MI', 'time_zone' => 'America/New_York' ], // Upper central Michigan: Mt Pleasant, Saginaw (split from 517; perm 4/7/01)
218 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // N Minnesota: Duluth
320 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // Cent. Minnesota: Saint Cloud (rural Minn, excl St. Paul/Minneapolis)
507 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // S Minnesota: Rochester, Mankato, Worthington
612 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // Cent. Minnesota: Minneapolis (split from St. Paul, see 651; see splits 763, 952)
651 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // Cent. Minnesota: St. Paul (split from Minneapolis, see 612)
763 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // Minnesota: Minneapolis NW (split from 612; see also 952)
952 => [ 'country' => 'US', 'province' => 'MN', 'time_zone' => 'America/Chicago' ], // Minnesota: Minneapolis SW, Bloomington (split from 612; see also 763)
314 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // SE Missouri: St Louis city and parts of the metro area only (see 573, 636, overlay 557)
417 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // SW Missouri: Springfield
557 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // SE Missouri: St Louis metro area only (cancelled: overlaid on 314)
573 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // SE Missouri: excluding St Louis metro area, includes Central/East Missouri, area between St. Louis and Kansas City
636 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // Missouri: W St. Louis metro area of St. Louis county, St. Charles County, Jefferson County area south (between 314 and 573)
660 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // N Missouri (split from 816)
816 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // N Missouri: Kansas City (see split 660, overlay 975)
975 => [ 'country' => 'US', 'province' => 'MO', 'time_zone' => 'America/Chicago' ], // N Missouri: Kansas City (overlaid on 816)
670 => [ 'country' => 'US', 'province' => 'MP', 'time_zone' => null ], //0* Commonwealth of the Northern Mariana Islands (CNMI, US Commonwealth)
228 => [ 'country' => 'US', 'province' => 'MS', 'time_zone' => 'America/Chicago' ], // S Mississippi (coastal areas, Biloxi, Gulfport; split from 601)
601 => [ 'country' => 'US', 'province' => 'MS', 'time_zone' => 'America/Chicago' ], // Mississippi: Meridian, Jackson area (see splits 228, 662; overlay 769)
662 => [ 'country' => 'US', 'province' => 'MS', 'time_zone' => 'America/Chicago' ], // N Mississippi: Tupelo, Grenada (split from 601)
769 => [ 'country' => 'US', 'province' => 'MS', 'time_zone' => 'America/Chicago' ], // Mississippi: Meridian, Jackson area (overlaid on 601; perm 7/19/04, mand 3/14/05)
406 => [ 'country' => 'US', 'province' => 'MT', 'time_zone' => 'America/Denver' ], // Montana
252 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // E North Carolina (Rocky Mount; split from 919)
336 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // Cent. North Carolina: Greensboro, Winston-Salem, High Point (split from 910)
743 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // Cent. North Carolina
704 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // W North Carolina: Charlotte (see split 828, overlay 980)
828 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // W North Carolina: Asheville (split from 704)
910 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // S Cent. North Carolina: Fayetteville, Wilmington (see 336)
919 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // E North Carolina: Raleigh (see split 252, overlay 984)
980 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // North Carolina: (overlay on 704; perm 5/1/00, mand 3/15/01)
984 => [ 'country' => 'US', 'province' => 'NC', 'time_zone' => 'America/New_York' ], // E North Carolina: Raleigh (overlaid on 919, perm 8/1/01, mand 2/5/02 POSTPONED)
701 => [ 'country' => 'US', 'province' => 'ND', 'time_zone' => null ], // North Dakota (**NON-SPECIFIC: CST, MST)
308 => [ 'country' => 'US', 'province' => 'NE', 'time_zone' => null ], // -7 W Nebraska: North Platte (**NON-SPECIFIC: America/Chicago, America/Denver)
402 => [ 'country' => 'US', 'province' => 'NE', 'time_zone' => 'America/Chicago' ], // E Nebraska: Omaha, Lincoln
531 => [ 'country' => 'US', 'province' => 'NE', 'time_zone' => 'America/Chicago' ], // E Nebraska: Omaha, Lincoln (Similar to 402 Area Code)
603 => [ 'country' => 'US', 'province' => 'NH', 'time_zone' => 'America/New_York' ], // New Hampshire
201 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // N New Jersey: Jersey City, Hackensack (see split 973, overlay 551)
551 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // N New Jersey: Jersey City, Hackensack (overlaid on 201)
609 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // S New Jersey: Trenton (see 856)
640 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // S New Jersey
732 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // Cent. New Jersey: Toms River, New Brunswick, Bound Brook (see overlay 848)
848 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // Cent. New Jersey: Toms River, New Brunswick, Bound Brook (see overlay 732)
856 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // SW New Jersey: greater Camden area, Mt Laurel (split from 609)
862 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // N New Jersey: Newark Paterson Morristown (overlaid on 973)
908 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // Cent. New Jersey: Elizabeth, Basking Ridge, Somerville, Bridgewater, Bound Brook
973 => [ 'country' => 'US', 'province' => 'NJ', 'time_zone' => 'America/New_York' ], // N New Jersey: Newark, Paterson, Morristown (see overlay 862; split from 201)
505 => [ 'country' => 'US', 'province' => 'NM', 'time_zone' => 'America/Denver' ], // North central and northwestern New Mexico (Albuquerque, Santa Fe, Los Alamos; see split 575, eff 10/07/07)
575 => [ 'country' => 'US', 'province' => 'NM', 'time_zone' => 'America/Denver' ], // New Mexico (Las Cruces, Alamogordo, Roswell; split from 505, eff 10/07/07)
957 => [ 'country' => 'US', 'province' => 'NM', 'time_zone' => 'America/Denver' ], // New Mexico (pending; region unknown)
702 => [ 'country' => 'US', 'province' => 'NV', 'time_zone' => 'America/Los_Angeles' ], // S. Nevada: Clark County, incl Las Vegas (see 775)
725 => [ 'country' => 'US', 'province' => 'NV', 'time_zone' => 'America/Los_Angeles' ], // S. Nevada
775 => [ 'country' => 'US', 'province' => 'NV', 'time_zone' => 'America/Los_Angeles' ], // N. Nevada: Reno (all of NV except Clark County area; see 702)
212 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York City, New York (Manhattan; see 646, 718)
332 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York City, New York
315 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // N Cent. New York: Syracuse
680 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // N Cent. New York
347 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York (overlay for 718: NYC area, except Manhattan)
929 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York
516 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York: Nassau County, Long Island; Hempstead (see split 631)
518 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // NE New York: Albany
838 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // NE New York
585 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // NW New York: Rochester (split from 716)
607 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // S Cent. New York: Ithaca, Binghamton; Catskills
631 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York: Suffolk County, Long Island; Huntington, Riverhead (split 516)
934 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York
646 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York (overlay 212/917) NYC: Manhattan only
716 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // NW New York: Buffalo (see split 585)
718 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York City, New York (Queens, Staten Island, The Bronx, and Brooklyn; see 212, 347)
845 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York: Poughkeepsie; Nyack, Nanuet, Valley Cottage, New City, Putnam, Dutchess, Rockland, Orange, Ulster and parts of Sullivan counties in New York's lower Hudson Valley and Delaware County in the Catskills (see 914; perm 6/5/00)
914 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // S New York: Westchester County (see 845)
917 => [ 'country' => 'US', 'province' => 'NY', 'time_zone' => 'America/New_York' ], // New York: New York City (cellular, see 646)
216 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // Cleveland (see splits 330, 440)
234 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // NE Ohio: Canton, Akron (overlaid on 330; perm 10/30/00)
283 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SW Ohio: Cincinnati (cancelled: overlaid on 513)
330 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // NE Ohio: Akron, Canton, Youngstown; Mahoning County, parts of Trumbull/Warren counties (see splits 216, 440, overlay 234)
380 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // Ohio: Columbus (overlaid on 614; assigned but not in use)
419 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // NW Ohio: Toledo (see overlay 567, perm 1/1/02)
440 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // Ohio: Cleveland metro area, excluding Cleveland (split from 216, see also 330)
513 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SW Ohio: Cincinnati (see split 937; overlay 283 cancelled)
567 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // NW Ohio: Toledo (overlaid on 419, perm 1/1/02)
614 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SE Ohio: Columbus (see overlay 380)
740 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SE Ohio (rural areas outside Columbus; split from 614)
220 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SE Ohio
937 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SW Ohio: Dayton (part of what used to be 513)
326 => [ 'country' => 'US', 'province' => 'OH', 'time_zone' => 'America/New_York' ], // SW Ohio
405 => [ 'country' => 'US', 'province' => 'OK', 'time_zone' => 'America/Chicago' ], // W Oklahoma: Oklahoma City (see 580)
572 => [ 'country' => 'US', 'province' => 'OK', 'time_zone' => 'America/Chicago' ], // W Oklahoma
580 => [ 'country' => 'US', 'province' => 'OK', 'time_zone' => 'America/Chicago' ], // W Oklahoma (rural areas outside Oklahoma City; split from 405)
918 => [ 'country' => 'US', 'province' => 'OK', 'time_zone' => 'America/Chicago' ], // E Oklahoma: Tulsa
539 => [ 'country' => 'US', 'province' => 'OK', 'time_zone' => 'America/Chicago' ], // E Oklahoma:
503 => [ 'country' => 'US', 'province' => 'OR', 'time_zone' => 'America/Los_Angeles' ], // Oregon (see 541, 971)
541 => [ 'country' => 'US', 'province' => 'OR', 'time_zone' => null ], ///-7 Oregon: Eugene, Medford (split from 503; 503 retains NW part [Portland/Salem], all else moves to 541; eastern oregon is UTC-7) (**NON-SPECIFIC: MST, PST)
971 => [ 'country' => 'US', 'province' => 'OR', 'time_zone' => 'America/Los_Angeles' ], // Oregon: Metropolitan Portland, Salem/Keizer area, incl Cricket Wireless (see 503; perm 10/1/00)
458 => [ 'country' => 'US', 'province' => 'OR', 'time_zone' => null ], // Oregon: (**NON-SPECIFIC: MST, PST)
215 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania: Philadelphia (see overlays 267)
267 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania: Philadelphia (see 215)
445 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania
412 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // W Pennsylvania: Pittsburgh (see split 724, overlay 878)
484 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown (see 610)
570 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // NE and N Central Pennsylvania: Wilkes-Barre, Scranton (see 717)
223 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // NE and N Central Pennsylvania
272 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // NE and N Central Pennsylvania
610 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown (see overlays 484, 835)
717 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // E Pennsylvania: Harrisburg (see split 570)
724 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SW Pennsylvania (areas outside metro Pittsburgh; split from 412)
814 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // Cent. Pennsylvania: Erie
582 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // Cent. Pennsylvania
835 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown (overlaid on 610, eff 5/1/01; see also 484)
878 => [ 'country' => 'US', 'province' => 'PA', 'time_zone' => 'America/New_York' ], // Pittsburgh, New Castle (overlaid on 412, perm 8/17/01, mand t.b.a.)
787 => [ 'country' => 'US', 'province' => 'PR', 'time_zone' => 'America/Puerto_Rico' ], //* Puerto Rico (see overlay 939, perm 8/1/01)
939 => [ 'country' => 'US', 'province' => 'PR', 'time_zone' => 'America/Puerto_Rico' ], //* Puerto Rico (overlaid on 787, perm 8/1/01)
401 => [ 'country' => 'US', 'province' => 'RI', 'time_zone' => 'America/New_York' ], // Rhode Island
803 => [ 'country' => 'US', 'province' => 'SC', 'time_zone' => 'America/New_York' ], // South Carolina: Columbia, Aiken, Sumter (see 843, 864)
839 => [ 'country' => 'US', 'province' => 'SC', 'time_zone' => 'America/New_York' ], // South Carolina
843 => [ 'country' => 'US', 'province' => 'SC', 'time_zone' => 'America/New_York' ], // South Carolina, coastal area: Charleston, Beaufort, Myrtle Beach (split from 803)
854 => [ 'country' => 'US', 'province' => 'SC', 'time_zone' => 'America/New_York' ], // South Carolina
864 => [ 'country' => 'US', 'province' => 'SC', 'time_zone' => 'America/New_York' ], // South Carolina, upstate area: Greenville, Spartanburg (split from 803)
605 => [ 'country' => 'US', 'province' => 'SD', 'time_zone' => null ], ///-7 South Dakota (**NON-SPECIFIC: CST, MST)
423 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => null ], // E Tennessee, except Knoxville metro area: Chattanooga, Bristol, Johnson City, Kingsport, Greeneville (see split 865; part of what used to be 615) (**NON-SPECIFIC: EST, CST)
615 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => 'America/Chicago' ], // Northern Middle Tennessee: Nashville metro area (see 423, 931)
629 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => 'America/Chicago' ], // Northern Middle Tennessee
731 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => 'America/Chicago' ], // W Tennessee: outside Memphis metro area (split from 901, perm 2/12/01, mand 9/17/01)
865 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => 'America/New_York' ], // E Tennessee: Knoxville, Knox and adjacent counties (split from 423; part of what used to be 615)
901 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => 'America/Chicago' ], // W Tennessee: Memphis metro area (see 615, 931, split 731)
931 => [ 'country' => 'US', 'province' => 'TN', 'time_zone' => null ], // Middle Tennessee: semi-circular ring around Nashville (split from 615) (**NON-SPECIFIC: EST, CST)
210 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // S Texas: San Antonio (see also splits 830, 956)
726 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // S Texas
214 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Dallas Metro (overlays 469/972)
945 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas
254 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Central Texas (Waco, Stephenville; split, see 817, 940)
281 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Houston Metro (split 713; overlay 832)
325 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Central Texas: Abilene, Sweetwater, Snyder, San Angelo (split from 915)
361 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // S Texas: Corpus Christi (split from 512; eff 2/13/99)
409 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // SE Texas: Galveston, Port Arthur, Beaumont (splits 936, 979)
430 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // NE Texas: Tyler (overlaid on 903, eff 7/20/02)
432 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Denver' ], ///-6 W Texas: Big Spring, Midland, Odessa (split from 915, eff 4/5/03)
469 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Dallas Metro (overlays 214/972)
512 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // S Texas: Austin (see split 361; overlay 737, perm 11/10/01)
682 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Fort Worth areas (perm 10/7/00, mand 12/9/00)
713 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Mid SE Texas: central Houston (split, 281; overlay 832)
737 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // S Texas: Austin (overlaid on 512, suspended; see also 361)
806 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Panhandle Texas: Amarillo, Lubbock
817 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // N Cent. Texas: Fort Worth area (see 254, 940)
830 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: region surrounding San Antonio (split from 210)
832 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Houston (overlay 713/281)
346 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Houston
903 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // NE Texas: Tyler (see overlay 430, eff 7/20/02)
915 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => null ], ///-6 W Texas: El Paso (see splits 325 eff 4/5/03; 432, eff 4/5/03) (**NON-SPECIFIC: CST, MST)
936 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // SE Texas: Conroe, Lufkin, Nacogdoches, Crockett (split from 409, see also 979)
940 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // N Cent. Texas: Denton, Wichita Falls (split from 254, 817)
956 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Valley of Texas area; Harlingen, Laredo (split from 210)
972 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // Texas: Dallas Metro (overlays 214/469)
979 => [ 'country' => 'US', 'province' => 'TX', 'time_zone' => 'America/Chicago' ], // SE Texas: Bryan, College Station, Bay City (split from 409, see also 936)
385 => [ 'country' => 'US', 'province' => 'UT', 'time_zone' => 'America/Denver' ], // Utah: Salt Lake City Metro (split from 801, eff 3/30/02 POSTPONED; see also 435)
435 => [ 'country' => 'US', 'province' => 'UT', 'time_zone' => 'America/Denver' ], // Rural Utah outside Salt Lake City metro (see split 801)
801 => [ 'country' => 'US', 'province' => 'UT', 'time_zone' => 'America/Denver' ], // Utah: Salt Lake City Metro (see split 385, eff 3/30/02; see also split 435)
276 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // S and SW Virginia: Bristol, Stuart, Martinsville (split from 540; perm 9/1/01, mand 3/16/02)
434 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // E Virginia: Charlottesville, Lynchburg, Danville, South Boston, and Emporia (split from 804, eff 6/1/01; see also 757)
540 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // Western and Southwest Virginia: Shenandoah and Roanoke valleys: Fredericksburg, Harrisonburg, Roanoke, Salem, Lexington and nearby areas (see split 276; split from 703)
571 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // Northern Virginia: Arlington, McLean, Tysons Corner (to be overlaid on 703 3/1/00; see earlier split 540)
703 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // Northern Virginia: Arlington, McLean, Tysons Corner (see split 540; overlay 571)
757 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // E Virginia: Tidewater / Hampton Roads area -- Norfolk, Virginia Beach, Chesapeake, Portsmouth, Hampton, Newport News, Suffolk (part of what used to be 804)
804 => [ 'country' => 'US', 'province' => 'VA', 'time_zone' => 'America/New_York' ], // E Virginia: Richmond (see splits 757, 434)
340 => [ 'country' => 'US', 'province' => 'VI', 'time_zone' => 'America/St_Thomas' ], //* US Virgin Islands (see also 809)
802 => [ 'country' => 'US', 'province' => 'VT', 'time_zone' => 'America/New_York' ], // Vermont
206 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // W Washington state: Seattle and Bainbridge Island (see splits 253, 360, 425; overlay 564)
253 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // Washington: South Tier - Tacoma, Federal Way (split from 206, see also 425; overlay 564)
360 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // W Washington State: Olympia, Bellingham (area circling 206, 253, and 425; split from 206; see overlay 564)
425 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // Washington: North Tier - Everett, Bellevue (split from 206, see also 253; overlay 564)
509 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // E and Central Washington state: Spokane, Yakima, Walla Walla, Ellensburg
564 => [ 'country' => 'US', 'province' => 'WA', 'time_zone' => 'America/Los_Angeles' ], // W Washington State: Olympia, Bellingham (overlaid on 360; see also 206, 253, 425; assigned but not in use)
262 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // SE Wisconsin: counties of Kenosha, Ozaukee, Racine, Walworth, Washington, Waukesha (split from 414)
414 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // SE Wisconsin: Milwaukee County (see splits 920, 262)
608 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // SW Wisconsin: Madison
715 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // N Wisconsin: Eau Claire, Wausau, Superior
534 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // Wisconsin
920 => [ 'country' => 'US', 'province' => 'WI', 'time_zone' => 'America/Chicago' ], // NE Wisconsin: Appleton, Green Bay, Sheboygan, Fond du Lac (from Beaver Dam NE to Oshkosh, Appleton, and Door County; part of what used to be 414)
304 => [ 'country' => 'US', 'province' => 'WV', 'time_zone' => 'America/New_York' ], // West Virginia
681 => [ 'country' => 'US', 'province' => 'WV', 'time_zone' => 'America/New_York' ], // West Virginia
307 => [ 'country' => 'US', 'province' => 'WY', 'time_zone' => 'America/Denver' ], // Wyoming
];
break;
case 'timesheet_view':
$retval = [
10 => TTi18n::gettext( 'Calendar' ),
20 => TTi18n::gettext( 'List' ),
];
break;
case 'start_week_day':
$retval = [
0 => TTi18n::gettext( 'Sunday' ),
1 => TTi18n::gettext( 'Monday' ),
2 => TTi18n::gettext( 'Tuesday' ),
3 => TTi18n::gettext( 'Wednesday' ),
4 => TTi18n::gettext( 'Thursday' ),
5 => TTi18n::gettext( 'Friday' ),
6 => TTi18n::gettext( 'Saturday' ),
];
break;
case 'schedule_icalendar_type':
$retval = [
0 => TTi18n::gettext( 'Disabled' ),
1 => TTi18n::gettext( 'Enabled (Authenticated)' ),
2 => TTi18n::gettext( 'Enabled (UnAuthenticated)' ),
];
break;
case 'notification_status':
$retval = [
//Kill switch to enable or disable sending notifications entirely.
0 => TTi18n::gettext( 'Disabled' ),
1 => TTi18n::gettext( 'Enabled' ),
];
break;
case 'default_login_screen':
$retval = [
'Home' => TTi18n::gettext( 'Dashboard' ),
'TimeSheet' => TTi18n::gettext( 'TimeSheet' ),
'Schedule' => TTi18n::gettext( 'Schedule' ),
];
global $current_user;
if ( isset( $current_user ) && is_object( $current_user ) ) {
$permission = new Permission();
if ( $permission->Check( 'report', 'enabled', $current_user->getId(), $current_user->getCompany() ) ) {
$retval['SavedReport'] = TTi18n::gettext( 'Saved Reports' );
}
}
break;
case 'language':
$retval = TTi18n::getLanguageArray();
//Because the array keys are strings, flex needs a sort prefix to maintain the order.
if ( defined( 'TIMETREX_API' ) == true && TIMETREX_API == true ) {
$retval = Misc::addSortPrefix( $retval );
}
break;
case 'columns':
$retval = [
'-1000-first_name' => TTi18n::gettext( 'First Name' ),
'-1002-last_name' => TTi18n::gettext( 'Last Name' ),
'-1005-user_status' => TTi18n::gettext( 'Employee Status' ),
'-1010-title' => TTi18n::gettext( 'Title' ),
'-1020-user_group' => TTi18n::gettext( 'Group' ),
'-1030-default_branch' => TTi18n::gettext( 'Default Branch' ),
'-1040-default_department' => TTi18n::gettext( 'Default Department' ),
'-1150-city' => TTi18n::gettext( 'City' ),
'-1160-province' => TTi18n::gettext( 'Province/State' ),
'-1170-country' => TTi18n::gettext( 'Country' ),
'-1120-language_display' => TTi18n::gettext( 'Language' ),
'-1130-date_format_display' => TTi18n::gettext( 'Date Format' ),
'-1140-time_format_display' => TTi18n::gettext( 'Time Format' ),
'-1150-time_zone_display' => TTi18n::gettext( 'TimeZone' ),
'-1160-time_unit_format_display' => TTi18n::gettext( 'Time Unit Format' ),
'-1170-distance_format_display' => TTi18n::gettext( 'Distance Units' ),
'-1180-items_per_page' => TTi18n::gettext( 'Items Per Page' ),
//'-1180-timesheet_view_display' => TTi18n::gettext('TimeSheet View'),
'-1190-start_week_day_display' => TTi18n::gettext( 'Start Weekday' ),
//'-1100-enable_email_notification_exception' => TTi18n::gettext('Email Notification Exception'),
//'-1110-enable_email_notification_message' => TTi18n::gettext('Email Notification Message'),
//'-1110-enable_email_notification_pay_stub' => TTi18n::gettext('Email Notification Pay Stub'),
//'-1120-enable_email_notification_home' => TTi18n::gettext('Email Notification Home'),
'-2000-created_by' => TTi18n::gettext( 'Created By' ),
'-2010-created_date' => TTi18n::gettext( 'Created Date' ),
'-2020-updated_by' => TTi18n::gettext( 'Updated By' ),
'-2030-updated_date' => TTi18n::gettext( 'Updated Date' ),
];
break;
case 'list_columns':
$retval = Misc::arrayIntersectByKey( $this->getOptions( 'default_display_columns' ), Misc::trimSortPrefix( $this->getOptions( 'columns' ) ) );
break;
case 'default_display_columns': //Columns that are displayed by default.
$retval = [
'first_name',
'last_name',
'date_format_display',
'time_format_display',
'time_unit_format_display',
'distance_format_display',
'time_zone_display',
];
break;
}
return $retval;
}
/**
* @param $data
* @return array
*/
function _getVariableToFunctionMap( $data ) {
$variable_function_map = [
'id' => 'ID',
'user_id' => 'User',
'first_name' => false,
'last_name' => false,
'user_name' => false,
'user_status_id' => false,
'user_status' => false,
'group_id' => false,
'user_group' => false,
'title_id' => false,
'title' => false,
'default_branch_id' => false,
'default_branch' => false,
'default_department_id' => false,
'default_department' => false,
'city' => false,
'province' => false,
'country' => false,
'language' => 'Language',
'date_format' => 'DateFormat',
'time_format' => 'TimeFormat',
'time_zone' => 'TimeZone',
'time_unit_format' => 'TimeUnitFormat',
'distance_format' => 'DistanceFormat',
//Ignore when setting.
'language_display' => false,
'date_format_display' => false,
'time_format_display' => false,
'time_zone_display' => false,
'time_unit_format_display' => false,
'distance_format_display' => false,
'items_per_page' => 'ItemsPerPage',
//'timesheet_view' => 'TimeSheetView',
'start_week_day' => 'StartWeekDay',
'start_week_day_display' => false,
'shortcut_key_sequence' => 'ShortcutKeySequence',
'enable_always_blank_timesheet_rows' => 'EnableAlwaysBlankTimeSheetRows',
//'enable_auto_context_menu' => 'EnableAutoContextMenu',
'enable_report_open_new_window' => 'EnableReportOpenNewWindow',
//'enable_email_notification_exception' => 'EnableEmailNotificationException',
//'enable_email_notification_message' => 'EnableEmailNotificationMessage',
//'enable_email_notification_pay_stub' => 'EnableEmailNotificationPayStub',
//'enable_email_notification_home' => 'EnableEmailNotificationHome',
//'schedule_icalendar_url' => 'ScheduleIcalendarURL',
'schedule_icalendar_type_id' => 'ScheduleIcalendarType',
//'schedule_icalendar_event_name' => 'ScheduleIcalendarEventName',
'schedule_icalendar_alarm1_working' => 'ScheduleIcalendarAlarm1Working',
'schedule_icalendar_alarm2_working' => 'ScheduleIcalendarAlarm2Working',
'schedule_icalendar_alarm1_absence' => 'ScheduleIcalendarAlarm1Absence',
'schedule_icalendar_alarm2_absence' => 'ScheduleIcalendarAlarm2Absence',
'schedule_icalendar_alarm1_modified' => 'ScheduleIcalendarAlarm1Modified',
'schedule_icalendar_alarm2_modified' => 'ScheduleIcalendarAlarm2Modified',
'enable_save_timesheet_state' => 'EnableSaveTimesheetState',
'default_login_screen' => 'DefaultLoginScreen',
'notification_duration' => 'NotificationDuration',
'notification_status_id' => 'NotificationStatus',
'browser_permission_ask_date' => 'BrowserPermissionAskDate',
'deleted' => 'Deleted',
];
return $variable_function_map;
}
/**
* @return bool
*/
function getUserObject() {
return $this->getGenericObject( 'UserListFactory', $this->getUser(), 'user_obj' );
}
/**
* @return bool|mixed
*/
function getUser() {
return $this->getGenericDataValue( 'user_id' );
}
/**
* @param string $value UUID
* @return bool
*/
function setUser( $value ) {
$value = TTUUID::castUUID( $value );
return $this->setGenericDataValue( 'user_id', $value );
}
/**
* @return bool|mixed
*/
function getLanguage() {
return $this->getGenericDataValue( 'language' );
}
/**
* @param $value
* @return bool
*/
function setLanguage( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'language', $value );
}
/**
* @return bool
*/
function getDateFormatExample() {
return Option::getByKey( $this->getDateFormat(), Misc::trimSortPrefix( $this->getOptions( 'date_format_example' ) ) );
}
/**
* @return bool|string
*/
function getJSDateFormat() {
$js_date_format = Option::getByKey( $this->getDateFormat(), $this->getOptions( 'js_date_format' ) );
if ( $js_date_format != '' ) {
Debug::text( 'Javascript Date Format: ' . $js_date_format, __FILE__, __LINE__, __METHOD__, 10 );
return $js_date_format;
}
return '%d-%M-%y';
}
/**
* @return bool|mixed
*/
function getDateFormat() {
return $this->getGenericDataValue( 'date_format' );
}
/**
* @param int $value EPOCH
* @return bool
*/
function setDateFormat( $value ) {
$value = trim( $value );
Debug::text( 'Date Format: ' . $value . ' Type: ' . gettype( $value ), __FILE__, __LINE__, __METHOD__, 10 );
return $this->setGenericDataValue( 'date_format', $value );
}
/**
* @return array|mixed
*/
function getTimeFormatExample() {
return Misc::trimSortPrefix( Option::getByKey( $this->getTimeFormat(), $this->getOptions( 'time_format_example' ) ) );
}
/**
* @return bool|string
*/
function getJSTimeFormat() {
$js_time_format = Option::getByKey( $this->getTimeFormat(), $this->getOptions( 'js_time_format' ) );
if ( $js_time_format != '' ) {
Debug::text( 'Javascript Time Format: ' . $js_time_format, __FILE__, __LINE__, __METHOD__, 10 );
return $js_time_format;
}
return '%l:%M %p';
}
/**
* @return bool|mixed
*/
function getTimeFormat() {
return $this->getGenericDataValue( 'time_format' );
}
/**
* @param $value
* @return bool
*/
function setTimeFormat( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'time_format', $value );
}
/**
* @param $country
* @param $province
* @param bool $work_phone
* @param bool $home_phone
* @param bool $default
* @return array|bool|mixed|string
*/
function getLocationTimeZone( $country, $province, $work_phone = false, $home_phone = false, $default = false, $enable_auto_detect = true ) {
$country = strtoupper( $country );
$province = strtoupper( $province );
Debug::text( 'Country: ' . $country . ' Province: ' . $province . ' Work Phone: ' . $work_phone . ' Home Phone: ' . $home_phone . ' Default: ' . $default .' Enable AutoDetect: '. (int)$enable_auto_detect, __FILE__, __LINE__, __METHOD__, 9 );
if ( $enable_auto_detect == false && $default != '' ) {
return $default;
}
$location_timezones = $this->getOptions( 'location_timezone' );
$area_code_timezone = $this->getOptions( 'area_code_timezone' );
//Work phone can be the most accurate.
if ( $work_phone != '' ) {
$work_area_code = $this->Validator->getPhoneNumberAreaCode( $work_phone );
//Make sure the area code matches the province, so if a BC province is specified with a ON area code, we use the province instead of area code.
if ( $work_area_code !== false
&& isset( $area_code_timezone[$work_area_code] )
&& $area_code_timezone[$work_area_code]['time_zone'] != null
&& $area_code_timezone[$work_area_code]['province'] == $province ) {
Debug::text( 'Using Work Phone for timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
return $area_code_timezone[$work_area_code]['time_zone'];
}
}
//Home phone is the next most accurate
if ( $home_phone != '' ) {
$home_area_code = $this->Validator->getPhoneNumberAreaCode( $home_phone );
//Make sure the area code matches the province, so if a BC province is specified with a ON area code, we use the province instead of area code.
if ( $home_area_code !== false
&& isset( $area_code_timezone[$home_area_code] )
&& $area_code_timezone[$home_area_code]['time_zone'] != null
&& $area_code_timezone[$home_area_code]['province'] == $province ) {
Debug::text( 'Using Home Phone for timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
return $area_code_timezone[$home_area_code]['time_zone'];
}
}
//Country/province is the last option.
if ( $country != '' && isset( $location_timezones[$country] ) ) {
if ( $province != '' && is_array( $location_timezones[$country] ) && isset( $location_timezones[$country][$province] ) && $location_timezones[$country][$province] != null ) {
Debug::text( 'Using Country/Province for timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
if ( is_array( $location_timezones[$country][$province] ) && $default == '' ) { //No default specified, so lets guess and use the first item from the array, assuming its the most commonly used.
return Misc::trimSortPrefix( $location_timezones[$country][$province][0] );
} else if ( !is_array( $location_timezones[$country][$province] ) ) {
return Misc::trimSortPrefix( $location_timezones[$country][$province] );
}
} else if ( isset( $location_timezones[$country] ) && !is_array( $location_timezones[$country] ) && $location_timezones[$country] != null ) {
Debug::text( 'Using Country for timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
if ( is_array( $location_timezones[$country] ) && $default == '' ) { //No default specified, so lets guess and use the first item from the array, assuming its the most commonly used.
return Misc::trimSortPrefix( $location_timezones[$country][0] );
} else if ( !is_array( $location_timezones[$country] ) ) {
return Misc::trimSortPrefix( $location_timezones[$country] );
}
}
}
if ( $default != '' ) {
Debug::text( 'Using Default for timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
return $default;
}
Debug::text( 'Using GMT timezone detection...', __FILE__, __LINE__, __METHOD__, 9 );
return 'GMT';
}
/**
* @return bool|mixed
*/
function getTimeZone() {
return $this->getGenericDataValue( 'time_zone' );
}
/**
* @param $value
* @return bool
*/
function setTimeZone( $value ) {
$value = Misc::trimSortPrefix( trim( $value ) );
return $this->setGenericDataValue( 'time_zone', $value );
}
/**
* @return mixed
*/
function getTimeUnitFormatExample() {
$options = $this->getOptions( 'time_unit_format' );
return $options[$this->getTimeUnitFormat()];
}
/**
* @return bool|mixed
*/
function getTimeUnitFormat() {
return $this->getGenericDataValue( 'time_unit_format' );
}
/**
* @param $value
* @return bool
*/
function setTimeUnitFormat( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'time_unit_format', $value );
}
/**
* @param $meters
* @param null $format
* @return bool|float|int
*/
function convertMetersToDistance( $meters, $format = null ) {
if ( $format == '' ) {
$format = self::getDistanceFormat();
}
switch ( $format ) {
case 20: //Miles
$dst_unit = 'mi';
break;
case 30: //Meters
$dst_unit = 'm';
break;
case 10: //KM
default:
$dst_unit = 'km';
break;
}
return UnitConvert::convert( 'm', $dst_unit, $meters );
}
/**
* @return bool|mixed
*/
function getDistanceFormat() {
return $this->getGenericDataValue( 'distance_format' );
}
/**
* @param $value
* @return bool
*/
function setDistanceFormat( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'distance_format', $value );
}
/**
* @return bool|mixed
*/
function getItemsPerPage() {
return $this->getGenericDataValue( 'items_per_page' );
}
/**
* @param $value
* @return bool
*/
function setItemsPerPage( $value ) {
$value = (int)$value;
return $this->setGenericDataValue( 'items_per_page', $value );
}
/**
* @return bool|mixed
*/
function getNotificationDuration() {
return $this->getGenericDataValue( 'notification_duration' );
}
/**
* @param $value
* @return bool
*/
function setNotificationDuration( $value ) {
$value = (int)$value;
return $this->setGenericDataValue( 'notification_duration', $value );
}
/**
* A quick function to change just the timezone, without having to change
* date formats and such in the process.
* @return bool
*/
function setTimeZonePreferences() {
return TTDate::setTimeZone( $this->getTimeZone() );
}
/**
* @return bool
*/
function setDateTimePreferences() {
//TTDate::setTimeZone( $this->getTimeZone() );
if ( $this->setTimeZonePreferences() == false ) {
//In case setting the time zone failed
return false;
}
TTDate::setDateFormat( $this->getDateFormat() );
TTDate::setTimeFormat( $this->getTimeFormat() );
TTDate::setTimeUnitFormat( $this->getTimeUnitFormat() );
return true;
}
/**
* @return bool|mixed
*/
function getTimeSheetView() {
return $this->getGenericDataValue( 'timesheet_view' );
}
/**
* @param $value
* @return bool
*/
function setTimeSheetView( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'timesheet_view', $value );
}
/**
* @return bool|mixed
*/
function getStartWeekDay() {
return $this->getGenericDataValue( 'start_week_day' );
}
/**
* @param $value
* @return bool
*/
function setStartWeekDay( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'start_week_day', $value );
}
/**
* Used in Flex interface only, currently its hardcoded for now at least. Default: CTRL+ALT
* @return bool|mixed
*/
function getShortcutKeySequence() {
return $this->getGenericDataValue( 'shortcut_key_sequence' );
}
/**
* @param $value
* @return bool
*/
function setShortcutKeySequence( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'shortcut_key_sequence', $value );
}
/**
* @return bool
*/
function getEnableAlwaysBlankTimeSheetRows() {
return $this->fromBool( $this->getGenericDataValue( 'enable_always_blank_timesheet_rows' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableAlwaysBlankTimeSheetRows( $value ) {
return $this->setGenericDataValue( 'enable_always_blank_timesheet_rows', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableAutoContextMenu() {
return $this->fromBool( $this->getGenericDataValue( 'enable_auto_context_menu' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableAutoContextMenu( $value ) {
return $this->setGenericDataValue( 'enable_auto_context_menu', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableReportOpenNewWindow() {
return $this->fromBool( $this->getGenericDataValue( 'enable_report_open_new_window' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableReportOpenNewWindow( $value ) {
return $this->setGenericDataValue( 'enable_report_open_new_window', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableEmailNotificationException() {
return $this->fromBool( $this->getGenericDataValue( 'enable_email_notification_exception' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableEmailNotificationException( $value ) {
return $this->setGenericDataValue( 'enable_email_notification_exception', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableEmailNotificationMessage() {
return $this->fromBool( $this->getGenericDataValue( 'enable_email_notification_message' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableEmailNotificationMessage( $value ) {
return $this->setGenericDataValue( 'enable_email_notification_message', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableEmailNotificationPayStub() {
return $this->fromBool( $this->getGenericDataValue( 'enable_email_notification_pay_stub' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableEmailNotificationPayStub( $value ) {
return $this->setGenericDataValue( 'enable_email_notification_pay_stub', $this->toBool( $value ) );
}
/**
* @return bool
*/
function getEnableEmailNotificationHome() {
return $this->fromBool( $this->getGenericDataValue( 'enable_email_notification_home' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableEmailNotificationHome( $value ) {
return $this->setGenericDataValue( 'enable_email_notification_home', $this->toBool( $value ) );
}
/**
* @return bool|int
*/
function getScheduleIcalendarType() {
return $this->getGenericDataValue( 'schedule_icalendar_type_id' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarType( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_type_id', $value );
}
/**
* Helper functions for dealing with unauthenticated calendar access, required by Google Calendar for now.
* @param null $user_name
* @param int $type_id ID
* @param null $selected_schedule
* @return string
*/
function getScheduleIcalendarURL( $user_name = null, $type_id = null, $selected_schedule = null ) {
if ( $user_name == '' ) {
$user_name = $this->getUserObject()->getUserName();
}
if ( $type_id == '' ) {
$type_id = $this->getScheduleIcalendarType();
}
$url_fragments = [];
if ( $type_id == 2 ) {
$url_fragments[] = 'u=' . $user_name;
$url_fragments[] = 'k=' . $this->getScheduleIcalendarKey();
}
if ( $selected_schedule != '' ) {
$url_fragments[] = 's=' . $selected_schedule;
}
$retval = Environment::getBaseURL() . 'ical/ical.php';
if ( count( $url_fragments ) > 0 ) {
$retval .= '?' . implode( '&', $url_fragments );
}
return $retval;
}
/**
* @param $key
* @return bool
*/
function checkScheduleICalendarKey( $key ) {
Debug::text( 'Checking Key: ' . $key . ' Should Match: ' . $this->getScheduleIcalendarKey(), __FILE__, __LINE__, __METHOD__, 10 );
if ( trim( $key ) == $this->getScheduleIcalendarKey( TTPassword::getPasswordVersion( $key ) ) ) {
return true;
}
return false;
}
/**
* @param null $version
* @return bool|string
*/
function getScheduleIcalendarKey( $version = null ) {
if ( (int)$version == 1 ) {
$salt = TTPassword::getPasswordSalt();
$user_id = TTUUID::convertUUIDToInt( $this->getUserObject()->getID() );
$retval = substr( md5( $this->getScheduleIcalendarEventName() . $salt . $user_id ), 0, 12 );
} else { //Should be v3.
$user_name = TTUUID::castUUID( $this->getUserObject()->getUserName() );
$user_id = TTUUID::castUUID( $this->getUserObject()->getID() );
//Use the TTPassword class to better handle different versions of the hashed data.
$retval = strtoupper( substr( TTPassword::encryptPassword( $user_name, $user_id, $this->getScheduleIcalendarEventName(), $version ), 0, 12 ) );
}
Debug::text( 'Key: ' . $retval, __FILE__, __LINE__, __METHOD__, 10 );
return $retval;
}
/**
* Currently used as part of the unauthenticated key, so if this changes the key to access the calendar changes too.
* @return bool
*/
function getScheduleIcalendarEventName() {
return $this->fromBool( $this->getGenericDataValue( 'schedule_icalendar_event_name' ) );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarEventName( $value ) {
return $this->setGenericDataValue( 'schedule_icalendar_event_name', $this->toBool( $value ) );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm1Working() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm1_working' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm1Working( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm1_working', $value );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm2Working() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm2_working' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm2Working( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm2_working', $value );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm1Absence() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm1_absence' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm1Absence( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm1_absence', $value );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm2Absence() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm2_absence' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm2Absence( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm2_absence', $value );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm1Modified() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm1_modified' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm1Modified( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm1_modified', $value );
}
/**
* @return bool|int
*/
function getScheduleIcalendarAlarm2Modified() {
return (int)$this->getGenericDataValue( 'schedule_icalendar_alarm2_modified' );
}
/**
* @param $value
* @return bool
*/
function setScheduleIcalendarAlarm2Modified( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue( 'schedule_icalendar_alarm2_modified', $value );
}
/**
* @return bool
*/
function getEnableSaveTimesheetState() {
return $this->fromBool( $this->getGenericDataValue( 'enable_save_timesheet_state' ) );
}
/**
* @param $value
* @return bool
*/
function setEnableSaveTimesheetState( $value ) {
return $this->setGenericDataValue( 'enable_save_timesheet_state', $this->toBool( $value ) );
}
/**
* @return int
*/
function getNotificationStatus() {
return $this->getGenericDataValue( 'notification_status_id' ); //Don't cast to INT as we need to check for false or 0.
}
/**
* @param $value
* @return bool
*/
function setNotificationStatus( $value ) {
$value = (int)trim( $value );
return $this->setGenericDataValue('notification_status_id', $value );
}
/**
* @return int
*/
function getBrowserPermissionAskDate( $raw = false ) {
$value = $this->getGenericDataValue( 'browser_permission_ask_date' );
if ( $value !== false ) {
if ( $raw === true ) {
return $value;
} else {
return TTDate::strtotime( $value );
}
}
return false;
}
/**
* @param $epoch
* @return bool
*/
function setBrowserPermissionAskDate( $epoch ) {
$value = (int)$epoch;
return $this->setGenericDataValue('browser_permission_ask_date', $value );
}
/**
* Default: Home/Dashboard
* @return bool|mixed
*/
function getDefaultLoginScreen() {
return $this->getGenericDataValue( 'default_login_screen' );
}
/**
* @param $value
* @return bool
*/
function setDefaultLoginScreen( $value ) {
$value = trim( $value );
return $this->setGenericDataValue( 'default_login_screen', $value );
}
/**
* @param bool $ignore_warning
* @return bool
*/
function Validate( $ignore_warning = true ) {
//
// BELOW: Validation code moved from set*() functions.
//
// User
if ( $this->getUser() != TTUUID::getZeroID() ) {
$ulf = TTnew( 'UserListFactory' ); /** @var UserListFactory $ulf */
$this->Validator->isResultSetWithRows( 'user',
$ulf->getByID( $this->getUser() ),
TTi18n::gettext( 'Invalid Employee' )
);
}
// Language
$language_options = TTi18n::getLanguageArray();
$this->Validator->inArrayKey( 'language',
$this->getLanguage(),
TTi18n::gettext( 'Incorrect language' ),
$language_options
);
// Date format
if ( $this->getDateFormat() != '' ) {
$this->Validator->inArrayKey( 'date_format',
$this->getDateFormat(),
TTi18n::gettext( 'Incorrect date format' ),
Misc::trimSortPrefix( $this->getOptions( 'date_format' ) )
);
}
// Time format
$this->Validator->inArrayKey( 'time_format',
$this->getTimeFormat(),
TTi18n::gettext( 'Incorrect time format' ),
$this->getOptions( 'time_format' )
);
// Time zone
$this->Validator->inArrayKey( 'time_zone',
$this->getTimeZone(),
TTi18n::gettext( 'Incorrect time zone' ),
Misc::trimSortPrefix( $this->getOptions( 'time_zone' ) )
);
// Time units
$this->Validator->inArrayKey( 'time_unit_format',
$this->getTimeUnitFormat(),
TTi18n::gettext( 'Incorrect time units' ),
$this->getOptions( 'time_unit_format' )
);
// Distance units
$this->Validator->inArrayKey( 'distance_format',
$this->getDistanceFormat(),
TTi18n::gettext( 'Incorrect distance units' ),
$this->getOptions( 'distance_format' )
);
// Items per page
$items_per_page_min = ( PRODUCTION == false ) ? 1 : 5; //Allow lower numbers to help with testing.
$items_per_page_max = ( PRODUCTION == false ) ? 10000 : 2000; //Allow higher numbers to help with testing.
if ( $this->getItemsPerPage() == '' || $this->getItemsPerPage() < $items_per_page_min || $this->getItemsPerPage() > $items_per_page_max ) {
$this->Validator->isTrue( 'items_per_page',
false,
TTi18n::gettext( 'Rows per page must be between %1 and %2', [ $items_per_page_min, $items_per_page_max ] )
);
}
// Default TimeSheet view'
if ( $this->getTimeSheetView() !== false ) {
$this->Validator->inArrayKey( 'timesheet_view',
$this->getTimeSheetView(),
TTi18n::gettext( 'Incorrect default TimeSheet view' ),
$this->getOptions( 'timesheet_view' )
);
}
// Day to start a week on
$this->Validator->inArrayKey( 'start_week_day',
$this->getStartWeekDay(),
TTi18n::gettext( 'Incorrect day to start a week on' ),
$this->getOptions( 'start_week_day' )
);
// Shortcut key sequence
if ( $this->getShortcutKeySequence() != '' ) {
$this->Validator->isLength( 'shortcut_key_sequence',
$this->getShortcutKeySequence(),
TTi18n::gettext( 'Shortcut key sequence is too short or too long' ),
0,
250
);
}
// Option to enable calendar synchronization
$this->Validator->inArrayKey( 'schedule_icalendar_type_id',
$this->getScheduleIcalendarType(),
TTi18n::gettext( 'Incorrect option to enable calendar synchronization' ),
$this->getOptions( 'schedule_icalendar_type' )
);
// Time for alarm #1
$this->Validator->isNumeric( 'schedule_icalendar_alarm1_working',
$this->getScheduleIcalendarAlarm1Working(),
TTi18n::gettext( 'Invalid time for alarm #1' )
);
// Time for alarm #2
$this->Validator->isNumeric( 'schedule_icalendar_alarm2_working',
$this->getScheduleIcalendarAlarm2Working(),
TTi18n::gettext( 'Invalid time for alarm #2' )
);
// Time for alarm #1
$this->Validator->isNumeric( 'schedule_icalendar_alarm1_absence',
$this->getScheduleIcalendarAlarm1Absence(),
TTi18n::gettext( 'Invalid time for alarm #1' )
);
// Time for alarm #2
$this->Validator->isNumeric( 'schedule_icalendar_alarm2_absence',
$this->getScheduleIcalendarAlarm2Absence(),
TTi18n::gettext( 'Invalid time for alarm #2' )
);
// Time for alarm #1
$this->Validator->isNumeric( 'schedule_icalendar_alarm1_modified',
$this->getScheduleIcalendarAlarm1Modified(),
TTi18n::gettext( 'Invalid time for alarm #1' )
);
// Time for alarm #2
$this->Validator->isNumeric( 'schedule_icalendar_alarm2_modified',
$this->getScheduleIcalendarAlarm2Modified(),
TTi18n::gettext( 'Invalid time for alarm #2' )
);
// Default login screen
if ( $this->getDefaultLoginScreen() != '' ) {
$this->Validator->isLength( 'default_login_screen',
$this->getDefaultLoginScreen(),
TTi18n::gettext( 'Default login screen is too short or too long' ),
0,
250
);
}
//
// ABOVE: Validation code moved from set*() functions.
//
if ( $this->getUser() == '' ) {
$this->Validator->isTRUE( 'user',
false,
TTi18n::gettext( 'Invalid Employee' ) );
}
if ( $this->getDateFormat() == '' ) {
$this->Validator->isTRUE( 'date_format',
false,
TTi18n::gettext( 'Incorrect date format' ) );
}
// Duration of notification popup in web browser.
if ( $this->getNotificationDuration() < 0 || $this->getNotificationDuration() > 86400 ) {
$this->Validator->isTrue( 'notification_duration',
false,
TTi18n::gettext( 'Notification duration must be between 0 and 86400 seconds' ) );
}
// status of push notificstion settings
$this->Validator->inArrayKey( 'notification_status_id',
$this->getNotificationStatus(),
TTi18n::gettext( 'Incorrect Notification Status' ),
$this->getOptions( 'notification_status' )
);
return true;
}
/**
* @return bool
*/
function isPreferencesComplete() {
if ( $this->getItemsPerPage() == ''
|| $this->getTimeZone() == '' ) {
Debug::text( 'User Preferences is NOT Complete: ', __FILE__, __LINE__, __METHOD__, 10 );
return false;
}
Debug::text( 'User Preferences IS Complete: ', __FILE__, __LINE__, __METHOD__, 10 );
return true;
}
/**
* @return bool
*/
function preValidate() {
global $config_vars;
if ( isset( $config_vars['other']['installer_enabled'] ) && $config_vars['other']['installer_enabled'] != 1 ) {
//These cause SQL errors when upgrading from older schema versions (1113A), so skip them for now.
if ( $this->getNotificationStatus() === false || $this->getNotificationStatus() === '' ) {
$this->setNotificationStatus( 1 ); //1=Enabled
}
if ( $this->getNotificationDuration() === false || $this->getNotificationStatus() === '' ) {
$this->setNotificationDuration( 120 );
}
}
//Check the locale, if its not english, we need to make sure the selected date format is correct for the language, or else force it.
if ( $this->getLanguage() != 'en' ) {
if ( Option::getByValue( $this->getDateFormat(), $this->getOptions( 'other_date_format' ) ) == false ) {
//Force a change of date format
$this->setDateFormat( 'd/m/Y' );
Debug::text( 'Language changed and date format doesnt match any longer, forcing it to: d/m/Y', __FILE__, __LINE__, __METHOD__, 10 );
} else {
Debug::text( 'Date format doesnt need fixing...', __FILE__, __LINE__, __METHOD__, 10 );
}
}
return true;
}
/**
* @return bool
*/
function postSave() {
$this->removeCache( $this->getUser() );
if ( is_object( $this->getUserObject() ) ) {
//CompanyFactory->getEncoding() is used to determine report encodings based on data saved here.
$this->removeCache( 'encoding_' . $this->getUserObject()->getCompany(), 'company' );
}
return true;
}
/**
* Support setting created_by, updated_by especially for importing data.
* Make sure data is set based on the getVariableToFunctionMap order.
* @param $data
* @return bool
*/
function setObjectFromArray( $data ) {
if ( is_array( $data ) ) {
$variable_function_map = $this->getVariableToFunctionMap();
foreach ( $variable_function_map as $key => $function ) {
if ( isset( $data[$key] ) ) {
$function = 'set' . $function;
switch ( $key ) {
default:
if ( method_exists( $this, $function ) ) {
$this->$function( $data[$key] );
}
break;
}
}
}
$this->setCreatedAndUpdatedColumns( $data );
return true;
}
return false;
}
/**
* @param null $include_columns
* @param bool $permission_children_ids
* @return array
*/
function getObjectAsArray( $include_columns = null, $permission_children_ids = false ) {
$uf = TTnew( 'UserFactory' ); /** @var UserFactory $uf */
$data = [];
$variable_function_map = $this->getVariableToFunctionMap();
if ( is_array( $variable_function_map ) ) {
foreach ( $variable_function_map as $variable => $function_stub ) {
if ( $include_columns == null || ( isset( $include_columns[$variable] ) && $include_columns[$variable] == true ) ) {
$function = 'get' . $function_stub;
switch ( $variable ) {
case 'first_name':
case 'last_name':
case 'user_name':
case 'user_status_id':
case 'group_id':
case 'user_group':
case 'title_id':
case 'title':
case 'default_branch_id':
case 'default_branch':
case 'default_department_id':
case 'default_department':
case 'city':
case 'province':
case 'country':
$data[$variable] = $this->getColumn( $variable );
break;
case 'user_status':
$data[$variable] = Option::getByKey( (int)$this->getColumn( 'user_status_id' ), $uf->getOptions( 'status' ) );
break;
//Add the *_display element for each of the below fields.
case 'language_display':
case 'time_zone_display':
case 'time_unit_format_display':
case 'distance_format_display':
case 'timesheet_view_display':
case 'start_week_day_display':
switch ( $variable ) {
case 'language_display':
$function = 'getLanguage';
break;
//Use Date/Time format example functions below instead.
//case 'date_format_display':
// $function = 'getDateFormat';
// break;
//case 'time_format_display':
// $function = 'getTimeFormat';
// break;
case 'time_zone_display':
$function = 'getTimeZone';
break;
case 'time_unit_format_display':
$function = 'getTimeUnitFormat';
break;
case 'distance_format_display':
$function = 'getDistanceFormat';
break;
case 'timesheet_view_display':
$function = 'getTimeSheetView';
break;
case 'start_week_day_display':
$function = 'getStartWeekDay';
break;
}
$variable = str_replace( '_display', '', $variable );
if ( method_exists( $this, $function ) ) {
$data[$variable . '_display'] = Option::getByKey( $this->$function(), Misc::trimSortPrefix( $this->getOptions( $variable ) ) );
}
break;
case 'date_format_display':
$data[$variable] = $this->getDateFormatExample();
break;
case 'time_format_display':
$data[$variable] = $this->getTimeFormatExample();
break;
default:
if ( method_exists( $this, $function ) ) {
$data[$variable] = $this->$function();
}
break;
}
}
}
$this->getPermissionColumns( $data, $this->getUser(), $this->getCreatedBy(), $permission_children_ids, $include_columns );
$this->getCreatedAndUpdatedColumns( $data, $include_columns );
}
return $data;
}
/**
* @param $log_action
* @return bool
*/
function addLog( $log_action ) {
$u_obj = $this->getUserObject();
if ( is_object( $u_obj ) ) {
return TTLog::addEntry( $this->getId(), $log_action, TTi18n::getText( 'Employee Preferences' ) . ': ' . $u_obj->getFullName( false, true ), null, $this->getTable(), $this );
}
return false;
}
}
?>