mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 07:00:06 +00:00 
			
		
		
		
	Merge pull request #178 from dpaulat/feature/time-customization
Time Customization
This commit is contained in:
		
						commit
						0fabe1e3a3
					
				
					 18 changed files with 679 additions and 409 deletions
				
			
		|  | @ -1,208 +1,208 @@ | ||||||
| [ | [ | ||||||
| 	{ "type":"wsr88d", "id":"RODN", "lat":26.307796,  "lon":127.903422,   "country":"JPN", "state":"OKI", "place":"Kadena Air Base" }, | 	{ "type": "wsr88d", "id": "RODN", "lat": 26.307796,  "lon": 127.903422,   "country": "JPN", "state": "OKI", "place": "Kadena Air Base",         "tz": "Asia/Tokyo" }, | ||||||
| 	{ "type":"wsr88d", "id":"RKSG", "lat":37.207652,  "lon":127.285614,   "country":"KOR", "state":"41",  "place":"Camp Humphreys" }, | 	{ "type": "wsr88d", "id": "RKSG", "lat": 37.207652,  "lon": 127.285614,   "country": "KOR", "state": "41",  "place": "Camp Humphreys",          "tz": "Asia/Seoul" }, | ||||||
| 	{ "type":"wsr88d", "id":"RKJK", "lat":35.92417,   "lon":126.62222,    "country":"KOR", "state":"45",  "place":"Kunsan Air Base" }, | 	{ "type": "wsr88d", "id": "RKJK", "lat": 35.92417,   "lon": 126.62222,    "country": "KOR", "state": "45",  "place": "Kunsan Air Base",         "tz": "Asia/Seoul" }, | ||||||
| 	{ "type":"wsr88d", "id":"PABC", "lat":60.791987,  "lon":-161.876539,  "country":"USA", "state":"AK",  "place":"Bethel" }, | 	{ "type": "wsr88d", "id": "PABC", "lat": 60.791987,  "lon": -161.876539,  "country": "USA", "state": "AK",  "place": "Bethel",                  "tz": "America/Anchorage" }, | ||||||
| 	{ "type":"wsr88d", "id":"PAPD", "lat":65.0351238, "lon":-147.5014222, "country":"USA", "state":"AK",  "place":"Fairbanks/Pedro Dome" }, | 	{ "type": "wsr88d", "id": "PAPD", "lat": 65.0351238, "lon": -147.5014222, "country": "USA", "state": "AK",  "place": "Fairbanks/Pedro Dome",    "tz": "America/Anchorage" }, | ||||||
| 	{ "type":"wsr88d", "id":"PAHG", "lat":60.6156335, "lon":-151.2832296, "country":"USA", "state":"AK",  "place":"Kenai" }, | 	{ "type": "wsr88d", "id": "PAHG", "lat": 60.6156335, "lon": -151.2832296, "country": "USA", "state": "AK",  "place": "Kenai",                   "tz": "America/Anchorage" }, | ||||||
| 	{ "type":"wsr88d", "id":"PAKC", "lat":58.6794558, "lon":-156.6293335, "country":"USA", "state":"AK",  "place":"King Salmon" }, | 	{ "type": "wsr88d", "id": "PAKC", "lat": 58.6794558, "lon": -156.6293335, "country": "USA", "state": "AK",  "place": "King Salmon",             "tz": "America/Anchorage" }, | ||||||
| 	{ "type":"wsr88d", "id":"PAIH", "lat":59.46194,   "lon":-146.30111,   "country":"USA", "state":"AK",  "place":"Middleton Island" }, | 	{ "type": "wsr88d", "id": "PAIH", "lat": 59.46194,   "lon": -146.30111,   "country": "USA", "state": "AK",  "place": "Middleton Island",        "tz": "America/Anchorage" }, | ||||||
| 	{ "type":"wsr88d", "id":"PAEC", "lat":64.5114973, "lon":-165.2949071, "country":"USA", "state":"AK",  "place":"Nome" }, | 	{ "type": "wsr88d", "id": "PAEC", "lat": 64.5114973, "lon": -165.2949071, "country": "USA", "state": "AK",  "place": "Nome",                    "tz": "America/Nome" }, | ||||||
| 	{ "type":"wsr88d", "id":"PACG", "lat":56.85214,   "lon":-135.552417,  "country":"USA", "state":"AK",  "place":"Sitka/Biorka Island" }, | 	{ "type": "wsr88d", "id": "PACG", "lat": 56.85214,   "lon": -135.552417,  "country": "USA", "state": "AK",  "place": "Sitka/Biorka Island",     "tz": "America/Sitka" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBMX", "lat":33.1722806, "lon":-86.7698425,  "country":"USA", "state":"AL",  "place":"Birmingham" }, | 	{ "type": "wsr88d", "id": "KBMX", "lat": 33.1722806, "lon": -86.7698425,  "country": "USA", "state": "AL",  "place": "Birmingham",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEOX", "lat":31.4605622, "lon":-85.4592401,  "country":"USA", "state":"AL",  "place":"Fort Rucker" }, | 	{ "type": "wsr88d", "id": "KEOX", "lat": 31.4605622, "lon": -85.4592401,  "country": "USA", "state": "AL",  "place": "Fort Rucker",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHTX", "lat":34.930508,  "lon":-86.0837388,  "country":"USA", "state":"AL",  "place":"Huntsville" }, | 	{ "type": "wsr88d", "id": "KHTX", "lat": 34.930508,  "lon": -86.0837388,  "country": "USA", "state": "AL",  "place": "Huntsville",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMXX", "lat":32.5366608, "lon":-85.7897848,  "country":"USA", "state":"AL",  "place":"Maxwell AFB" }, | 	{ "type": "wsr88d", "id": "KMXX", "lat": 32.5366608, "lon": -85.7897848,  "country": "USA", "state": "AL",  "place": "Maxwell AFB",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMOB", "lat":30.6795378, "lon":-88.2397816,  "country":"USA", "state":"AL",  "place":"Mobile" }, | 	{ "type": "wsr88d", "id": "KMOB", "lat": 30.6795378, "lon": -88.2397816,  "country": "USA", "state": "AL",  "place": "Mobile",                  "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSRX", "lat":35.2904423, "lon":-94.3619075,  "country":"USA", "state":"AR",  "place":"Fort Smith" }, | 	{ "type": "wsr88d", "id": "KSRX", "lat": 35.2904423, "lon": -94.3619075,  "country": "USA", "state": "AR",  "place": "Fort Smith",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLZK", "lat":34.8365261, "lon":-92.2621697,  "country":"USA", "state":"AR",  "place":"Little Rock" }, | 	{ "type": "wsr88d", "id": "KLZK", "lat": 34.8365261, "lon": -92.2621697,  "country": "USA", "state": "AR",  "place": "Little Rock",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFSX", "lat":34.574449,  "lon":-111.198367,  "country":"USA", "state":"AZ",  "place":"Flagstaff" }, | 	{ "type": "wsr88d", "id": "KFSX", "lat": 34.574449,  "lon": -111.198367,  "country": "USA", "state": "AZ",  "place": "Flagstaff",               "tz": "America/Phoenix" }, | ||||||
| 	{ "type":"wsr88d", "id":"KIWA", "lat":33.289111,  "lon":-111.6700092, "country":"USA", "state":"AZ",  "place":"Phoenix" }, | 	{ "type": "wsr88d", "id": "KIWA", "lat": 33.289111,  "lon": -111.6700092, "country": "USA", "state": "AZ",  "place": "Phoenix",                 "tz": "America/Phoenix" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEMX", "lat":31.8937186, "lon":-110.6304306, "country":"USA", "state":"AZ",  "place":"Tucson" }, | 	{ "type": "wsr88d", "id": "KEMX", "lat": 31.8937186, "lon": -110.6304306, "country": "USA", "state": "AZ",  "place": "Tucson",                  "tz": "America/Phoenix" }, | ||||||
| 	{ "type":"wsr88d", "id":"KYUX", "lat":32.4953477, "lon":-114.6567214, "country":"USA", "state":"AZ",  "place":"Yuma" }, | 	{ "type": "wsr88d", "id": "KYUX", "lat": 32.4953477, "lon": -114.6567214, "country": "USA", "state": "AZ",  "place": "Yuma",                    "tz": "America/Phoenix" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBBX", "lat":39.4956958, "lon":-121.6316557, "country":"USA", "state":"CA",  "place":"Beale AFB" }, | 	{ "type": "wsr88d", "id": "KBBX", "lat": 39.4956958, "lon": -121.6316557, "country": "USA", "state": "CA",  "place": "Beale AFB",               "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEYX", "lat":35.0979358, "lon":-117.5608832, "country":"USA", "state":"CA",  "place":"Edwards AFB" }, | 	{ "type": "wsr88d", "id": "KEYX", "lat": 35.0979358, "lon": -117.5608832, "country": "USA", "state": "CA",  "place": "Edwards AFB",             "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBHX", "lat":40.4986955, "lon":-124.2918867, "country":"USA", "state":"CA",  "place":"Eureka" }, | 	{ "type": "wsr88d", "id": "KBHX", "lat": 40.4986955, "lon": -124.2918867, "country": "USA", "state": "CA",  "place": "Eureka",                  "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KVTX", "lat":34.4116386, "lon":-119.1795641, "country":"USA", "state":"CA",  "place":"Los Angeles" }, | 	{ "type": "wsr88d", "id": "KVTX", "lat": 34.4116386, "lon": -119.1795641, "country": "USA", "state": "CA",  "place": "Los Angeles",             "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDAX", "lat":38.5011529, "lon":-121.6778487, "country":"USA", "state":"CA",  "place":"Sacramento" }, | 	{ "type": "wsr88d", "id": "KDAX", "lat": 38.5011529, "lon": -121.6778487, "country": "USA", "state": "CA",  "place": "Sacramento",              "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KNKX", "lat":32.9189891, "lon":-117.041814,  "country":"USA", "state":"CA",  "place":"San Diego" }, | 	{ "type": "wsr88d", "id": "KNKX", "lat": 32.9189891, "lon": -117.041814,  "country": "USA", "state": "CA",  "place": "San Diego",               "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMUX", "lat":37.155152,  "lon":-121.8984577, "country":"USA", "state":"CA",  "place":"San Francisco" }, | 	{ "type": "wsr88d", "id": "KMUX", "lat": 37.155152,  "lon": -121.8984577, "country": "USA", "state": "CA",  "place": "San Francisco",           "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHNX", "lat":36.3142088, "lon":-119.6320903, "country":"USA", "state":"CA",  "place":"San Joaquin Valley" }, | 	{ "type": "wsr88d", "id": "KHNX", "lat": 36.3142088, "lon": -119.6320903, "country": "USA", "state": "CA",  "place": "San Joaquin Valley",      "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSOX", "lat":33.8176452, "lon":-117.6359743, "country":"USA", "state":"CA",  "place":"Santa Ana Mountains" }, | 	{ "type": "wsr88d", "id": "KSOX", "lat": 33.8176452, "lon": -117.6359743, "country": "USA", "state": "CA",  "place": "Santa Ana Mountains",     "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KVBG", "lat":34.8383137, "lon":-120.3977805, "country":"USA", "state":"CA",  "place":"Vandenberg AFB" }, | 	{ "type": "wsr88d", "id": "KVBG", "lat": 34.8383137, "lon": -120.3977805, "country": "USA", "state": "CA",  "place": "Vandenberg AFB",          "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFTG", "lat":39.7866156, "lon":-104.5458126, "country":"USA", "state":"CO",  "place":"Denver" }, | 	{ "type": "wsr88d", "id": "KFTG", "lat": 39.7866156, "lon": -104.5458126, "country": "USA", "state": "CO",  "place": "Denver",                  "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGJX", "lat":39.0619824, "lon":-108.2137012, "country":"USA", "state":"CO",  "place":"Grand Junction" }, | 	{ "type": "wsr88d", "id": "KGJX", "lat": 39.0619824, "lon": -108.2137012, "country": "USA", "state": "CO",  "place": "Grand Junction",          "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KPUX", "lat":38.4595034, "lon":-104.1816223, "country":"USA", "state":"CO",  "place":"Pueblo" }, | 	{ "type": "wsr88d", "id": "KPUX", "lat": 38.4595034, "lon": -104.1816223, "country": "USA", "state": "CO",  "place": "Pueblo",                  "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDOX", "lat":38.8257651, "lon":-75.4400763,  "country":"USA", "state":"DE",  "place":"Dover AFB" }, | 	{ "type": "wsr88d", "id": "KDOX", "lat": 38.8257651, "lon": -75.4400763,  "country": "USA", "state": "DE",  "place": "Dover AFB",               "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEVX", "lat":30.5649908, "lon":-85.921559,   "country":"USA", "state":"FL",  "place":"Eglin AFB" }, | 	{ "type": "wsr88d", "id": "KEVX", "lat": 30.5649908, "lon": -85.921559,   "country": "USA", "state": "FL",  "place": "Eglin AFB",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KJAX", "lat":30.4846878, "lon":-81.7018917,  "country":"USA", "state":"FL",  "place":"Jacksonville" }, | 	{ "type": "wsr88d", "id": "KJAX", "lat": 30.4846878, "lon": -81.7018917,  "country": "USA", "state": "FL",  "place": "Jacksonville",            "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBYX", "lat":24.5974996, "lon":-81.7032355,  "country":"USA", "state":"FL",  "place":"Key West" }, | 	{ "type": "wsr88d", "id": "KBYX", "lat": 24.5974996, "lon": -81.7032355,  "country": "USA", "state": "FL",  "place": "Key West",                "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMLB", "lat":28.1131808, "lon":-80.6540988,  "country":"USA", "state":"FL",  "place":"Melbourne" }, | 	{ "type": "wsr88d", "id": "KMLB", "lat": 28.1131808, "lon": -80.6540988,  "country": "USA", "state": "FL",  "place": "Melbourne",               "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KAMX", "lat":25.6111275, "lon":-80.412747,   "country":"USA", "state":"FL",  "place":"Miami" }, | 	{ "type": "wsr88d", "id": "KAMX", "lat": 25.6111275, "lon": -80.412747,   "country": "USA", "state": "FL",  "place": "Miami",                   "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTLH", "lat":30.397568,  "lon":-84.3289116,  "country":"USA", "state":"FL",  "place":"Tallahassee" }, | 	{ "type": "wsr88d", "id": "KTLH", "lat": 30.397568,  "lon": -84.3289116,  "country": "USA", "state": "FL",  "place": "Tallahassee",             "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTBW", "lat":27.7054701, "lon":-82.40179,    "country":"USA", "state":"FL",  "place":"Tampa" }, | 	{ "type": "wsr88d", "id": "KTBW", "lat": 27.7054701, "lon": -82.40179,    "country": "USA", "state": "FL",  "place": "Tampa",                   "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFFC", "lat":33.3635771, "lon":-84.565866,   "country":"USA", "state":"GA",  "place":"Atlanta" }, | 	{ "type": "wsr88d", "id": "KFFC", "lat": 33.3635771, "lon": -84.565866,   "country": "USA", "state": "GA",  "place": "Atlanta",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KVAX", "lat":30.8903853, "lon":-83.0019021,  "country":"USA", "state":"GA",  "place":"Moody AFB" }, | 	{ "type": "wsr88d", "id": "KVAX", "lat": 30.8903853, "lon": -83.0019021,  "country": "USA", "state": "GA",  "place": "Moody AFB",               "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KJGX", "lat":32.6755239, "lon":-83.3508575,  "country":"USA", "state":"GA",  "place":"Robins AFB" }, | 	{ "type": "wsr88d", "id": "KJGX", "lat": 32.6755239, "lon": -83.3508575,  "country": "USA", "state": "GA",  "place": "Robins AFB",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"PGUA", "lat":13.455965,  "lon":144.8111022,  "country":"USA", "state":"GU",  "place":"Andersen AFB" }, | 	{ "type": "wsr88d", "id": "PGUA", "lat": 13.455965,  "lon": 144.8111022,  "country": "USA", "state": "GU",  "place": "Andersen AFB",            "tz": "Pacific/Guam" }, | ||||||
| 	{ "type":"wsr88d", "id":"PHKI", "lat":21.8938762, "lon":-159.5524585, "country":"USA", "state":"HI",  "place":"Kauai" }, | 	{ "type": "wsr88d", "id": "PHKI", "lat": 21.8938762, "lon": -159.5524585, "country": "USA", "state": "HI",  "place": "Kauai",                   "tz": "Pacific/Honolulu" }, | ||||||
| 	{ "type":"wsr88d", "id":"PHKM", "lat":20.1254606, "lon":-155.778054,  "country":"USA", "state":"HI",  "place":"Kohala" }, | 	{ "type": "wsr88d", "id": "PHKM", "lat": 20.1254606, "lon": -155.778054,  "country": "USA", "state": "HI",  "place": "Kohala",                  "tz": "Pacific/Honolulu" }, | ||||||
| 	{ "type":"wsr88d", "id":"PHMO", "lat":21.1327531, "lon":-157.1802807, "country":"USA", "state":"HI",  "place":"Molokai" }, | 	{ "type": "wsr88d", "id": "PHMO", "lat": 21.1327531, "lon": -157.1802807, "country": "USA", "state": "HI",  "place": "Molokai",                 "tz": "Pacific/Honolulu" }, | ||||||
| 	{ "type":"wsr88d", "id":"PHWA", "lat":19.0950155, "lon":-155.5688846, "country":"USA", "state":"HI",  "place":"South Shore" }, | 	{ "type": "wsr88d", "id": "PHWA", "lat": 19.0950155, "lon": -155.5688846, "country": "USA", "state": "HI",  "place": "South Shore",             "tz": "Pacific/Honolulu" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDVN", "lat":41.611556,  "lon":-90.5809987,  "country":"USA", "state":"IA",  "place":"Davenport" }, | 	{ "type": "wsr88d", "id": "KDVN", "lat": 41.611556,  "lon": -90.5809987,  "country": "USA", "state": "IA",  "place": "Davenport",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDMX", "lat":41.7311788, "lon":-93.7229235,  "country":"USA", "state":"IA",  "place":"Des Moines" }, | 	{ "type": "wsr88d", "id": "KDMX", "lat": 41.7311788, "lon": -93.7229235,  "country": "USA", "state": "IA",  "place": "Des Moines",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCBX", "lat":43.4902104, "lon":-116.2360436, "country":"USA", "state":"ID",  "place":"Boise" }, | 	{ "type": "wsr88d", "id": "KCBX", "lat": 43.4902104, "lon": -116.2360436, "country": "USA", "state": "ID",  "place": "Boise",                   "tz": "America/Boise" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSFX", "lat":43.1055967, "lon":-112.6860487, "country":"USA", "state":"ID",  "place":"Pocatello/Idaho Falls" }, | 	{ "type": "wsr88d", "id": "KSFX", "lat": 43.1055967, "lon": -112.6860487, "country": "USA", "state": "ID",  "place": "Pocatello/Idaho Falls",   "tz": "America/Boise" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLOT", "lat":41.6044264, "lon":-88.084361,   "country":"USA", "state":"IL",  "place":"Chicago" }, | 	{ "type": "wsr88d", "id": "KLOT", "lat": 41.6044264, "lon": -88.084361,   "country": "USA", "state": "IL",  "place": "Chicago",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KILX", "lat":40.150544,  "lon":-89.336842,   "country":"USA", "state":"IL",  "place":"Lincoln" }, | 	{ "type": "wsr88d", "id": "KILX", "lat": 40.150544,  "lon": -89.336842,   "country": "USA", "state": "IL",  "place": "Lincoln",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KIND", "lat":39.7074962, "lon":-86.2803675,  "country":"USA", "state":"IN",  "place":"Indianapolis" }, | 	{ "type": "wsr88d", "id": "KIND", "lat": 39.7074962, "lon": -86.2803675,  "country": "USA", "state": "IN",  "place": "Indianapolis",            "tz": "America/Indiana/Indianapolis" }, | ||||||
| 	{ "type":"wsr88d", "id":"KIWX", "lat":41.3586356, "lon":-85.7000488,  "country":"USA", "state":"IN",  "place":"North Webster" }, | 	{ "type": "wsr88d", "id": "KIWX", "lat": 41.3586356, "lon": -85.7000488,  "country": "USA", "state": "IN",  "place": "North Webster",           "tz": "America/Indiana/Indianapolis" }, | ||||||
| 	{ "type":"wsr88d", "id":"KVWX", "lat":38.2603901, "lon":-87.7246553,  "country":"USA", "state":"IN",  "place":"Owensville (Evansville)" }, | 	{ "type": "wsr88d", "id": "KVWX", "lat": 38.2603901, "lon": -87.7246553,  "country": "USA", "state": "IN",  "place": "Owensville (Evansville)", "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDDC", "lat":37.7608043, "lon":-99.9688053,  "country":"USA", "state":"KS",  "place":"Dodge City" }, | 	{ "type": "wsr88d", "id": "KDDC", "lat": 37.7608043, "lon": -99.9688053,  "country": "USA", "state": "KS",  "place": "Dodge City",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGLD", "lat":39.3667737, "lon":-101.7004341, "country":"USA", "state":"KS",  "place":"Goodland" }, | 	{ "type": "wsr88d", "id": "KGLD", "lat": 39.3667737, "lon": -101.7004341, "country": "USA", "state": "KS",  "place": "Goodland",                "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTWX", "lat":38.996998,  "lon":-96.232618,   "country":"USA", "state":"KS",  "place":"Topeka" }, | 	{ "type": "wsr88d", "id": "KTWX", "lat": 38.996998,  "lon": -96.232618,   "country": "USA", "state": "KS",  "place": "Topeka",                  "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KICT", "lat":37.6545724, "lon":-97.4431461,  "country":"USA", "state":"KS",  "place":"Wichita" }, | 	{ "type": "wsr88d", "id": "KICT", "lat": 37.6545724, "lon": -97.4431461,  "country": "USA", "state": "KS",  "place": "Wichita",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHPX", "lat":36.7368894, "lon":-87.2854328,  "country":"USA", "state":"KY",  "place":"Fort Campbell" }, | 	{ "type": "wsr88d", "id": "KHPX", "lat": 36.7368894, "lon": -87.2854328,  "country": "USA", "state": "KY",  "place": "Fort Campbell",           "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KJKL", "lat":37.590762,  "lon":-83.313039,   "country":"USA", "state":"KY",  "place":"Jackson" }, | 	{ "type": "wsr88d", "id": "KJKL", "lat": 37.590762,  "lon": -83.313039,   "country": "USA", "state": "KY",  "place": "Jackson",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLVX", "lat":37.9753058, "lon":-85.9438455,  "country":"USA", "state":"KY",  "place":"Louisville" }, | 	{ "type": "wsr88d", "id": "KLVX", "lat": 37.9753058, "lon": -85.9438455,  "country": "USA", "state": "KY",  "place": "Louisville",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KPAH", "lat":37.0683618, "lon":-88.7720257,  "country":"USA", "state":"KY",  "place":"Paducah" }, | 	{ "type": "wsr88d", "id": "KPAH", "lat": 37.0683618, "lon": -88.7720257,  "country": "USA", "state": "KY",  "place": "Paducah",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KPOE", "lat":31.1556923, "lon":-92.9762596,  "country":"USA", "state":"LA",  "place":"Fort Polk" }, | 	{ "type": "wsr88d", "id": "KPOE", "lat": 31.1556923, "lon": -92.9762596,  "country": "USA", "state": "LA",  "place": "Fort Polk",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHDC", "lat":30.521667,  "lon":-90.418333,   "country":"USA", "state":"LA",  "place":"New Orleans (Hammond)" }, | 	{ "type": "wsr88d", "id": "KHDC", "lat": 30.521667,  "lon": -90.418333,   "country": "USA", "state": "LA",  "place": "New Orleans (Hammond)",   "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLCH", "lat":30.125382,  "lon":-93.2161188,  "country":"USA", "state":"LA",  "place":"Lake Charles" }, | 	{ "type": "wsr88d", "id": "KLCH", "lat": 30.125382,  "lon": -93.2161188,  "country": "USA", "state": "LA",  "place": "Lake Charles",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSHV", "lat":32.450813,  "lon":-93.8412774,  "country":"USA", "state":"LA",  "place":"Shreveport" }, | 	{ "type": "wsr88d", "id": "KSHV", "lat": 32.450813,  "lon": -93.8412774,  "country": "USA", "state": "LA",  "place": "Shreveport",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLIX", "lat":30.3367133, "lon":-89.8256618,  "country":"USA", "state":"LA",  "place":"New Orleans (Slidell)" }, | 	{ "type": "wsr88d", "id": "KLIX", "lat": 30.3367133, "lon": -89.8256618,  "country": "USA", "state": "LA",  "place": "New Orleans (Slidell)",   "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBOX", "lat":41.9558919, "lon":-71.1369681,  "country":"USA", "state":"MA",  "place":"Boston" }, | 	{ "type": "wsr88d", "id": "KBOX", "lat": 41.9558919, "lon": -71.1369681,  "country": "USA", "state": "MA",  "place": "Boston",                  "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGYX", "lat":43.8913555, "lon":-70.2565545,  "country":"USA", "state":"ME",  "place":"Gray/Portland" }, | 	{ "type": "wsr88d", "id": "KGYX", "lat": 43.8913555, "lon": -70.2565545,  "country": "USA", "state": "ME",  "place": "Gray/Portland",           "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCBW", "lat":46.0391944, "lon":-67.8066033,  "country":"USA", "state":"ME",  "place":"Houlton" }, | 	{ "type": "wsr88d", "id": "KCBW", "lat": 46.0391944, "lon": -67.8066033,  "country": "USA", "state": "ME",  "place": "Houlton",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDTX", "lat":42.6999677, "lon":-83.471809,   "country":"USA", "state":"MI",  "place":"Detroit/Pontiac" }, | 	{ "type": "wsr88d", "id": "KDTX", "lat": 42.6999677, "lon": -83.471809,   "country": "USA", "state": "MI",  "place": "Detroit/Pontiac",         "tz": "America/Detroit" }, | ||||||
| 	{ "type":"wsr88d", "id":"KAPX", "lat":44.907106,  "lon":-84.719817,   "country":"USA", "state":"MI",  "place":"Gaylord" }, | 	{ "type": "wsr88d", "id": "KAPX", "lat": 44.907106,  "lon": -84.719817,   "country": "USA", "state": "MI",  "place": "Gaylord",                 "tz": "America/Detroit" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGRR", "lat":42.893872,  "lon":-85.5449206,  "country":"USA", "state":"MI",  "place":"Grand Rapids" }, | 	{ "type": "wsr88d", "id": "KGRR", "lat": 42.893872,  "lon": -85.5449206,  "country": "USA", "state": "MI",  "place": "Grand Rapids",            "tz": "America/Detroit" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMQT", "lat":46.5311443, "lon":-87.5487131,  "country":"USA", "state":"MI",  "place":"Marquette" }, | 	{ "type": "wsr88d", "id": "KMQT", "lat": 46.5311443, "lon": -87.5487131,  "country": "USA", "state": "MI",  "place": "Marquette",               "tz": "America/Detroit" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDLH", "lat":46.8368569, "lon":-92.2097433,  "country":"USA", "state":"MN",  "place":"Duluth" }, | 	{ "type": "wsr88d", "id": "KDLH", "lat": 46.8368569, "lon": -92.2097433,  "country": "USA", "state": "MN",  "place": "Duluth",                  "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMPX", "lat":44.8488029, "lon":-93.5654873,  "country":"USA", "state":"MN",  "place":"Minneapolis/St. Paul" }, | 	{ "type": "wsr88d", "id": "KMPX", "lat": 44.8488029, "lon": -93.5654873,  "country": "USA", "state": "MN",  "place": "Minneapolis/St. Paul",    "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEAX", "lat":38.8102231, "lon":-94.2644924,  "country":"USA", "state":"MO",  "place":"Kansas City" }, | 	{ "type": "wsr88d", "id": "KEAX", "lat": 38.8102231, "lon": -94.2644924,  "country": "USA", "state": "MO",  "place": "Kansas City",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSGF", "lat":37.235223,  "lon":-93.4006011,  "country":"USA", "state":"MO",  "place":"Springfield" }, | 	{ "type": "wsr88d", "id": "KSGF", "lat": 37.235223,  "lon": -93.4006011,  "country": "USA", "state": "MO",  "place": "Springfield",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLSX", "lat":38.6986863, "lon":-90.682877,   "country":"USA", "state":"MO",  "place":"St. Louis" }, | 	{ "type": "wsr88d", "id": "KLSX", "lat": 38.6986863, "lon": -90.682877,   "country": "USA", "state": "MO",  "place": "St. Louis",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDGX", "lat":32.2797358, "lon":-89.9846309,  "country":"USA", "state":"MS",  "place":"Brandon/Jackson" }, | 	{ "type": "wsr88d", "id": "KDGX", "lat": 32.2797358, "lon": -89.9846309,  "country": "USA", "state": "MS",  "place": "Brandon/Jackson",         "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGWX", "lat":33.8967796, "lon":-88.3293915,  "country":"USA", "state":"MS",  "place":"Columbus AFB" }, | 	{ "type": "wsr88d", "id": "KGWX", "lat": 33.8967796, "lon": -88.3293915,  "country": "USA", "state": "MS",  "place": "Columbus AFB",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBLX", "lat":45.8537632, "lon":-108.6068165, "country":"USA", "state":"MT",  "place":"Billings" }, | 	{ "type": "wsr88d", "id": "KBLX", "lat": 45.8537632, "lon": -108.6068165, "country": "USA", "state": "MT",  "place": "Billings",                "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGGW", "lat":48.2064536, "lon":-106.6252971, "country":"USA", "state":"MT",  "place":"Glasgow" }, | 	{ "type": "wsr88d", "id": "KGGW", "lat": 48.2064536, "lon": -106.6252971, "country": "USA", "state": "MT",  "place": "Glasgow",                 "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTFX", "lat":47.4595023, "lon":-111.3855368, "country":"USA", "state":"MT",  "place":"Great Falls" }, | 	{ "type": "wsr88d", "id": "KTFX", "lat": 47.4595023, "lon": -111.3855368, "country": "USA", "state": "MT",  "place": "Great Falls",             "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMSX", "lat":47.0412971, "lon":-113.9864373, "country":"USA", "state":"MT",  "place":"Missoula" }, | 	{ "type": "wsr88d", "id": "KMSX", "lat": 47.0412971, "lon": -113.9864373, "country": "USA", "state": "MT",  "place": "Missoula",                "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMHX", "lat":34.7759313, "lon":-76.8762571,  "country":"USA", "state":"NC",  "place":"Morehead City" }, | 	{ "type": "wsr88d", "id": "KMHX", "lat": 34.7759313, "lon": -76.8762571,  "country": "USA", "state": "NC",  "place": "Morehead City",           "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KRAX", "lat":35.6654967, "lon":-78.4897855,  "country":"USA", "state":"NC",  "place":"Raleigh/Durham" }, | 	{ "type": "wsr88d", "id": "KRAX", "lat": 35.6654967, "lon": -78.4897855,  "country": "USA", "state": "NC",  "place": "Raleigh/Durham",          "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLTX", "lat":33.9891631, "lon":-78.4291059,  "country":"USA", "state":"NC",  "place":"Wilmington" }, | 	{ "type": "wsr88d", "id": "KLTX", "lat": 33.9891631, "lon": -78.4291059,  "country": "USA", "state": "NC",  "place": "Wilmington",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBIS", "lat":46.7709329, "lon":-100.7605532, "country":"USA", "state":"ND",  "place":"Bismarck" }, | 	{ "type": "wsr88d", "id": "KBIS", "lat": 46.7709329, "lon": -100.7605532, "country": "USA", "state": "ND",  "place": "Bismarck",                "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMVX", "lat":47.5279417, "lon":-97.3256654,  "country":"USA", "state":"ND",  "place":"Grand Forks (Mayville)" }, | 	{ "type": "wsr88d", "id": "KMVX", "lat": 47.5279417, "lon": -97.3256654,  "country": "USA", "state": "ND",  "place": "Grand Forks (Mayville)",  "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMBX", "lat":48.39303,   "lon":-100.8644378, "country":"USA", "state":"ND",  "place":"Minot AFB" }, | 	{ "type": "wsr88d", "id": "KMBX", "lat": 48.39303,   "lon": -100.8644378, "country": "USA", "state": "ND",  "place": "Minot AFB",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KUEX", "lat":40.320966,  "lon":-98.4418559,  "country":"USA", "state":"NE",  "place":"Grand Island/Hastings" }, | 	{ "type": "wsr88d", "id": "KUEX", "lat": 40.320966,  "lon": -98.4418559,  "country": "USA", "state": "NE",  "place": "Grand Island/Hastings",   "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLNX", "lat":41.9579623, "lon":-100.5759609, "country":"USA", "state":"NE",  "place":"North Platte" }, | 	{ "type": "wsr88d", "id": "KLNX", "lat": 41.9579623, "lon": -100.5759609, "country": "USA", "state": "NE",  "place": "North Platte",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KOAX", "lat":41.3202803, "lon":-96.3667971,  "country":"USA", "state":"NE",  "place":"Omaha" }, | 	{ "type": "wsr88d", "id": "KOAX", "lat": 41.3202803, "lon": -96.3667971,  "country": "USA", "state": "NE",  "place": "Omaha",                   "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KABX", "lat":35.1497579, "lon":-106.8239576, "country":"USA", "state":"NM",  "place":"Albuquerque" }, | 	{ "type": "wsr88d", "id": "KABX", "lat": 35.1497579, "lon": -106.8239576, "country": "USA", "state": "NM",  "place": "Albuquerque",             "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFDX", "lat":34.6341569, "lon":-103.6186427, "country":"USA", "state":"NM",  "place":"Cannon AFB" }, | 	{ "type": "wsr88d", "id": "KFDX", "lat": 34.6341569, "lon": -103.6186427, "country": "USA", "state": "NM",  "place": "Cannon AFB",              "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHDX", "lat":33.0768844, "lon":-106.1200923, "country":"USA", "state":"NM",  "place":"Holloman AFB" }, | 	{ "type": "wsr88d", "id": "KHDX", "lat": 33.0768844, "lon": -106.1200923, "country": "USA", "state": "NM",  "place": "Holloman AFB",            "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLRX", "lat":40.7396933, "lon":-116.8025529, "country":"USA", "state":"NV",  "place":"Elko" }, | 	{ "type": "wsr88d", "id": "KLRX", "lat": 40.7396933, "lon": -116.8025529, "country": "USA", "state": "NV",  "place": "Elko",                    "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KESX", "lat":35.7012894, "lon":-114.8918277, "country":"USA", "state":"NV",  "place":"Las Vegas" }, | 	{ "type": "wsr88d", "id": "KESX", "lat": 35.7012894, "lon": -114.8918277, "country": "USA", "state": "NV",  "place": "Las Vegas",               "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KRGX", "lat":39.7541931, "lon":-119.4620597, "country":"USA", "state":"NV",  "place":"Reno" }, | 	{ "type": "wsr88d", "id": "KRGX", "lat": 39.7541931, "lon": -119.4620597, "country": "USA", "state": "NV",  "place": "Reno",                    "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KENX", "lat":42.5865699, "lon":-74.0639877,  "country":"USA", "state":"NY",  "place":"Albany" }, | 	{ "type": "wsr88d", "id": "KENX", "lat": 42.5865699, "lon": -74.0639877,  "country": "USA", "state": "NY",  "place": "Albany",                  "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBGM", "lat":42.1997045, "lon":-75.9847015,  "country":"USA", "state":"NY",  "place":"Binghamton" }, | 	{ "type": "wsr88d", "id": "KBGM", "lat": 42.1997045, "lon": -75.9847015,  "country": "USA", "state": "NY",  "place": "Binghamton",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBUF", "lat":42.9488055, "lon":-78.7369108,  "country":"USA", "state":"NY",  "place":"Buffalo" }, | 	{ "type": "wsr88d", "id": "KBUF", "lat": 42.9488055, "lon": -78.7369108,  "country": "USA", "state": "NY",  "place": "Buffalo",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTYX", "lat":43.7556319, "lon":-75.6799918,  "country":"USA", "state":"NY",  "place":"Montague" }, | 	{ "type": "wsr88d", "id": "KTYX", "lat": 43.7556319, "lon": -75.6799918,  "country": "USA", "state": "NY",  "place": "Montague",                "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KOKX", "lat":40.8655093, "lon":-72.8638548,  "country":"USA", "state":"NY",  "place":"New York City" }, | 	{ "type": "wsr88d", "id": "KOKX", "lat": 40.8655093, "lon": -72.8638548,  "country": "USA", "state": "NY",  "place": "New York City",           "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCLE", "lat":41.4131875, "lon":-81.8597451,  "country":"USA", "state":"OH",  "place":"Cleveland" }, | 	{ "type": "wsr88d", "id": "KCLE", "lat": 41.4131875, "lon": -81.8597451,  "country": "USA", "state": "OH",  "place": "Cleveland",               "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KILN", "lat":39.42028,   "lon":-83.82167,    "country":"USA", "state":"OH",  "place":"Wilmington" }, | 	{ "type": "wsr88d", "id": "KILN", "lat": 39.42028,   "lon": -83.82167,    "country": "USA", "state": "OH",  "place": "Wilmington",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFDR", "lat":34.3620014, "lon":-98.9766884,  "country":"USA", "state":"OK",  "place":"Frederick" }, | 	{ "type": "wsr88d", "id": "KFDR", "lat": 34.3620014, "lon": -98.9766884,  "country": "USA", "state": "OK",  "place": "Frederick",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KTLX", "lat":35.3333873, "lon":-97.2778255,  "country":"USA", "state":"OK",  "place":"Oklahoma City" }, | 	{ "type": "wsr88d", "id": "KTLX", "lat": 35.3333873, "lon": -97.2778255,  "country": "USA", "state": "OK",  "place": "Oklahoma City",           "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KINX", "lat":36.1750977, "lon":-95.5642802,  "country":"USA", "state":"OK",  "place":"Tulsa" }, | 	{ "type": "wsr88d", "id": "KINX", "lat": 36.1750977, "lon": -95.5642802,  "country": "USA", "state": "OK",  "place": "Tulsa",                   "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KVNX", "lat":36.7406166, "lon":-98.1279409,  "country":"USA", "state":"OK",  "place":"Vance AFB" }, | 	{ "type": "wsr88d", "id": "KVNX", "lat": 36.7406166, "lon": -98.1279409,  "country": "USA", "state": "OK",  "place": "Vance AFB",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMAX", "lat":42.0810766, "lon":-122.7173334, "country":"USA", "state":"OR",  "place":"Medford" }, | 	{ "type": "wsr88d", "id": "KMAX", "lat": 42.0810766, "lon": -122.7173334, "country": "USA", "state": "OR",  "place": "Medford",                 "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KPDT", "lat":45.6906118, "lon":-118.8529301, "country":"USA", "state":"OR",  "place":"Pendleton" }, | 	{ "type": "wsr88d", "id": "KPDT", "lat": 45.6906118, "lon": -118.8529301, "country": "USA", "state": "OR",  "place": "Pendleton",               "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KRTX", "lat":45.7150308, "lon":-122.9650542, "country":"USA", "state":"OR",  "place":"Portland" }, | 	{ "type": "wsr88d", "id": "KRTX", "lat": 45.7150308, "lon": -122.9650542, "country": "USA", "state": "OR",  "place": "Portland",                "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDIX", "lat":39.9470885, "lon":-74.4108027,  "country":"USA", "state":"PA",  "place":"Philadelphia" }, | 	{ "type": "wsr88d", "id": "KDIX", "lat": 39.9470885, "lon": -74.4108027,  "country": "USA", "state": "PA",  "place": "Philadelphia",            "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KPBZ", "lat":40.5316842, "lon":-80.2179515,  "country":"USA", "state":"PA",  "place":"Pittsburgh" }, | 	{ "type": "wsr88d", "id": "KPBZ", "lat": 40.5316842, "lon": -80.2179515,  "country": "USA", "state": "PA",  "place": "Pittsburgh",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCCX", "lat":40.9228521, "lon":-78.0038738,  "country":"USA", "state":"PA",  "place":"State College" }, | 	{ "type": "wsr88d", "id": "KCCX", "lat": 40.9228521, "lon": -78.0038738,  "country": "USA", "state": "PA",  "place": "State College",           "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"TJUA", "lat":18.1155998, "lon":-66.0780644,  "country":"USA", "state":"PR",  "place":"San Juan" }, | 	{ "type": "wsr88d", "id": "TJUA", "lat": 18.1155998, "lon": -66.0780644,  "country": "USA", "state": "PR",  "place": "San Juan",                "tz": "America/Puerto_Rico" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCLX", "lat":32.6554866, "lon":-81.0423124,  "country":"USA", "state":"SC",  "place":"Charleston" }, | 	{ "type": "wsr88d", "id": "KCLX", "lat": 32.6554866, "lon": -81.0423124,  "country": "USA", "state": "SC",  "place": "Charleston",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCAE", "lat":33.9487579, "lon":-81.1184281,  "country":"USA", "state":"SC",  "place":"Columbia" }, | 	{ "type": "wsr88d", "id": "KCAE", "lat": 33.9487579, "lon": -81.1184281,  "country": "USA", "state": "SC",  "place": "Columbia",                "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGSP", "lat":34.8833435, "lon":-82.2200757,  "country":"USA", "state":"SC",  "place":"Greer" }, | 	{ "type": "wsr88d", "id": "KGSP", "lat": 34.8833435, "lon": -82.2200757,  "country": "USA", "state": "SC",  "place": "Greer",                   "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KABR", "lat":45.4558185, "lon":-98.4132046,  "country":"USA", "state":"SD",  "place":"Aberdeen" }, | 	{ "type": "wsr88d", "id": "KABR", "lat": 45.4558185, "lon": -98.4132046,  "country": "USA", "state": "SD",  "place": "Aberdeen",                "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KUDX", "lat":44.1248485, "lon":-102.8298157, "country":"USA", "state":"SD",  "place":"Rapid City" }, | 	{ "type": "wsr88d", "id": "KUDX", "lat": 44.1248485, "lon": -102.8298157, "country": "USA", "state": "SD",  "place": "Rapid City",              "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFSD", "lat":43.5877467, "lon":-96.7293674,  "country":"USA", "state":"SD",  "place":"Sioux Falls" }, | 	{ "type": "wsr88d", "id": "KFSD", "lat": 43.5877467, "lon": -96.7293674,  "country": "USA", "state": "SD",  "place": "Sioux Falls",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMRX", "lat":36.168538,  "lon":-83.401779,   "country":"USA", "state":"TN",  "place":"Knoxville/Tri Cities" }, | 	{ "type": "wsr88d", "id": "KMRX", "lat": 36.168538,  "lon": -83.401779,   "country": "USA", "state": "TN",  "place": "Knoxville/Tri Cities",    "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KNQA", "lat":35.3447802, "lon":-89.8734534,  "country":"USA", "state":"TN",  "place":"Memphis" }, | 	{ "type": "wsr88d", "id": "KNQA", "lat": 35.3447802, "lon": -89.8734534,  "country": "USA", "state": "TN",  "place": "Memphis",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KOHX", "lat":36.2472389, "lon":-86.5625185,  "country":"USA", "state":"TN",  "place":"Nashville" }, | 	{ "type": "wsr88d", "id": "KOHX", "lat": 36.2472389, "lon": -86.5625185,  "country": "USA", "state": "TN",  "place": "Nashville",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KAMA", "lat":35.2334827, "lon":-101.7092478, "country":"USA", "state":"TX",  "place":"Amarillo" }, | 	{ "type": "wsr88d", "id": "KAMA", "lat": 35.2334827, "lon": -101.7092478, "country": "USA", "state": "TX",  "place": "Amarillo",                "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEWX", "lat":29.7039802, "lon":-98.028506,   "country":"USA", "state":"TX",  "place":"Austin/San Antonio" }, | 	{ "type": "wsr88d", "id": "KEWX", "lat": 29.7039802, "lon": -98.028506,   "country": "USA", "state": "TX",  "place": "Austin/San Antonio",      "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KBRO", "lat":25.9159979, "lon":-97.4189526,  "country":"USA", "state":"TX",  "place":"Brownsville" }, | 	{ "type": "wsr88d", "id": "KBRO", "lat": 25.9159979, "lon": -97.4189526,  "country": "USA", "state": "TX",  "place": "Brownsville",             "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCRP", "lat":27.7840203, "lon":-97.511234,   "country":"USA", "state":"TX",  "place":"Corpus Christi" }, | 	{ "type": "wsr88d", "id": "KCRP", "lat": 27.7840203, "lon": -97.511234,   "country": "USA", "state": "TX",  "place": "Corpus Christi",          "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFWS", "lat":32.5730186, "lon":-97.3031911,  "country":"USA", "state":"TX",  "place":"Dallas/Ft. Worth" }, | 	{ "type": "wsr88d", "id": "KFWS", "lat": 32.5730186, "lon": -97.3031911,  "country": "USA", "state": "TX",  "place": "Dallas/Ft. Worth",        "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDYX", "lat":32.5386009, "lon":-99.2542863,  "country":"USA", "state":"TX",  "place":"Dyess AFB" }, | 	{ "type": "wsr88d", "id": "KDYX", "lat": 32.5386009, "lon": -99.2542863,  "country": "USA", "state": "TX",  "place": "Dyess AFB",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KEPZ", "lat":31.8731115, "lon":-106.697942,  "country":"USA", "state":"TX",  "place":"El Paso" }, | 	{ "type": "wsr88d", "id": "KEPZ", "lat": 31.8731115, "lon": -106.697942,  "country": "USA", "state": "TX",  "place": "El Paso",                 "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGRK", "lat":30.7217637, "lon":-97.3829627,  "country":"USA", "state":"TX",  "place":"Fort Hood" }, | 	{ "type": "wsr88d", "id": "KGRK", "lat": 30.7217637, "lon": -97.3829627,  "country": "USA", "state": "TX",  "place": "Fort Hood",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KHGX", "lat":29.4718835, "lon":-95.0788593,  "country":"USA", "state":"TX",  "place":"Houston/Galveston" }, | 	{ "type": "wsr88d", "id": "KHGX", "lat": 29.4718835, "lon": -95.0788593,  "country": "USA", "state": "TX",  "place": "Houston/Galveston",       "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KDFX", "lat":29.2730823, "lon":-100.2802312, "country":"USA", "state":"TX",  "place":"Laughlin AFB" }, | 	{ "type": "wsr88d", "id": "KDFX", "lat": 29.2730823, "lon": -100.2802312, "country": "USA", "state": "TX",  "place": "Laughlin AFB",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLBB", "lat":33.6541242, "lon":-101.814149,  "country":"USA", "state":"TX",  "place":"Lubbock" }, | 	{ "type": "wsr88d", "id": "KLBB", "lat": 33.6541242, "lon": -101.814149,  "country": "USA", "state": "TX",  "place": "Lubbock",                 "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMAF", "lat":31.9433953, "lon":-102.1894383, "country":"USA", "state":"TX",  "place":"Midland/Odessa" }, | 	{ "type": "wsr88d", "id": "KMAF", "lat": 31.9433953, "lon": -102.1894383, "country": "USA", "state": "TX",  "place": "Midland/Odessa",          "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KSJT", "lat":31.3712815, "lon":-100.4925227, "country":"USA", "state":"TX",  "place":"San Angelo" }, | 	{ "type": "wsr88d", "id": "KSJT", "lat": 31.3712815, "lon": -100.4925227, "country": "USA", "state": "TX",  "place": "San Angelo",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KICX", "lat":37.59083,   "lon":-112.86222,   "country":"USA", "state":"UT",  "place":"Cedar City" }, | 	{ "type": "wsr88d", "id": "KICX", "lat": 37.59083,   "lon": -112.86222,   "country": "USA", "state": "UT",  "place": "Cedar City",              "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMTX", "lat":41.2627795, "lon":-112.4480081, "country":"USA", "state":"UT",  "place":"Salt Lake City" }, | 	{ "type": "wsr88d", "id": "KMTX", "lat": 41.2627795, "lon": -112.4480081, "country": "USA", "state": "UT",  "place": "Salt Lake City",          "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KAKQ", "lat":36.9840475, "lon":-77.007342,   "country":"USA", "state":"VA",  "place":"Norfolk/Richmond" }, | 	{ "type": "wsr88d", "id": "KAKQ", "lat": 36.9840475, "lon": -77.007342,   "country": "USA", "state": "VA",  "place": "Norfolk/Richmond",        "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KFCX", "lat":37.0242098, "lon":-80.2736664,  "country":"USA", "state":"VA",  "place":"Roanoke" }, | 	{ "type": "wsr88d", "id": "KFCX", "lat": 37.0242098, "lon": -80.2736664,  "country": "USA", "state": "VA",  "place": "Roanoke",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLWX", "lat":38.9753957, "lon":-77.4778444,  "country":"USA", "state":"VA",  "place":"Sterling" }, | 	{ "type": "wsr88d", "id": "KLWX", "lat": 38.9753957, "lon": -77.4778444,  "country": "USA", "state": "VA",  "place": "Sterling",                "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCXX", "lat":44.5109941, "lon":-73.166424,   "country":"USA", "state":"VT",  "place":"Burlington" }, | 	{ "type": "wsr88d", "id": "KCXX", "lat": 44.5109941, "lon": -73.166424,   "country": "USA", "state": "VT",  "place": "Burlington",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KLGX", "lat":47.116806,  "lon":-124.10625,   "country":"USA", "state":"WA",  "place":"Langley Hill" }, | 	{ "type": "wsr88d", "id": "KLGX", "lat": 47.116806,  "lon": -124.10625,   "country": "USA", "state": "WA",  "place": "Langley Hill",            "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KATX", "lat":48.1945614, "lon":-122.4957508, "country":"USA", "state":"WA",  "place":"Seattle/Tacoma" }, | 	{ "type": "wsr88d", "id": "KATX", "lat": 48.1945614, "lon": -122.4957508, "country": "USA", "state": "WA",  "place": "Seattle/Tacoma",          "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KOTX", "lat":47.6803744, "lon":-117.6267797, "country":"USA", "state":"WA",  "place":"Spokane" }, | 	{ "type": "wsr88d", "id": "KOTX", "lat": 47.6803744, "lon": -117.6267797, "country": "USA", "state": "WA",  "place": "Spokane",                 "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"wsr88d", "id":"KGRB", "lat":44.4984644, "lon":-88.111124,   "country":"USA", "state":"WI",  "place":"Green Bay" }, | 	{ "type": "wsr88d", "id": "KGRB", "lat": 44.4984644, "lon": -88.111124,   "country": "USA", "state": "WI",  "place": "Green Bay",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KARX", "lat":43.822766,  "lon":-91.1915767,  "country":"USA", "state":"WI",  "place":"La Crosse" }, | 	{ "type": "wsr88d", "id": "KARX", "lat": 43.822766,  "lon": -91.1915767,  "country": "USA", "state": "WI",  "place": "La Crosse",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KMKX", "lat":42.9678286, "lon":-88.5506335,  "country":"USA", "state":"WI",  "place":"Milwaukee" }, | 	{ "type": "wsr88d", "id": "KMKX", "lat": 42.9678286, "lon": -88.5506335,  "country": "USA", "state": "WI",  "place": "Milwaukee",               "tz": "America/Chicago" }, | ||||||
| 	{ "type":"wsr88d", "id":"KRLX", "lat":38.3110763, "lon":-81.7229015,  "country":"USA", "state":"WV",  "place":"Charleston" }, | 	{ "type": "wsr88d", "id": "KRLX", "lat": 38.3110763, "lon": -81.7229015,  "country": "USA", "state": "WV",  "place": "Charleston",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"wsr88d", "id":"KCYS", "lat":41.1519308, "lon":-104.8060325, "country":"USA", "state":"WY",  "place":"Cheyenne" }, | 	{ "type": "wsr88d", "id": "KCYS", "lat": 41.1519308, "lon": -104.8060325, "country": "USA", "state": "WY",  "place": "Cheyenne",                "tz": "America/Denver" }, | ||||||
| 	{ "type":"wsr88d", "id":"KRIW", "lat":43.0660779, "lon":-108.4773731, "country":"USA", "state":"WY",  "place":"Riverton" }, | 	{ "type": "wsr88d", "id": "KRIW", "lat": 43.0660779, "lon": -108.4773731, "country": "USA", "state": "WY",  "place": "Riverton",                "tz": "America/Denver" }, | ||||||
| 
 | 
 | ||||||
| 	{ "type":"tdwr", "id":"TADW", "lat":38.695, "lon":-76.845,  "country":"USA", "state":"MD", "place":"Andrews Air Force Base" }, | 	{ "type": "tdwr", "id": "TADW", "lat": 38.695, "lon": -76.845,  "country": "USA", "state": "MD", "place": "Andrews Air Force Base", "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TATL", "lat":33.647, "lon":-84.262,  "country":"USA", "state":"GA", "place":"Atlanta" }, | 	{ "type": "tdwr", "id": "TATL", "lat": 33.647, "lon": -84.262,  "country": "USA", "state": "GA", "place": "Atlanta",                "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TBNA", "lat":35.98,  "lon":-86.662,  "country":"USA", "state":"TN", "place":"Nashville" }, | 	{ "type": "tdwr", "id": "TBNA", "lat": 35.98,  "lon": -86.662,  "country": "USA", "state": "TN", "place": "Nashville",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TBOS", "lat":42.158, "lon":-70.933,  "country":"USA", "state":"MA", "place":"Boston" }, | 	{ "type": "tdwr", "id": "TBOS", "lat": 42.158, "lon": -70.933,  "country": "USA", "state": "MA", "place": "Boston",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TBWI", "lat":39.09,  "lon":-76.63,   "country":"USA", "state":"MD", "place":"Baltimore/Wash" }, | 	{ "type": "tdwr", "id": "TBWI", "lat": 39.09,  "lon": -76.63,   "country": "USA", "state": "MD", "place": "Baltimore/Wash",         "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TCLT", "lat":35.337, "lon":-80.885,  "country":"USA", "state":"NC", "place":"Charlotte" }, | 	{ "type": "tdwr", "id": "TCLT", "lat": 35.337, "lon": -80.885,  "country": "USA", "state": "NC", "place": "Charlotte",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TCMH", "lat":40.006, "lon":-82.715,  "country":"USA", "state":"OH", "place":"Columbus" }, | 	{ "type": "tdwr", "id": "TCMH", "lat": 40.006, "lon": -82.715,  "country": "USA", "state": "OH", "place": "Columbus",               "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TCVG", "lat":38.898, "lon":-84.58,   "country":"USA", "state":"OH", "place":"Cincinnati" }, | 	{ "type": "tdwr", "id": "TCVG", "lat": 38.898, "lon": -84.58,   "country": "USA", "state": "OH", "place": "Cincinnati",             "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TDAL", "lat":32.926, "lon":-96.968,  "country":"USA", "state":"TX", "place":"Dallas Love Field" }, | 	{ "type": "tdwr", "id": "TDAL", "lat": 32.926, "lon": -96.968,  "country": "USA", "state": "TX", "place": "Dallas Love Field",      "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TDAY", "lat":40.022, "lon":-84.123,  "country":"USA", "state":"OH", "place":"Dayton" }, | 	{ "type": "tdwr", "id": "TDAY", "lat": 40.022, "lon": -84.123,  "country": "USA", "state": "OH", "place": "Dayton",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TDCA", "lat":38.759, "lon":-76.962,  "country":"USA", "state":"MD", "place":"Washington National" }, | 	{ "type": "tdwr", "id": "TDCA", "lat": 38.759, "lon": -76.962,  "country": "USA", "state": "MD", "place": "Washington National",    "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TDEN", "lat":39.728, "lon":-104.526, "country":"USA", "state":"CO", "place":"Denver" }, | 	{ "type": "tdwr", "id": "TDEN", "lat": 39.728, "lon": -104.526, "country": "USA", "state": "CO", "place": "Denver",                 "tz": "America/Denver" }, | ||||||
| 	{ "type":"tdwr", "id":"TDFW", "lat":33.065, "lon":-96.918,  "country":"USA", "state":"TX", "place":"Dallas/Ft. Worth" }, | 	{ "type": "tdwr", "id": "TDFW", "lat": 33.065, "lon": -96.918,  "country": "USA", "state": "TX", "place": "Dallas/Ft. Worth",       "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TDTW", "lat":42.111, "lon":-83.515,  "country":"USA", "state":"MI", "place":"Detroit" }, | 	{ "type": "tdwr", "id": "TDTW", "lat": 42.111, "lon": -83.515,  "country": "USA", "state": "MI", "place": "Detroit",                "tz": "America/Detroit" }, | ||||||
| 	{ "type":"tdwr", "id":"TEWR", "lat":40.593, "lon":-74.27,   "country":"USA", "state":"NJ", "place":"Newark" }, | 	{ "type": "tdwr", "id": "TEWR", "lat": 40.593, "lon": -74.27,   "country": "USA", "state": "NJ", "place": "Newark",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TFLL", "lat":26.143, "lon":-80.344,  "country":"USA", "state":"FL", "place":"Fort Lauderdale" }, | 	{ "type": "tdwr", "id": "TFLL", "lat": 26.143, "lon": -80.344,  "country": "USA", "state": "FL", "place": "Fort Lauderdale",        "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"THOU", "lat":29.516, "lon":-95.242,  "country":"USA", "state":"TX", "place":"Houston Hobby" }, | 	{ "type": "tdwr", "id": "THOU", "lat": 29.516, "lon": -95.242,  "country": "USA", "state": "TX", "place": "Houston Hobby",          "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TIAD", "lat":39.084, "lon":-77.529,  "country":"USA", "state":"VA", "place":"Dulles" }, | 	{ "type": "tdwr", "id": "TIAD", "lat": 39.084, "lon": -77.529,  "country": "USA", "state": "VA", "place": "Dulles",                 "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TIAH", "lat":30.065, "lon":-95.567,  "country":"USA", "state":"TX", "place":"Houston International" }, | 	{ "type": "tdwr", "id": "TIAH", "lat": 30.065, "lon": -95.567,  "country": "USA", "state": "TX", "place": "Houston International",  "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TICH", "lat":37.507, "lon":-97.437,  "country":"USA", "state":"KS", "place":"Wichita" }, | 	{ "type": "tdwr", "id": "TICH", "lat": 37.507, "lon": -97.437,  "country": "USA", "state": "KS", "place": "Wichita",                "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TIDS", "lat":39.637, "lon":-86.436,  "country":"USA", "state":"IN", "place":"Indianapolis" }, | 	{ "type": "tdwr", "id": "TIDS", "lat": 39.637, "lon": -86.436,  "country": "USA", "state": "IN", "place": "Indianapolis",           "tz": "America/Indiana/Indianapolis" }, | ||||||
| 	{ "type":"tdwr", "id":"TJFK", "lat":40.589, "lon":-73.881,  "country":"USA", "state":"NY", "place":"New York City" }, | 	{ "type": "tdwr", "id": "TJFK", "lat": 40.589, "lon": -73.881,  "country": "USA", "state": "NY", "place": "New York City",          "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TLAS", "lat":36.144, "lon":-115.007, "country":"USA", "state":"NV", "place":"Las Vegas" }, | 	{ "type": "tdwr", "id": "TLAS", "lat": 36.144, "lon": -115.007, "country": "USA", "state": "NV", "place": "Las Vegas",              "tz": "America/Los_Angeles" }, | ||||||
| 	{ "type":"tdwr", "id":"TLVE", "lat":41.29,  "lon":-82.008,  "country":"USA", "state":"OH", "place":"Cleveland" }, | 	{ "type": "tdwr", "id": "TLVE", "lat": 41.29,  "lon": -82.008,  "country": "USA", "state": "OH", "place": "Cleveland",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TMCI", "lat":39.498, "lon":-94.742,  "country":"USA", "state":"MO", "place":"Kansas City" }, | 	{ "type": "tdwr", "id": "TMCI", "lat": 39.498, "lon": -94.742,  "country": "USA", "state": "MO", "place": "Kansas City",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TMCO", "lat":28.344, "lon":-81.326,  "country":"USA", "state":"FL", "place":"Orlando International" }, | 	{ "type": "tdwr", "id": "TMCO", "lat": 28.344, "lon": -81.326,  "country": "USA", "state": "FL", "place": "Orlando International",  "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TMDW", "lat":41.651, "lon":-87.73,   "country":"USA", "state":"IL", "place":"Chicago Midway" }, | 	{ "type": "tdwr", "id": "TMDW", "lat": 41.651, "lon": -87.73,   "country": "USA", "state": "IL", "place": "Chicago Midway",         "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TMEM", "lat":34.896, "lon":-89.993,  "country":"USA", "state":"TN", "place":"Memphis" }, | 	{ "type": "tdwr", "id": "TMEM", "lat": 34.896, "lon": -89.993,  "country": "USA", "state": "TN", "place": "Memphis",                "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TMIA", "lat":25.758, "lon":-80.491,  "country":"USA", "state":"FL", "place":"Miami" }, | 	{ "type": "tdwr", "id": "TMIA", "lat": 25.758, "lon": -80.491,  "country": "USA", "state": "FL", "place": "Miami",                  "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TMKE", "lat":42.819, "lon":-88.046,  "country":"USA", "state":"WI", "place":"Milwaukee" }, | 	{ "type": "tdwr", "id": "TMKE", "lat": 42.819, "lon": -88.046,  "country": "USA", "state": "WI", "place": "Milwaukee",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TMSP", "lat":44.871, "lon":-92.933,  "country":"USA", "state":"MN", "place":"Minneapolis" }, | 	{ "type": "tdwr", "id": "TMSP", "lat": 44.871, "lon": -92.933,  "country": "USA", "state": "MN", "place": "Minneapolis",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TMSY", "lat":30.022, "lon":-90.403,  "country":"USA", "state":"LA", "place":"New Orleans" }, | 	{ "type": "tdwr", "id": "TMSY", "lat": 30.022, "lon": -90.403,  "country": "USA", "state": "LA", "place": "New Orleans",            "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TOKC", "lat":35.276, "lon":-97.51,   "country":"USA", "state":"OK", "place":"Oklahoma City" }, | 	{ "type": "tdwr", "id": "TOKC", "lat": 35.276, "lon": -97.51,   "country": "USA", "state": "OK", "place": "Oklahoma City",          "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TORD", "lat":41.797, "lon":-87.858,  "country":"USA", "state":"IL", "place":"Chicago O'Hare" }, | 	{ "type": "tdwr", "id": "TORD", "lat": 41.797, "lon": -87.858,  "country": "USA", "state": "IL", "place": "Chicago O'Hare",         "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TPBI", "lat":26.688, "lon":-80.273,  "country":"USA", "state":"FL", "place":"West Palm Beach" }, | 	{ "type": "tdwr", "id": "TPBI", "lat": 26.688, "lon": -80.273,  "country": "USA", "state": "FL", "place": "West Palm Beach",        "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TPHL", "lat":39.949, "lon":-75.069,  "country":"USA", "state":"PA", "place":"Philadelphia" }, | 	{ "type": "tdwr", "id": "TPHL", "lat": 39.949, "lon": -75.069,  "country": "USA", "state": "PA", "place": "Philadelphia",           "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TPHX", "lat":33.421, "lon":-112.163, "country":"USA", "state":"AZ", "place":"Phoenix" }, | 	{ "type": "tdwr", "id": "TPHX", "lat": 33.421, "lon": -112.163, "country": "USA", "state": "AZ", "place": "Phoenix",                "tz": "America/Phoenix" }, | ||||||
| 	{ "type":"tdwr", "id":"TPIT", "lat":40.501, "lon":-80.486,  "country":"USA", "state":"PA", "place":"Pittsburgh" }, | 	{ "type": "tdwr", "id": "TPIT", "lat": 40.501, "lon": -80.486,  "country": "USA", "state": "PA", "place": "Pittsburgh",             "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TRDU", "lat":36.002, "lon":-78.697,  "country":"USA", "state":"NC", "place":"Raleigh Durham" }, | 	{ "type": "tdwr", "id": "TRDU", "lat": 36.002, "lon": -78.697,  "country": "USA", "state": "NC", "place": "Raleigh Durham",         "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TSDF", "lat":38.046, "lon":-85.61,   "country":"USA", "state":"KY", "place":"Louisville" }, | 	{ "type": "tdwr", "id": "TSDF", "lat": 38.046, "lon": -85.61,   "country": "USA", "state": "KY", "place": "Louisville",             "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TSJU", "lat":18.474, "lon":-66.179,  "country":"USA", "state":"PR", "place":"San Juan" }, | 	{ "type": "tdwr", "id": "TSJU", "lat": 18.474, "lon": -66.179,  "country": "USA", "state": "PR", "place": "San Juan",               "tz": "America/Puerto_Rico" }, | ||||||
| 	{ "type":"tdwr", "id":"TSLC", "lat":40.967, "lon":-111.93,  "country":"USA", "state":"UT", "place":"Salt Lake City" }, | 	{ "type": "tdwr", "id": "TSLC", "lat": 40.967, "lon": -111.93,  "country": "USA", "state": "UT", "place": "Salt Lake City",         "tz": "America/Denver" }, | ||||||
| 	{ "type":"tdwr", "id":"TSTL", "lat":38.805, "lon":-90.489,  "country":"USA", "state":"MO", "place":"St. Louis" }, | 	{ "type": "tdwr", "id": "TSTL", "lat": 38.805, "lon": -90.489,  "country": "USA", "state": "MO", "place": "St. Louis",              "tz": "America/Chicago" }, | ||||||
| 	{ "type":"tdwr", "id":"TTPA", "lat":27.86,  "lon":-82.518,  "country":"USA", "state":"FL", "place":"Tampa Bay" }, | 	{ "type": "tdwr", "id": "TTPA", "lat": 27.86,  "lon": -82.518,  "country": "USA", "state": "FL", "place": "Tampa Bay",              "tz": "America/New_York" }, | ||||||
| 	{ "type":"tdwr", "id":"TTUL", "lat":36.071, "lon":-95.827,  "country":"USA", "state":"OK", "place":"Tulsa" } | 	{ "type": "tdwr", "id": "TTUL", "lat": 36.071, "lon": -95.827,  "country": "USA", "state": "OK", "place": "Tulsa",                  "tz": "America/Chicago" } | ||||||
| ] | ] | ||||||
|  | @ -201,7 +201,8 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp | ||||||
|               source/scwx/qt/types/radar_product_record.hpp |               source/scwx/qt/types/radar_product_record.hpp | ||||||
|               source/scwx/qt/types/text_event_key.hpp |               source/scwx/qt/types/text_event_key.hpp | ||||||
|               source/scwx/qt/types/text_types.hpp |               source/scwx/qt/types/text_types.hpp | ||||||
|               source/scwx/qt/types/texture_types.hpp) |               source/scwx/qt/types/texture_types.hpp | ||||||
|  |               source/scwx/qt/types/time_types.hpp) | ||||||
| set(SRC_TYPES source/scwx/qt/types/alert_types.cpp | set(SRC_TYPES source/scwx/qt/types/alert_types.cpp | ||||||
|               source/scwx/qt/types/github_types.cpp |               source/scwx/qt/types/github_types.cpp | ||||||
|               source/scwx/qt/types/icon_types.cpp |               source/scwx/qt/types/icon_types.cpp | ||||||
|  | @ -214,7 +215,8 @@ set(SRC_TYPES source/scwx/qt/types/alert_types.cpp | ||||||
|               source/scwx/qt/types/radar_product_record.cpp |               source/scwx/qt/types/radar_product_record.cpp | ||||||
|               source/scwx/qt/types/text_event_key.cpp |               source/scwx/qt/types/text_event_key.cpp | ||||||
|               source/scwx/qt/types/text_types.cpp |               source/scwx/qt/types/text_types.cpp | ||||||
|               source/scwx/qt/types/texture_types.cpp) |               source/scwx/qt/types/texture_types.cpp | ||||||
|  |               source/scwx/qt/types/time_types.cpp) | ||||||
| set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | ||||||
|            source/scwx/qt/ui/alert_dialog.hpp |            source/scwx/qt/ui/alert_dialog.hpp | ||||||
|            source/scwx/qt/ui/alert_dock_widget.hpp |            source/scwx/qt/ui/alert_dock_widget.hpp | ||||||
|  |  | ||||||
|  | @ -4,11 +4,16 @@ | ||||||
| #include <scwx/common/sites.hpp> | #include <scwx/common/sites.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <chrono> | ||||||
| #include <shared_mutex> | #include <shared_mutex> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| 
 | 
 | ||||||
| #include <boost/json.hpp> | #include <boost/json.hpp> | ||||||
| 
 | 
 | ||||||
|  | #if !defined(_MSC_VER) | ||||||
|  | #   include <date/date.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
| namespace qt | namespace qt | ||||||
|  | @ -35,26 +40,19 @@ static bool ValidateJsonEntry(const boost::json::object& o); | ||||||
| class RadarSiteImpl | class RadarSiteImpl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit RadarSiteImpl() : |    explicit RadarSiteImpl() {} | ||||||
|        type_ {}, |  | ||||||
|        id_ {}, |  | ||||||
|        latitude_ {0.0}, |  | ||||||
|        longitude_ {0.0}, |  | ||||||
|        country_ {}, |  | ||||||
|        state_ {}, |  | ||||||
|        place_ {} |  | ||||||
|    { |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    ~RadarSiteImpl() {} |    ~RadarSiteImpl() {} | ||||||
| 
 | 
 | ||||||
|    std::string type_; |    std::string type_ {}; | ||||||
|    std::string id_; |    std::string id_ {}; | ||||||
|    double      latitude_; |    double      latitude_ {0.0}; | ||||||
|    double      longitude_; |    double      longitude_ {0.0}; | ||||||
|    std::string country_; |    std::string country_ {}; | ||||||
|    std::string state_; |    std::string state_ {}; | ||||||
|    std::string place_; |    std::string place_ {}; | ||||||
|  |    std::string tzName_ {}; | ||||||
|  | 
 | ||||||
|  |    const scwx::util::time_zone* timeZone_ {nullptr}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RadarSite::RadarSite() : p(std::make_unique<RadarSiteImpl>()) {} | RadarSite::RadarSite() : p(std::make_unique<RadarSiteImpl>()) {} | ||||||
|  | @ -134,6 +132,16 @@ std::string RadarSite::location_name() const | ||||||
|    return locationName; |    return locationName; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::string RadarSite::tz_name() const | ||||||
|  | { | ||||||
|  |    return p->tzName_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const scwx::util::time_zone* RadarSite::time_zone() const | ||||||
|  | { | ||||||
|  |    return p->timeZone_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id) | std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id) | ||||||
| { | { | ||||||
|    std::shared_lock           lock(siteMutex_); |    std::shared_lock           lock(siteMutex_); | ||||||
|  | @ -259,6 +267,23 @@ size_t RadarSite::ReadConfig(const std::string& path) | ||||||
|                boost::json::value_to<std::string>(o.at("country")); |                boost::json::value_to<std::string>(o.at("country")); | ||||||
|             site->p->state_ = boost::json::value_to<std::string>(o.at("state")); |             site->p->state_ = boost::json::value_to<std::string>(o.at("state")); | ||||||
|             site->p->place_ = boost::json::value_to<std::string>(o.at("place")); |             site->p->place_ = boost::json::value_to<std::string>(o.at("place")); | ||||||
|  |             site->p->tzName_ = boost::json::value_to<std::string>(o.at("tz")); | ||||||
|  | 
 | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  | #if defined(_MSC_VER) | ||||||
|  |                using namespace std::chrono; | ||||||
|  | #else | ||||||
|  |                using namespace date; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |                site->p->timeZone_ = get_tzdb().locate_zone(site->p->tzName_); | ||||||
|  |             } | ||||||
|  |             catch (const std::runtime_error&) | ||||||
|  |             { | ||||||
|  |                logger_->warn( | ||||||
|  |                   "{} unknown time zone: {}", site->p->id_, site->p->tzName_); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             if (!radarSiteMap_.contains(site->p->id_)) |             if (!radarSiteMap_.contains(site->p->id_)) | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <scwx/util/time.hpp> | ||||||
|  | 
 | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <optional> | #include <optional> | ||||||
| #include <string> | #include <string> | ||||||
|  | @ -35,6 +37,9 @@ public: | ||||||
|    std::string state() const; |    std::string state() const; | ||||||
|    std::string place() const; |    std::string place() const; | ||||||
|    std::string location_name() const; |    std::string location_name() const; | ||||||
|  |    std::string tz_name() const; | ||||||
|  | 
 | ||||||
|  |    const scwx::util::time_zone* time_zone() const; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<RadarSite>              Get(const std::string& id); |    static std::shared_ptr<RadarSite>              Get(const std::string& id); | ||||||
|    static std::vector<std::shared_ptr<RadarSite>> GetAll(); |    static std::vector<std::shared_ptr<RadarSite>> GetAll(); | ||||||
|  |  | ||||||
|  | @ -1,12 +1,13 @@ | ||||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | #include <scwx/qt/manager/radar_product_manager.hpp> | ||||||
| #include <scwx/qt/manager/radar_product_manager_notifier.hpp> | #include <scwx/qt/manager/radar_product_manager_notifier.hpp> | ||||||
|  | #include <scwx/qt/settings/general_settings.hpp> | ||||||
|  | #include <scwx/qt/types/time_types.hpp> | ||||||
| #include <scwx/qt/util/geographic_lib.hpp> | #include <scwx/qt/util/geographic_lib.hpp> | ||||||
| #include <scwx/common/constants.hpp> | #include <scwx/common/constants.hpp> | ||||||
| #include <scwx/provider/nexrad_data_provider_factory.hpp> | #include <scwx/provider/nexrad_data_provider_factory.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| #include <scwx/util/map.hpp> | #include <scwx/util/map.hpp> | ||||||
| #include <scwx/util/threads.hpp> | #include <scwx/util/threads.hpp> | ||||||
| #include <scwx/util/time.hpp> |  | ||||||
| #include <scwx/wsr88d/nexrad_file_factory.hpp> | #include <scwx/wsr88d/nexrad_file_factory.hpp> | ||||||
| 
 | 
 | ||||||
| #include <deque> | #include <deque> | ||||||
|  | @ -391,6 +392,34 @@ RadarProductManager::coordinates(common::RadialSize radialSize) const | ||||||
|       throw std::invalid_argument("Invalid radial size"); |       throw std::invalid_argument("Invalid radial size"); | ||||||
|    } |    } | ||||||
| } | } | ||||||
|  | const scwx::util::time_zone* RadarProductManager::default_time_zone() const | ||||||
|  | { | ||||||
|  |    types::DefaultTimeZone defaultTimeZone = types::GetDefaultTimeZone( | ||||||
|  |       settings::GeneralSettings::Instance().default_time_zone().GetValue()); | ||||||
|  | 
 | ||||||
|  |    switch (defaultTimeZone) | ||||||
|  |    { | ||||||
|  |    case types::DefaultTimeZone::Radar: | ||||||
|  |    { | ||||||
|  |       auto radarSite = radar_site(); | ||||||
|  |       if (radarSite != nullptr) | ||||||
|  |       { | ||||||
|  |          return radarSite->time_zone(); | ||||||
|  |       } | ||||||
|  |       [[fallthrough]]; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    case types::DefaultTimeZone::Local: | ||||||
|  | #if defined(_MSC_VER) | ||||||
|  |       return std::chrono::current_zone(); | ||||||
|  | #else | ||||||
|  |       return date::current_zone(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |    default: | ||||||
|  |       return nullptr; | ||||||
|  |    } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| float RadarProductManager::gate_size() const | float RadarProductManager::gate_size() const | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <scwx/qt/config/radar_site.hpp> | #include <scwx/qt/config/radar_site.hpp> | ||||||
| #include <scwx/qt/request/nexrad_file_request.hpp> | #include <scwx/qt/request/nexrad_file_request.hpp> | ||||||
| #include <scwx/qt/types/radar_product_record.hpp> | #include <scwx/qt/types/radar_product_record.hpp> | ||||||
|  | #include <scwx/util/time.hpp> | ||||||
| #include <scwx/wsr88d/ar2v_file.hpp> | #include <scwx/wsr88d/ar2v_file.hpp> | ||||||
| #include <scwx/wsr88d/level3_file.hpp> | #include <scwx/wsr88d/level3_file.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -41,6 +42,7 @@ public: | ||||||
|    static void DumpRecords(); |    static void DumpRecords(); | ||||||
| 
 | 
 | ||||||
|    const std::vector<float>& coordinates(common::RadialSize radialSize) const; |    const std::vector<float>& coordinates(common::RadialSize radialSize) const; | ||||||
|  |    const scwx::util::time_zone*       default_time_zone() const; | ||||||
|    float                              gate_size() const; |    float                              gate_size() const; | ||||||
|    std::string                        radar_id() const; |    std::string                        radar_id() const; | ||||||
|    std::shared_ptr<config::RadarSite> radar_site() const; |    std::shared_ptr<config::RadarSite> radar_site() const; | ||||||
|  |  | ||||||
|  | @ -52,6 +52,20 @@ public: | ||||||
|    { |    { | ||||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); |       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
| 
 | 
 | ||||||
|  |       clockFormatCallbackUuid_ = | ||||||
|  |          generalSettings.clock_format().RegisterValueChangedCallback( | ||||||
|  |             [this](const std::string&) | ||||||
|  |             { | ||||||
|  |                sweepTimeNeedsUpdate_ = true; | ||||||
|  |                Q_EMIT self_->NeedsRendering(); | ||||||
|  |             }); | ||||||
|  |       defaultTimeZoneCallbackUuid_ = | ||||||
|  |          generalSettings.default_time_zone().RegisterValueChangedCallback( | ||||||
|  |             [this](const std::string&) | ||||||
|  |             { | ||||||
|  |                sweepTimeNeedsUpdate_ = true; | ||||||
|  |                Q_EMIT self_->NeedsRendering(); | ||||||
|  |             }); | ||||||
|       showMapAttributionCallbackUuid_ = |       showMapAttributionCallbackUuid_ = | ||||||
|          generalSettings.show_map_attribution().RegisterValueChangedCallback( |          generalSettings.show_map_attribution().RegisterValueChangedCallback( | ||||||
|             [this](const bool&) { Q_EMIT self_->NeedsRendering(); }); |             [this](const bool&) { Q_EMIT self_->NeedsRendering(); }); | ||||||
|  | @ -64,6 +78,10 @@ public: | ||||||
|    { |    { | ||||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); |       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
| 
 | 
 | ||||||
|  |       generalSettings.clock_format().UnregisterValueChangedCallback( | ||||||
|  |          clockFormatCallbackUuid_); | ||||||
|  |       generalSettings.default_time_zone().UnregisterValueChangedCallback( | ||||||
|  |          defaultTimeZoneCallbackUuid_); | ||||||
|       generalSettings.show_map_attribution().UnregisterValueChangedCallback( |       generalSettings.show_map_attribution().UnregisterValueChangedCallback( | ||||||
|          showMapAttributionCallbackUuid_); |          showMapAttributionCallbackUuid_); | ||||||
|       generalSettings.show_map_logo().UnregisterValueChangedCallback( |       generalSettings.show_map_logo().UnregisterValueChangedCallback( | ||||||
|  | @ -72,6 +90,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    OverlayLayer* self_; |    OverlayLayer* self_; | ||||||
| 
 | 
 | ||||||
|  |    boost::uuids::uuid clockFormatCallbackUuid_; | ||||||
|  |    boost::uuids::uuid defaultTimeZoneCallbackUuid_; | ||||||
|    boost::uuids::uuid showMapAttributionCallbackUuid_; |    boost::uuids::uuid showMapAttributionCallbackUuid_; | ||||||
|    boost::uuids::uuid showMapLogoCallbackUuid_; |    boost::uuids::uuid showMapLogoCallbackUuid_; | ||||||
| 
 | 
 | ||||||
|  | @ -263,18 +283,20 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| 
 | 
 | ||||||
|    p->sweepTimePicked_ = false; |    p->sweepTimePicked_ = false; | ||||||
| 
 | 
 | ||||||
|    if (p->sweepTimeNeedsUpdate_ && radarProductView != nullptr) |    if (radarProductView != nullptr) | ||||||
|    { |    { | ||||||
|       const scwx::util::time_zone* currentZone; |       scwx::util::ClockFormat clockFormat = scwx::util::GetClockFormat( | ||||||
|  |          settings::GeneralSettings::Instance().clock_format().GetValue()); | ||||||
| 
 | 
 | ||||||
| #if defined(_MSC_VER) |       auto radarProductManager = radarProductView->radar_product_manager(); | ||||||
|       currentZone = std::chrono::current_zone(); | 
 | ||||||
| #else |       const scwx::util::time_zone* currentZone = | ||||||
|       currentZone = date::current_zone(); |          (radarProductManager != nullptr) ? | ||||||
| #endif |             radarProductManager->default_time_zone() : | ||||||
|  |             nullptr; | ||||||
| 
 | 
 | ||||||
|       p->sweepTimeString_ = scwx::util::TimeString( |       p->sweepTimeString_ = scwx::util::TimeString( | ||||||
|          radarProductView->sweep_time(), currentZone, false); |          radarProductView->sweep_time(), clockFormat, currentZone, false); | ||||||
|       p->sweepTimeNeedsUpdate_ = false; |       p->sweepTimeNeedsUpdate_ = false; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,11 @@ | ||||||
| #include <scwx/qt/settings/general_settings.hpp> | #include <scwx/qt/settings/general_settings.hpp> | ||||||
| #include <scwx/qt/settings/settings_container.hpp> | #include <scwx/qt/settings/settings_container.hpp> | ||||||
|  | #include <scwx/qt/settings/settings_definitions.hpp> | ||||||
| #include <scwx/qt/map/map_provider.hpp> | #include <scwx/qt/map/map_provider.hpp> | ||||||
| #include <scwx/qt/types/alert_types.hpp> | #include <scwx/qt/types/alert_types.hpp> | ||||||
| #include <scwx/qt/types/qt_types.hpp> | #include <scwx/qt/types/qt_types.hpp> | ||||||
|  | #include <scwx/qt/types/time_types.hpp> | ||||||
|  | #include <scwx/util/time.hpp> | ||||||
| 
 | 
 | ||||||
| #include <array> | #include <array> | ||||||
| 
 | 
 | ||||||
|  | @ -22,21 +25,29 @@ class GeneralSettings::Impl | ||||||
| public: | public: | ||||||
|    explicit Impl() |    explicit Impl() | ||||||
|    { |    { | ||||||
|  |       std::string defaultClockFormatValue = | ||||||
|  |          scwx::util::GetClockFormatName(scwx::util::ClockFormat::_24Hour); | ||||||
|       std::string defaultDefaultAlertActionValue = |       std::string defaultDefaultAlertActionValue = | ||||||
|          types::GetAlertActionName(types::AlertAction::Go); |          types::GetAlertActionName(types::AlertAction::Go); | ||||||
|  |       std::string defaultDefaultTimeZoneValue = | ||||||
|  |          types::GetDefaultTimeZoneName(types::DefaultTimeZone::Radar); | ||||||
|       std::string defaultMapProviderValue = |       std::string defaultMapProviderValue = | ||||||
|          map::GetMapProviderName(map::MapProvider::MapTiler); |          map::GetMapProviderName(map::MapProvider::MapTiler); | ||||||
|       std::string defaultThemeValue = |       std::string defaultThemeValue = | ||||||
|          types::GetUiStyleName(types::UiStyle::Default); |          types::GetUiStyleName(types::UiStyle::Default); | ||||||
| 
 | 
 | ||||||
|  |       boost::to_lower(defaultClockFormatValue); | ||||||
|       boost::to_lower(defaultDefaultAlertActionValue); |       boost::to_lower(defaultDefaultAlertActionValue); | ||||||
|  |       boost::to_lower(defaultDefaultTimeZoneValue); | ||||||
|       boost::to_lower(defaultMapProviderValue); |       boost::to_lower(defaultMapProviderValue); | ||||||
|       boost::to_lower(defaultThemeValue); |       boost::to_lower(defaultThemeValue); | ||||||
| 
 | 
 | ||||||
|       antiAliasingEnabled_.SetDefault(true); |       antiAliasingEnabled_.SetDefault(true); | ||||||
|  |       clockFormat_.SetDefault(defaultClockFormatValue); | ||||||
|       debugEnabled_.SetDefault(false); |       debugEnabled_.SetDefault(false); | ||||||
|       defaultAlertAction_.SetDefault(defaultDefaultAlertActionValue); |       defaultAlertAction_.SetDefault(defaultDefaultAlertActionValue); | ||||||
|       defaultRadarSite_.SetDefault("KLSX"); |       defaultRadarSite_.SetDefault("KLSX"); | ||||||
|  |       defaultTimeZone_.SetDefault(defaultDefaultTimeZoneValue); | ||||||
|       fontSizes_.SetDefault({16}); |       fontSizes_.SetDefault({16}); | ||||||
|       loopDelay_.SetDefault(2500); |       loopDelay_.SetDefault(2500); | ||||||
|       loopSpeed_.SetDefault(5.0); |       loopSpeed_.SetDefault(5.0); | ||||||
|  | @ -67,74 +78,40 @@ public: | ||||||
|       loopTime_.SetMinimum(1); |       loopTime_.SetMinimum(1); | ||||||
|       loopTime_.SetMaximum(1440); |       loopTime_.SetMaximum(1440); | ||||||
| 
 | 
 | ||||||
|  |       clockFormat_.SetValidator( | ||||||
|  |          SCWX_SETTINGS_ENUM_VALIDATOR(scwx::util::ClockFormat, | ||||||
|  |                                       scwx::util::ClockFormatIterator(), | ||||||
|  |                                       scwx::util::GetClockFormatName)); | ||||||
|       defaultAlertAction_.SetValidator( |       defaultAlertAction_.SetValidator( | ||||||
|          [](const std::string& value) |          SCWX_SETTINGS_ENUM_VALIDATOR(types::AlertAction, | ||||||
|          { |                                       types::AlertActionIterator(), | ||||||
|             for (types::AlertAction alertAction : types::AlertActionIterator()) |                                       types::GetAlertActionName)); | ||||||
|             { |       defaultTimeZone_.SetValidator( | ||||||
|                // If the value is equal to a lower case alert action name
 |          SCWX_SETTINGS_ENUM_VALIDATOR(types::DefaultTimeZone, | ||||||
|                std::string alertActionName = |                                       types::DefaultTimeZoneIterator(), | ||||||
|                   types::GetAlertActionName(alertAction); |                                       types::GetDefaultTimeZoneName)); | ||||||
|                boost::to_lower(alertActionName); |  | ||||||
|                if (value == alertActionName) |  | ||||||
|                { |  | ||||||
|                   // Regard as a match, valid
 |  | ||||||
|                   return true; |  | ||||||
|                } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // No match found, invalid
 |  | ||||||
|             return false; |  | ||||||
|          }); |  | ||||||
|       mapProvider_.SetValidator( |       mapProvider_.SetValidator( | ||||||
|          [](const std::string& value) |          SCWX_SETTINGS_ENUM_VALIDATOR(map::MapProvider, | ||||||
|          { |                                       map::MapProviderIterator(), | ||||||
|             for (map::MapProvider mapProvider : map::MapProviderIterator()) |                                       map::GetMapProviderName)); | ||||||
|             { |  | ||||||
|                // If the value is equal to a lower case map provider name
 |  | ||||||
|                std::string mapProviderName = |  | ||||||
|                   map::GetMapProviderName(mapProvider); |  | ||||||
|                boost::to_lower(mapProviderName); |  | ||||||
|                if (value == mapProviderName) |  | ||||||
|                { |  | ||||||
|                   // Regard as a match, valid
 |  | ||||||
|                   return true; |  | ||||||
|                } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // No match found, invalid
 |  | ||||||
|             return false; |  | ||||||
|          }); |  | ||||||
|       mapboxApiKey_.SetValidator([](const std::string& value) |       mapboxApiKey_.SetValidator([](const std::string& value) | ||||||
|                                  { return !value.empty(); }); |                                  { return !value.empty(); }); | ||||||
|       maptilerApiKey_.SetValidator([](const std::string& value) |       maptilerApiKey_.SetValidator([](const std::string& value) | ||||||
|                                    { return !value.empty(); }); |                                    { return !value.empty(); }); | ||||||
|       theme_.SetValidator( |       theme_.SetValidator(                            //
 | ||||||
|          [](const std::string& value) |          SCWX_SETTINGS_ENUM_VALIDATOR(types::UiStyle, //
 | ||||||
|          { |                                       types::UiStyleIterator(), | ||||||
|             for (types::UiStyle uiStyle : types::UiStyleIterator()) |                                       types::GetUiStyleName)); | ||||||
|             { |  | ||||||
|                // If the value is equal to a lower case UI style name
 |  | ||||||
|                std::string uiStyleName = types::GetUiStyleName(uiStyle); |  | ||||||
|                boost::to_lower(uiStyleName); |  | ||||||
|                if (value == uiStyleName) |  | ||||||
|                { |  | ||||||
|                   // Regard as a match, valid
 |  | ||||||
|                   return true; |  | ||||||
|                } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // No match found, invalid
 |  | ||||||
|             return false; |  | ||||||
|          }); |  | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ~Impl() {} |    ~Impl() {} | ||||||
| 
 | 
 | ||||||
|    SettingsVariable<bool>        antiAliasingEnabled_ {"anti_aliasing_enabled"}; |    SettingsVariable<bool>        antiAliasingEnabled_ {"anti_aliasing_enabled"}; | ||||||
|  |    SettingsVariable<std::string> clockFormat_ {"clock_format"}; | ||||||
|    SettingsVariable<bool>        debugEnabled_ {"debug_enabled"}; |    SettingsVariable<bool>        debugEnabled_ {"debug_enabled"}; | ||||||
|    SettingsVariable<std::string> defaultAlertAction_ {"default_alert_action"}; |    SettingsVariable<std::string> defaultAlertAction_ {"default_alert_action"}; | ||||||
|    SettingsVariable<std::string> defaultRadarSite_ {"default_radar_site"}; |    SettingsVariable<std::string> defaultRadarSite_ {"default_radar_site"}; | ||||||
|  |    SettingsVariable<std::string> defaultTimeZone_ {"default_time_zone"}; | ||||||
|    SettingsContainer<std::vector<std::int64_t>> fontSizes_ {"font_sizes"}; |    SettingsContainer<std::vector<std::int64_t>> fontSizes_ {"font_sizes"}; | ||||||
|    SettingsVariable<std::int64_t>               gridWidth_ {"grid_width"}; |    SettingsVariable<std::int64_t>               gridWidth_ {"grid_width"}; | ||||||
|    SettingsVariable<std::int64_t>               gridHeight_ {"grid_height"}; |    SettingsVariable<std::int64_t>               gridHeight_ {"grid_height"}; | ||||||
|  | @ -154,10 +131,12 @@ public: | ||||||
| GeneralSettings::GeneralSettings() : | GeneralSettings::GeneralSettings() : | ||||||
|     SettingsCategory("general"), p(std::make_unique<Impl>()) |     SettingsCategory("general"), p(std::make_unique<Impl>()) | ||||||
| { | { | ||||||
|    RegisterVariables({&p->antiAliasingEnabled_, |    RegisterVariables({&p->antiAliasingEnabled_, //
 | ||||||
|  |                       &p->clockFormat_, | ||||||
|                       &p->debugEnabled_, |                       &p->debugEnabled_, | ||||||
|                       &p->defaultAlertAction_, |                       &p->defaultAlertAction_, | ||||||
|                       &p->defaultRadarSite_, |                       &p->defaultRadarSite_, | ||||||
|  |                       &p->defaultTimeZone_, | ||||||
|                       &p->fontSizes_, |                       &p->fontSizes_, | ||||||
|                       &p->gridWidth_, |                       &p->gridWidth_, | ||||||
|                       &p->gridHeight_, |                       &p->gridHeight_, | ||||||
|  | @ -185,6 +164,11 @@ SettingsVariable<bool>& GeneralSettings::anti_aliasing_enabled() const | ||||||
|    return p->antiAliasingEnabled_; |    return p->antiAliasingEnabled_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SettingsVariable<std::string>& GeneralSettings::clock_format() const | ||||||
|  | { | ||||||
|  |    return p->clockFormat_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| SettingsVariable<bool>& GeneralSettings::debug_enabled() const | SettingsVariable<bool>& GeneralSettings::debug_enabled() const | ||||||
| { | { | ||||||
|    return p->debugEnabled_; |    return p->debugEnabled_; | ||||||
|  | @ -200,6 +184,11 @@ SettingsVariable<std::string>& GeneralSettings::default_radar_site() const | ||||||
|    return p->defaultRadarSite_; |    return p->defaultRadarSite_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SettingsVariable<std::string>& GeneralSettings::default_time_zone() const | ||||||
|  | { | ||||||
|  |    return p->defaultTimeZone_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| SettingsContainer<std::vector<std::int64_t>>& | SettingsContainer<std::vector<std::int64_t>>& | ||||||
| GeneralSettings::font_sizes() const | GeneralSettings::font_sizes() const | ||||||
| { | { | ||||||
|  | @ -293,9 +282,11 @@ GeneralSettings& GeneralSettings::Instance() | ||||||
| bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) | bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) | ||||||
| { | { | ||||||
|    return (lhs.p->antiAliasingEnabled_ == rhs.p->antiAliasingEnabled_ && |    return (lhs.p->antiAliasingEnabled_ == rhs.p->antiAliasingEnabled_ && | ||||||
|  |            lhs.p->clockFormat_ == rhs.p->clockFormat_ && | ||||||
|            lhs.p->debugEnabled_ == rhs.p->debugEnabled_ && |            lhs.p->debugEnabled_ == rhs.p->debugEnabled_ && | ||||||
|            lhs.p->defaultAlertAction_ == rhs.p->defaultAlertAction_ && |            lhs.p->defaultAlertAction_ == rhs.p->defaultAlertAction_ && | ||||||
|            lhs.p->defaultRadarSite_ == rhs.p->defaultRadarSite_ && |            lhs.p->defaultRadarSite_ == rhs.p->defaultRadarSite_ && | ||||||
|  |            lhs.p->defaultTimeZone_ == rhs.p->defaultTimeZone_ && | ||||||
|            lhs.p->fontSizes_ == rhs.p->fontSizes_ && |            lhs.p->fontSizes_ == rhs.p->fontSizes_ && | ||||||
|            lhs.p->gridWidth_ == rhs.p->gridWidth_ && |            lhs.p->gridWidth_ == rhs.p->gridWidth_ && | ||||||
|            lhs.p->gridHeight_ == rhs.p->gridHeight_ && |            lhs.p->gridHeight_ == rhs.p->gridHeight_ && | ||||||
|  |  | ||||||
|  | @ -26,9 +26,11 @@ public: | ||||||
|    GeneralSettings& operator=(GeneralSettings&&) noexcept; |    GeneralSettings& operator=(GeneralSettings&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    SettingsVariable<bool>&                       anti_aliasing_enabled() const; |    SettingsVariable<bool>&                       anti_aliasing_enabled() const; | ||||||
|  |    SettingsVariable<std::string>&                clock_format() const; | ||||||
|    SettingsVariable<bool>&                       debug_enabled() const; |    SettingsVariable<bool>&                       debug_enabled() const; | ||||||
|    SettingsVariable<std::string>&                default_alert_action() const; |    SettingsVariable<std::string>&                default_alert_action() const; | ||||||
|    SettingsVariable<std::string>&                default_radar_site() const; |    SettingsVariable<std::string>&                default_radar_site() const; | ||||||
|  |    SettingsVariable<std::string>&                default_time_zone() const; | ||||||
|    SettingsContainer<std::vector<std::int64_t>>& font_sizes() const; |    SettingsContainer<std::vector<std::int64_t>>& font_sizes() const; | ||||||
|    SettingsVariable<std::int64_t>&               grid_height() const; |    SettingsVariable<std::int64_t>&               grid_height() const; | ||||||
|    SettingsVariable<std::int64_t>&               grid_width() const; |    SettingsVariable<std::int64_t>&               grid_width() const; | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								scwx-qt/source/scwx/qt/types/time_types.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								scwx-qt/source/scwx/qt/types/time_types.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | #include <scwx/qt/types/time_types.hpp> | ||||||
|  | #include <scwx/util/enum.hpp> | ||||||
|  | 
 | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | #include <boost/algorithm/string.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace types | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::unordered_map<DefaultTimeZone, std::string> | ||||||
|  |    defaultTimeZoneName_ {{DefaultTimeZone::Local, "Local"}, | ||||||
|  |                          {DefaultTimeZone::Radar, "Radar"}, | ||||||
|  |                          {DefaultTimeZone::UTC, "UTC"}, | ||||||
|  |                          {DefaultTimeZone::Unknown, "?"}}; | ||||||
|  | 
 | ||||||
|  | SCWX_GET_ENUM(DefaultTimeZone, GetDefaultTimeZone, defaultTimeZoneName_) | ||||||
|  | 
 | ||||||
|  | const std::string& GetDefaultTimeZoneName(DefaultTimeZone timeZone) | ||||||
|  | { | ||||||
|  |    return defaultTimeZoneName_.at(timeZone); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace types
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										30
									
								
								scwx-qt/source/scwx/qt/types/time_types.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								scwx-qt/source/scwx/qt/types/time_types.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/util/iterator.hpp> | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace types | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | enum class DefaultTimeZone | ||||||
|  | { | ||||||
|  |    Local, | ||||||
|  |    Radar, | ||||||
|  |    UTC, | ||||||
|  |    Unknown | ||||||
|  | }; | ||||||
|  | typedef scwx::util:: | ||||||
|  |    Iterator<DefaultTimeZone, DefaultTimeZone::Local, DefaultTimeZone::UTC> | ||||||
|  |       DefaultTimeZoneIterator; | ||||||
|  | 
 | ||||||
|  | DefaultTimeZone    GetDefaultTimeZone(const std::string& name); | ||||||
|  | const std::string& GetDefaultTimeZoneName(DefaultTimeZone timeZone); | ||||||
|  | 
 | ||||||
|  | } // namespace types
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| #include <scwx/qt/types/location_types.hpp> | #include <scwx/qt/types/location_types.hpp> | ||||||
| #include <scwx/qt/types/qt_types.hpp> | #include <scwx/qt/types/qt_types.hpp> | ||||||
| #include <scwx/qt/types/text_types.hpp> | #include <scwx/qt/types/text_types.hpp> | ||||||
|  | #include <scwx/qt/types/time_types.hpp> | ||||||
| #include <scwx/qt/ui/county_dialog.hpp> | #include <scwx/qt/ui/county_dialog.hpp> | ||||||
| #include <scwx/qt/ui/radar_site_dialog.hpp> | #include <scwx/qt/ui/radar_site_dialog.hpp> | ||||||
| #include <scwx/qt/util/color.hpp> | #include <scwx/qt/util/color.hpp> | ||||||
|  | @ -129,6 +130,8 @@ public: | ||||||
|           &mapTilerApiKey_, |           &mapTilerApiKey_, | ||||||
|           &theme_, |           &theme_, | ||||||
|           &defaultAlertAction_, |           &defaultAlertAction_, | ||||||
|  |           &clockFormat_, | ||||||
|  |           &defaultTimeZone_, | ||||||
|           &antiAliasingEnabled_, |           &antiAliasingEnabled_, | ||||||
|           &showMapAttribution_, |           &showMapAttribution_, | ||||||
|           &showMapLogo_, |           &showMapLogo_, | ||||||
|  | @ -220,6 +223,8 @@ public: | ||||||
|    settings::SettingsInterface<std::string>  mapboxApiKey_ {}; |    settings::SettingsInterface<std::string>  mapboxApiKey_ {}; | ||||||
|    settings::SettingsInterface<std::string>  mapTilerApiKey_ {}; |    settings::SettingsInterface<std::string>  mapTilerApiKey_ {}; | ||||||
|    settings::SettingsInterface<std::string>  defaultAlertAction_ {}; |    settings::SettingsInterface<std::string>  defaultAlertAction_ {}; | ||||||
|  |    settings::SettingsInterface<std::string>  clockFormat_ {}; | ||||||
|  |    settings::SettingsInterface<std::string>  defaultTimeZone_ {}; | ||||||
|    settings::SettingsInterface<std::string>  theme_ {}; |    settings::SettingsInterface<std::string>  theme_ {}; | ||||||
|    settings::SettingsInterface<bool>         antiAliasingEnabled_ {}; |    settings::SettingsInterface<bool>         antiAliasingEnabled_ {}; | ||||||
|    settings::SettingsInterface<bool>         showMapAttribution_ {}; |    settings::SettingsInterface<bool>         showMapAttribution_ {}; | ||||||
|  | @ -590,23 +595,9 @@ void SettingsDialogImpl::SetupGeneralTab() | ||||||
|    defaultAlertAction_.SetSettingsVariable( |    defaultAlertAction_.SetSettingsVariable( | ||||||
|       generalSettings.default_alert_action()); |       generalSettings.default_alert_action()); | ||||||
|    defaultAlertAction_.SetMapFromValueFunction( |    defaultAlertAction_.SetMapFromValueFunction( | ||||||
|       [](const std::string& text) -> std::string |       SCWX_ENUM_MAP_FROM_VALUE(types::AlertAction, | ||||||
|       { |                                types::AlertActionIterator(), | ||||||
|          for (types::AlertAction alertAction : types::AlertActionIterator()) |                                types::GetAlertActionName)); | ||||||
|          { |  | ||||||
|             const std::string alertActionName = |  | ||||||
|                types::GetAlertActionName(alertAction); |  | ||||||
| 
 |  | ||||||
|             if (boost::iequals(text, alertActionName)) |  | ||||||
|             { |  | ||||||
|                // Return alert action label
 |  | ||||||
|                return alertActionName; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          // Alert action label not found, return unknown
 |  | ||||||
|          return "?"; |  | ||||||
|       }); |  | ||||||
|    defaultAlertAction_.SetMapToValueFunction( |    defaultAlertAction_.SetMapToValueFunction( | ||||||
|       [](std::string text) -> std::string |       [](std::string text) -> std::string | ||||||
|       { |       { | ||||||
|  | @ -617,6 +608,48 @@ void SettingsDialogImpl::SetupGeneralTab() | ||||||
|    defaultAlertAction_.SetEditWidget(self_->ui->defaultAlertActionComboBox); |    defaultAlertAction_.SetEditWidget(self_->ui->defaultAlertActionComboBox); | ||||||
|    defaultAlertAction_.SetResetButton(self_->ui->resetDefaultAlertActionButton); |    defaultAlertAction_.SetResetButton(self_->ui->resetDefaultAlertActionButton); | ||||||
| 
 | 
 | ||||||
|  |    for (const auto& clockFormat : scwx::util::ClockFormatIterator()) | ||||||
|  |    { | ||||||
|  |       self_->ui->clockFormatComboBox->addItem( | ||||||
|  |          QString::fromStdString(scwx::util::GetClockFormatName(clockFormat))); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    clockFormat_.SetSettingsVariable(generalSettings.clock_format()); | ||||||
|  |    clockFormat_.SetMapFromValueFunction( | ||||||
|  |       SCWX_ENUM_MAP_FROM_VALUE(scwx::util::ClockFormat, | ||||||
|  |                                scwx::util::ClockFormatIterator(), | ||||||
|  |                                scwx::util::GetClockFormatName)); | ||||||
|  |    clockFormat_.SetMapToValueFunction( | ||||||
|  |       [](std::string text) -> std::string | ||||||
|  |       { | ||||||
|  |          // Convert label to lower case and return
 | ||||||
|  |          boost::to_lower(text); | ||||||
|  |          return text; | ||||||
|  |       }); | ||||||
|  |    clockFormat_.SetEditWidget(self_->ui->clockFormatComboBox); | ||||||
|  |    clockFormat_.SetResetButton(self_->ui->resetClockFormatButton); | ||||||
|  | 
 | ||||||
|  |    for (const auto& timeZone : types::DefaultTimeZoneIterator()) | ||||||
|  |    { | ||||||
|  |       self_->ui->defaultTimeZoneComboBox->addItem( | ||||||
|  |          QString::fromStdString(types::GetDefaultTimeZoneName(timeZone))); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    defaultTimeZone_.SetSettingsVariable(generalSettings.default_time_zone()); | ||||||
|  |    defaultTimeZone_.SetMapFromValueFunction( | ||||||
|  |       SCWX_ENUM_MAP_FROM_VALUE(types::DefaultTimeZone, | ||||||
|  |                                types::DefaultTimeZoneIterator(), | ||||||
|  |                                types::GetDefaultTimeZoneName)); | ||||||
|  |    defaultTimeZone_.SetMapToValueFunction( | ||||||
|  |       [](std::string text) -> std::string | ||||||
|  |       { | ||||||
|  |          // Convert label to lower case and return
 | ||||||
|  |          boost::to_lower(text); | ||||||
|  |          return text; | ||||||
|  |       }); | ||||||
|  |    defaultTimeZone_.SetEditWidget(self_->ui->defaultTimeZoneComboBox); | ||||||
|  |    defaultTimeZone_.SetResetButton(self_->ui->resetDefaultTimeZoneButton); | ||||||
|  | 
 | ||||||
|    antiAliasingEnabled_.SetSettingsVariable( |    antiAliasingEnabled_.SetSettingsVariable( | ||||||
|       generalSettings.anti_aliasing_enabled()); |       generalSettings.anti_aliasing_enabled()); | ||||||
|    antiAliasingEnabled_.SetEditWidget(self_->ui->antiAliasingEnabledCheckBox); |    antiAliasingEnabled_.SetEditWidget(self_->ui->antiAliasingEnabledCheckBox); | ||||||
|  |  | ||||||
|  | @ -129,8 +129,18 @@ | ||||||
|               <property name="bottomMargin"> |               <property name="bottomMargin"> | ||||||
|                <number>0</number> |                <number>0</number> | ||||||
|               </property> |               </property> | ||||||
|               <item row="5" column="4"> |               <item row="8" column="0"> | ||||||
|                <widget class="QToolButton" name="resetMapProviderButton"> |                <widget class="QLabel" name="defaultAlertActionLabel"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Default Alert Action</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="0" column="2"> | ||||||
|  |                <widget class="QComboBox" name="themeComboBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="0" column="4"> | ||||||
|  |                <widget class="QToolButton" name="resetThemeButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -140,46 +150,8 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="1" column="3"> |               <item row="8" column="2"> | ||||||
|                <widget class="QToolButton" name="radarSiteSelectButton"> |                <widget class="QComboBox" name="defaultAlertActionComboBox"/> | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="5" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_7"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Map Provider</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="1" column="2"> |  | ||||||
|                <widget class="QComboBox" name="radarSiteComboBox"/> |  | ||||||
|               </item> |  | ||||||
|               <item row="3" column="0"> |  | ||||||
|                <widget class="QLabel" name="label_3"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Grid Height</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="3" column="2"> |  | ||||||
|                <widget class="QSpinBox" name="gridHeightSpinBox"/> |  | ||||||
|               </item> |  | ||||||
|               <item row="2" column="2"> |  | ||||||
|                <widget class="QSpinBox" name="gridWidthSpinBox"/> |  | ||||||
|               </item> |  | ||||||
|               <item row="1" column="4"> |  | ||||||
|                <widget class="QToolButton" name="resetRadarSiteButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |               </item> | ||||||
|               <item row="6" column="2"> |               <item row="6" column="2"> | ||||||
|                <widget class="QLineEdit" name="mapboxApiKeyLineEdit"> |                <widget class="QLineEdit" name="mapboxApiKeyLineEdit"> | ||||||
|  | @ -188,6 +160,13 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  |               <item row="10" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_21"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Default Time Zone</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|               <item row="2" column="0"> |               <item row="2" column="0"> | ||||||
|                <widget class="QLabel" name="label_2"> |                <widget class="QLabel" name="label_2"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|  | @ -195,10 +174,17 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="8" column="0"> |               <item row="0" column="0"> | ||||||
|                <widget class="QLabel" name="defaultAlertActionLabel"> |                <widget class="QLabel" name="label_5"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>Default Alert Action</string> |                  <string>Theme</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="5" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_7"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Map Provider</string> | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  | @ -209,34 +195,6 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="1" column="0"> |  | ||||||
|                <widget class="QLabel" name="label"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>Default Radar Site</string> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="7" column="2"> |  | ||||||
|                <widget class="QLineEdit" name="mapTilerApiKeyLineEdit"> |  | ||||||
|                 <property name="echoMode"> |  | ||||||
|                  <enum>QLineEdit::Password</enum> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="8" column="2"> |  | ||||||
|                <widget class="QComboBox" name="defaultAlertActionComboBox"/> |  | ||||||
|               </item> |  | ||||||
|               <item row="7" column="4"> |  | ||||||
|                <widget class="QToolButton" name="resetMapTilerApiKeyButton"> |  | ||||||
|                 <property name="text"> |  | ||||||
|                  <string>...</string> |  | ||||||
|                 </property> |  | ||||||
|                 <property name="icon"> |  | ||||||
|                  <iconset resource="../../../../scwx-qt.qrc"> |  | ||||||
|                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> |  | ||||||
|                 </property> |  | ||||||
|                </widget> |  | ||||||
|               </item> |  | ||||||
|               <item row="3" column="4"> |               <item row="3" column="4"> | ||||||
|                <widget class="QToolButton" name="resetGridHeightButton"> |                <widget class="QToolButton" name="resetGridHeightButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|  | @ -251,10 +209,25 @@ | ||||||
|               <item row="5" column="2"> |               <item row="5" column="2"> | ||||||
|                <widget class="QComboBox" name="mapProviderComboBox"/> |                <widget class="QComboBox" name="mapProviderComboBox"/> | ||||||
|               </item> |               </item> | ||||||
|               <item row="6" column="0"> |               <item row="7" column="4"> | ||||||
|                <widget class="QLabel" name="label_4"> |                <widget class="QToolButton" name="resetMapTilerApiKeyButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>Mapbox API Key</string> |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="5" column="4"> | ||||||
|  |                <widget class="QToolButton" name="resetMapProviderButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  | @ -269,8 +242,21 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="8" column="4"> |               <item row="9" column="0"> | ||||||
|                <widget class="QToolButton" name="resetDefaultAlertActionButton"> |                <widget class="QLabel" name="label_20"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Clock Format</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="2" column="2"> | ||||||
|  |                <widget class="QSpinBox" name="gridWidthSpinBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="9" column="2"> | ||||||
|  |                <widget class="QComboBox" name="clockFormatComboBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="1" column="4"> | ||||||
|  |                <widget class="QToolButton" name="resetRadarSiteButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -280,6 +266,23 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|  |               <item row="1" column="2"> | ||||||
|  |                <widget class="QComboBox" name="radarSiteComboBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="1" column="0"> | ||||||
|  |                <widget class="QLabel" name="label"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Default Radar Site</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="6" column="0"> | ||||||
|  |                <widget class="QLabel" name="label_4"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>Mapbox API Key</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|               <item row="6" column="4"> |               <item row="6" column="4"> | ||||||
|                <widget class="QToolButton" name="resetMapboxApiKeyButton"> |                <widget class="QToolButton" name="resetMapboxApiKeyButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|  | @ -291,18 +294,57 @@ | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="0" column="0"> |               <item row="3" column="0"> | ||||||
|                <widget class="QLabel" name="label_5"> |                <widget class="QLabel" name="label_3"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>Theme</string> |                  <string>Grid Height</string> | ||||||
|                 </property> |                 </property> | ||||||
|                </widget> |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="0" column="2"> |               <item row="8" column="4"> | ||||||
|                <widget class="QComboBox" name="themeComboBox"/> |                <widget class="QToolButton" name="resetDefaultAlertActionButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|               </item> |               </item> | ||||||
|               <item row="0" column="4"> |               <item row="1" column="3"> | ||||||
|                <widget class="QToolButton" name="resetThemeButton"> |                <widget class="QToolButton" name="radarSiteSelectButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="7" column="2"> | ||||||
|  |                <widget class="QLineEdit" name="mapTilerApiKeyLineEdit"> | ||||||
|  |                 <property name="echoMode"> | ||||||
|  |                  <enum>QLineEdit::Password</enum> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="3" column="2"> | ||||||
|  |                <widget class="QSpinBox" name="gridHeightSpinBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="10" column="2"> | ||||||
|  |                <widget class="QComboBox" name="defaultTimeZoneComboBox"/> | ||||||
|  |               </item> | ||||||
|  |               <item row="9" column="4"> | ||||||
|  |                <widget class="QToolButton" name="resetClockFormatButton"> | ||||||
|  |                 <property name="text"> | ||||||
|  |                  <string>...</string> | ||||||
|  |                 </property> | ||||||
|  |                 <property name="icon"> | ||||||
|  |                  <iconset resource="../../../../scwx-qt.qrc"> | ||||||
|  |                   <normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> | ||||||
|  |                 </property> | ||||||
|  |                </widget> | ||||||
|  |               </item> | ||||||
|  |               <item row="10" column="4"> | ||||||
|  |                <widget class="QToolButton" name="resetDefaultTimeZoneButton"> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>...</string> |                  <string>...</string> | ||||||
|                 </property> |                 </property> | ||||||
|  | @ -387,7 +429,7 @@ | ||||||
|                    <rect> |                    <rect> | ||||||
|                     <x>0</x> |                     <x>0</x> | ||||||
|                     <y>0</y> |                     <y>0</y> | ||||||
|                     <width>66</width> |                     <width>63</width> | ||||||
|                     <height>18</height> |                     <height>18</height> | ||||||
|                    </rect> |                    </rect> | ||||||
|                   </property> |                   </property> | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include <scwx/qt/view/level3_product_view.hpp> | #include <scwx/qt/view/level3_product_view.hpp> | ||||||
|  | #include <scwx/qt/settings/general_settings.hpp> | ||||||
| #include <scwx/common/characters.hpp> | #include <scwx/common/characters.hpp> | ||||||
| #include <scwx/common/constants.hpp> | #include <scwx/common/constants.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
|  | @ -176,13 +177,15 @@ Level3ProductView::GetDescriptionFields() const | ||||||
| 
 | 
 | ||||||
|    if (p->graphicMessage_ != nullptr) |    if (p->graphicMessage_ != nullptr) | ||||||
|    { |    { | ||||||
|       const scwx::util::time_zone* currentZone; |       util::ClockFormat clockFormat = util::GetClockFormat( | ||||||
|  |          settings::GeneralSettings::Instance().clock_format().GetValue()); | ||||||
| 
 | 
 | ||||||
| #if defined(_MSC_VER) |       auto radarProductManager = radar_product_manager(); | ||||||
|       currentZone = std::chrono::current_zone(); | 
 | ||||||
| #else |       const scwx::util::time_zone* currentZone = | ||||||
|       currentZone = date::current_zone(); |          (radarProductManager != nullptr) ? | ||||||
| #endif |             radarProductManager->default_time_zone() : | ||||||
|  |             nullptr; | ||||||
| 
 | 
 | ||||||
|       auto descriptionBlock = p->graphicMessage_->description_block(); |       auto descriptionBlock = p->graphicMessage_->description_block(); | ||||||
| 
 | 
 | ||||||
|  | @ -197,10 +200,12 @@ Level3ProductView::GetDescriptionFields() const | ||||||
| 
 | 
 | ||||||
|          description.emplace_back( |          description.emplace_back( | ||||||
|             "Volume Time", |             "Volume Time", | ||||||
|             scwx::util::TimeString(volumeTime, currentZone, false)); |             scwx::util::TimeString( | ||||||
|  |                volumeTime, clockFormat, currentZone, false)); | ||||||
|          description.emplace_back( |          description.emplace_back( | ||||||
|             "Product Time", |             "Product Time", | ||||||
|             scwx::util::TimeString(productTime, currentZone, false)); |             scwx::util::TimeString( | ||||||
|  |                productTime, clockFormat, currentZone, false)); | ||||||
| 
 | 
 | ||||||
|          description.emplace_back( |          description.emplace_back( | ||||||
|             "Sequence Number", |             "Sequence Number", | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| Subproject commit 9cef3730c84d22803ea433fba8111826327dd82f | Subproject commit 2ba8740516bbdc58c848bf71755b2f285aa47938 | ||||||
|  | @ -38,6 +38,9 @@ TEST_F(RadarSiteTest, DefaultConfig) | ||||||
|    EXPECT_EQ(radarSite->country(), "USA"); |    EXPECT_EQ(radarSite->country(), "USA"); | ||||||
|    EXPECT_EQ(radarSite->state(), "MO"); |    EXPECT_EQ(radarSite->state(), "MO"); | ||||||
|    EXPECT_EQ(radarSite->place(), "St. Louis"); |    EXPECT_EQ(radarSite->place(), "St. Louis"); | ||||||
|  |    EXPECT_EQ(radarSite->tz_name(), "America/Chicago"); | ||||||
|  |    ASSERT_NE(radarSite->time_zone(), nullptr); | ||||||
|  |    EXPECT_EQ(radarSite->time_zone()->name(), "America/Chicago"); | ||||||
|    EXPECT_DOUBLE_EQ(radarSite->latitude(), 38.6986863); |    EXPECT_DOUBLE_EQ(radarSite->latitude(), 38.6986863); | ||||||
|    EXPECT_DOUBLE_EQ(radarSite->longitude(), -90.682877); |    EXPECT_DOUBLE_EQ(radarSite->longitude(), -90.682877); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <scwx/util/iterator.hpp> | ||||||
|  | 
 | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <optional> | #include <optional> | ||||||
|  | #include <string> | ||||||
| 
 | 
 | ||||||
| #if !defined(_MSC_VER) | #if !defined(_MSC_VER) | ||||||
| #   include <date/tz.h> | #   include <date/tz.h> | ||||||
|  | @ -18,10 +21,24 @@ typedef std::chrono::time_zone time_zone; | ||||||
| typedef date::time_zone time_zone; | typedef date::time_zone time_zone; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | enum class ClockFormat | ||||||
|  | { | ||||||
|  |    _12Hour, | ||||||
|  |    _24Hour, | ||||||
|  |    Unknown | ||||||
|  | }; | ||||||
|  | typedef scwx::util:: | ||||||
|  |    Iterator<ClockFormat, ClockFormat::_12Hour, ClockFormat::_24Hour> | ||||||
|  |       ClockFormatIterator; | ||||||
|  | 
 | ||||||
|  | ClockFormat        GetClockFormat(const std::string& name); | ||||||
|  | const std::string& GetClockFormatName(ClockFormat clockFormat); | ||||||
|  | 
 | ||||||
| std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate, | std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate, | ||||||
|                                                 uint32_t milliseconds); |                                                 uint32_t milliseconds); | ||||||
| 
 | 
 | ||||||
| std::string TimeString(std::chrono::system_clock::time_point time, | std::string TimeString(std::chrono::system_clock::time_point time, | ||||||
|  |                        ClockFormat      clockFormat = ClockFormat::_24Hour, | ||||||
|                        const time_zone* timeZone    = nullptr, |                        const time_zone* timeZone    = nullptr, | ||||||
|                        bool             epochValid  = true); |                        bool             epochValid  = true); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,8 +9,12 @@ | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include <scwx/util/time.hpp> | #include <scwx/util/time.hpp> | ||||||
|  | #include <scwx/util/enum.hpp> | ||||||
| 
 | 
 | ||||||
| #include <sstream> | #include <sstream> | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | #include <boost/algorithm/string.hpp> | ||||||
| 
 | 
 | ||||||
| #if !defined(_MSC_VER) | #if !defined(_MSC_VER) | ||||||
| #   include <date/date.h> | #   include <date/date.h> | ||||||
|  | @ -21,6 +25,18 @@ namespace scwx | ||||||
| namespace util | namespace util | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | static const std::unordered_map<ClockFormat, std::string> clockFormatName_ { | ||||||
|  |    {ClockFormat::_12Hour, "12-hour"}, | ||||||
|  |    {ClockFormat::_24Hour, "24-hour"}, | ||||||
|  |    {ClockFormat::Unknown, "?"}}; | ||||||
|  | 
 | ||||||
|  | SCWX_GET_ENUM(ClockFormat, GetClockFormat, clockFormatName_) | ||||||
|  | 
 | ||||||
|  | const std::string& GetClockFormatName(ClockFormat clockFormat) | ||||||
|  | { | ||||||
|  |    return clockFormatName_.at(clockFormat); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate, | std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate, | ||||||
|                                                 uint32_t milliseconds) |                                                 uint32_t milliseconds) | ||||||
| { | { | ||||||
|  | @ -33,6 +49,7 @@ std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string TimeString(std::chrono::system_clock::time_point time, | std::string TimeString(std::chrono::system_clock::time_point time, | ||||||
|  |                        ClockFormat                           clockFormat, | ||||||
|                        const time_zone*                      timeZone, |                        const time_zone*                      timeZone, | ||||||
|                        bool                                  epochValid) |                        bool                                  epochValid) | ||||||
| { | { | ||||||
|  | @ -49,12 +66,27 @@ std::string TimeString(std::chrono::system_clock::time_point time, | ||||||
|    { |    { | ||||||
|       if (timeZone != nullptr) |       if (timeZone != nullptr) | ||||||
|       { |       { | ||||||
|          zoned_time zt = {current_zone(), timeInSeconds}; |          zoned_time zt = {timeZone, timeInSeconds}; | ||||||
|          os << zt; | 
 | ||||||
|  |          if (clockFormat == ClockFormat::_24Hour) | ||||||
|  |          { | ||||||
|  |             os << format("{:%Y-%m-%d %H:%M:%S %Z}", zt); | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|          os << timeInSeconds; |             os << format("{:%Y-%m-%d %I:%M:%S %p %Z}", zt); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          if (clockFormat == ClockFormat::_24Hour) | ||||||
|  |          { | ||||||
|  |             os << format("{:%Y-%m-%d %H:%M:%S %Z}", timeInSeconds); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             os << format("{:%Y-%m-%d %I:%M:%S %p %Z}", timeInSeconds); | ||||||
|  |          } | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat