fusesell 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fusesell might be problematic. Click here for more details.

@@ -0,0 +1,914 @@
1
+ """
2
+ Timezone Detection Utility
3
+ Detect customer timezone from address or other information
4
+ """
5
+
6
+ import re
7
+ import logging
8
+ from typing import Optional, Dict, Any
9
+
10
+
11
+ class TimezoneDetector:
12
+ """Utility for detecting customer timezone from various inputs."""
13
+
14
+ def __init__(self):
15
+ self.logger = logging.getLogger(__name__)
16
+
17
+ # Common timezone mappings
18
+ self.country_timezones = {
19
+ # North America
20
+ 'usa': 'America/New_York',
21
+ 'united states': 'America/New_York',
22
+ 'us': 'America/New_York',
23
+ 'canada': 'America/Toronto',
24
+ 'mexico': 'America/Mexico_City',
25
+
26
+ # Europe
27
+ 'uk': 'Europe/London',
28
+ 'united kingdom': 'Europe/London',
29
+ 'england': 'Europe/London',
30
+ 'france': 'Europe/Paris',
31
+ 'germany': 'Europe/Berlin',
32
+ 'spain': 'Europe/Madrid',
33
+ 'italy': 'Europe/Rome',
34
+ 'netherlands': 'Europe/Amsterdam',
35
+ 'sweden': 'Europe/Stockholm',
36
+ 'norway': 'Europe/Oslo',
37
+ 'denmark': 'Europe/Copenhagen',
38
+ 'finland': 'Europe/Helsinki',
39
+ 'poland': 'Europe/Warsaw',
40
+ 'russia': 'Europe/Moscow',
41
+
42
+ # Asia Pacific
43
+ 'japan': 'Asia/Tokyo',
44
+ 'china': 'Asia/Shanghai',
45
+ 'india': 'Asia/Kolkata',
46
+ 'singapore': 'Asia/Singapore',
47
+ 'thailand': 'Asia/Bangkok',
48
+ 'vietnam': 'Asia/Ho_Chi_Minh',
49
+ 'philippines': 'Asia/Manila',
50
+ 'indonesia': 'Asia/Jakarta',
51
+ 'malaysia': 'Asia/Kuala_Lumpur',
52
+ 'south korea': 'Asia/Seoul',
53
+ 'korea': 'Asia/Seoul',
54
+ 'australia': 'Australia/Sydney',
55
+ 'new zealand': 'Pacific/Auckland',
56
+
57
+ # Others
58
+ 'brazil': 'America/Sao_Paulo',
59
+ 'argentina': 'America/Argentina/Buenos_Aires',
60
+ 'south africa': 'Africa/Johannesburg',
61
+ 'egypt': 'Africa/Cairo',
62
+ 'israel': 'Asia/Jerusalem',
63
+ 'uae': 'Asia/Dubai',
64
+ 'saudi arabia': 'Asia/Riyadh'
65
+ }
66
+
67
+ # US state timezones
68
+ self.us_state_timezones = {
69
+ # Eastern Time
70
+ 'new york': 'America/New_York',
71
+ 'florida': 'America/New_York',
72
+ 'georgia': 'America/New_York',
73
+ 'virginia': 'America/New_York',
74
+ 'north carolina': 'America/New_York',
75
+ 'south carolina': 'America/New_York',
76
+ 'pennsylvania': 'America/New_York',
77
+ 'new jersey': 'America/New_York',
78
+ 'massachusetts': 'America/New_York',
79
+ 'connecticut': 'America/New_York',
80
+ 'maryland': 'America/New_York',
81
+ 'delaware': 'America/New_York',
82
+ 'maine': 'America/New_York',
83
+ 'new hampshire': 'America/New_York',
84
+ 'vermont': 'America/New_York',
85
+ 'rhode island': 'America/New_York',
86
+
87
+ # Central Time
88
+ 'texas': 'America/Chicago',
89
+ 'illinois': 'America/Chicago',
90
+ 'wisconsin': 'America/Chicago',
91
+ 'minnesota': 'America/Chicago',
92
+ 'iowa': 'America/Chicago',
93
+ 'missouri': 'America/Chicago',
94
+ 'arkansas': 'America/Chicago',
95
+ 'louisiana': 'America/Chicago',
96
+ 'mississippi': 'America/Chicago',
97
+ 'alabama': 'America/Chicago',
98
+ 'tennessee': 'America/Chicago',
99
+ 'kentucky': 'America/Chicago',
100
+ 'oklahoma': 'America/Chicago',
101
+ 'kansas': 'America/Chicago',
102
+ 'nebraska': 'America/Chicago',
103
+ 'south dakota': 'America/Chicago',
104
+ 'north dakota': 'America/Chicago',
105
+
106
+ # Mountain Time
107
+ 'colorado': 'America/Denver',
108
+ 'utah': 'America/Denver',
109
+ 'wyoming': 'America/Denver',
110
+ 'montana': 'America/Denver',
111
+ 'new mexico': 'America/Denver',
112
+ 'arizona': 'America/Phoenix', # Arizona doesn't observe DST
113
+
114
+ # Pacific Time
115
+ 'california': 'America/Los_Angeles',
116
+ 'washington': 'America/Los_Angeles',
117
+ 'oregon': 'America/Los_Angeles',
118
+ 'nevada': 'America/Los_Angeles',
119
+
120
+ # Alaska & Hawaii
121
+ 'alaska': 'America/Anchorage',
122
+ 'hawaii': 'Pacific/Honolulu'
123
+ }
124
+
125
+ # City timezones
126
+ self.city_timezones = {
127
+ # Major US cities
128
+ 'new york': 'America/New_York',
129
+ 'los angeles': 'America/Los_Angeles',
130
+ 'chicago': 'America/Chicago',
131
+ 'houston': 'America/Chicago',
132
+ 'phoenix': 'America/Phoenix',
133
+ 'philadelphia': 'America/New_York',
134
+ 'san antonio': 'America/Chicago',
135
+ 'san diego': 'America/Los_Angeles',
136
+ 'dallas': 'America/Chicago',
137
+ 'san jose': 'America/Los_Angeles',
138
+ 'austin': 'America/Chicago',
139
+ 'jacksonville': 'America/New_York',
140
+ 'san francisco': 'America/Los_Angeles',
141
+ 'columbus': 'America/New_York',
142
+ 'charlotte': 'America/New_York',
143
+ 'fort worth': 'America/Chicago',
144
+ 'detroit': 'America/New_York',
145
+ 'el paso': 'America/Denver',
146
+ 'memphis': 'America/Chicago',
147
+ 'seattle': 'America/Los_Angeles',
148
+ 'denver': 'America/Denver',
149
+ 'washington': 'America/New_York',
150
+ 'boston': 'America/New_York',
151
+ 'nashville': 'America/Chicago',
152
+ 'baltimore': 'America/New_York',
153
+ 'oklahoma city': 'America/Chicago',
154
+ 'portland': 'America/Los_Angeles',
155
+ 'las vegas': 'America/Los_Angeles',
156
+ 'milwaukee': 'America/Chicago',
157
+ 'albuquerque': 'America/Denver',
158
+ 'tucson': 'America/Phoenix',
159
+ 'fresno': 'America/Los_Angeles',
160
+ 'sacramento': 'America/Los_Angeles',
161
+ 'mesa': 'America/Phoenix',
162
+ 'kansas city': 'America/Chicago',
163
+ 'atlanta': 'America/New_York',
164
+ 'long beach': 'America/Los_Angeles',
165
+ 'colorado springs': 'America/Denver',
166
+ 'raleigh': 'America/New_York',
167
+ 'miami': 'America/New_York',
168
+ 'virginia beach': 'America/New_York',
169
+ 'omaha': 'America/Chicago',
170
+ 'oakland': 'America/Los_Angeles',
171
+ 'minneapolis': 'America/Chicago',
172
+ 'tulsa': 'America/Chicago',
173
+ 'arlington': 'America/Chicago',
174
+ 'tampa': 'America/New_York',
175
+ 'new orleans': 'America/Chicago',
176
+ 'wichita': 'America/Chicago',
177
+ 'cleveland': 'America/New_York',
178
+ 'bakersfield': 'America/Los_Angeles',
179
+ 'aurora': 'America/Denver',
180
+ 'anaheim': 'America/Los_Angeles',
181
+ 'honolulu': 'Pacific/Honolulu',
182
+ 'santa ana': 'America/Los_Angeles',
183
+ 'corpus christi': 'America/Chicago',
184
+ 'riverside': 'America/Los_Angeles',
185
+ 'lexington': 'America/New_York',
186
+ 'stockton': 'America/Los_Angeles',
187
+ 'st. paul': 'America/Chicago',
188
+ 'cincinnati': 'America/New_York',
189
+ 'anchorage': 'America/Anchorage',
190
+ 'henderson': 'America/Los_Angeles',
191
+ 'greensboro': 'America/New_York',
192
+ 'plano': 'America/Chicago',
193
+ 'newark': 'America/New_York',
194
+ 'lincoln': 'America/Chicago',
195
+ 'buffalo': 'America/New_York',
196
+ 'jersey city': 'America/New_York',
197
+ 'chula vista': 'America/Los_Angeles',
198
+ 'fort wayne': 'America/New_York',
199
+ 'orlando': 'America/New_York',
200
+ 'st. petersburg': 'America/New_York',
201
+ 'chandler': 'America/Phoenix',
202
+ 'laredo': 'America/Chicago',
203
+ 'norfolk': 'America/New_York',
204
+ 'durham': 'America/New_York',
205
+ 'madison': 'America/Chicago',
206
+ 'lubbock': 'America/Chicago',
207
+ 'irvine': 'America/Los_Angeles',
208
+ 'winston-salem': 'America/New_York',
209
+ 'glendale': 'America/Phoenix',
210
+ 'garland': 'America/Chicago',
211
+ 'hialeah': 'America/New_York',
212
+ 'reno': 'America/Los_Angeles',
213
+ 'chesapeake': 'America/New_York',
214
+ 'gilbert': 'America/Phoenix',
215
+ 'baton rouge': 'America/Chicago',
216
+ 'irving': 'America/Chicago',
217
+ 'scottsdale': 'America/Phoenix',
218
+ 'north las vegas': 'America/Los_Angeles',
219
+ 'fremont': 'America/Los_Angeles',
220
+ 'boise': 'America/Boise',
221
+ 'richmond': 'America/New_York',
222
+ 'san bernardino': 'America/Los_Angeles',
223
+ 'birmingham': 'America/Chicago',
224
+ 'spokane': 'America/Los_Angeles',
225
+ 'rochester': 'America/New_York',
226
+ 'des moines': 'America/Chicago',
227
+ 'modesto': 'America/Los_Angeles',
228
+ 'fayetteville': 'America/New_York',
229
+ 'tacoma': 'America/Los_Angeles',
230
+ 'oxnard': 'America/Los_Angeles',
231
+ 'fontana': 'America/Los_Angeles',
232
+ 'columbus': 'America/Chicago',
233
+ 'montgomery': 'America/Chicago',
234
+ 'moreno valley': 'America/Los_Angeles',
235
+ 'shreveport': 'America/Chicago',
236
+ 'aurora': 'America/Chicago',
237
+ 'yonkers': 'America/New_York',
238
+ 'akron': 'America/New_York',
239
+ 'huntington beach': 'America/Los_Angeles',
240
+ 'little rock': 'America/Chicago',
241
+ 'augusta': 'America/New_York',
242
+ 'amarillo': 'America/Chicago',
243
+ 'glendale': 'America/Los_Angeles',
244
+ 'mobile': 'America/Chicago',
245
+ 'grand rapids': 'America/New_York',
246
+ 'salt lake city': 'America/Denver',
247
+ 'tallahassee': 'America/New_York',
248
+ 'huntsville': 'America/Chicago',
249
+ 'grand prairie': 'America/Chicago',
250
+ 'knoxville': 'America/New_York',
251
+ 'worcester': 'America/New_York',
252
+ 'newport news': 'America/New_York',
253
+ 'brownsville': 'America/Chicago',
254
+ 'overland park': 'America/Chicago',
255
+ 'santa clarita': 'America/Los_Angeles',
256
+ 'providence': 'America/New_York',
257
+ 'garden grove': 'America/Los_Angeles',
258
+ 'chattanooga': 'America/New_York',
259
+ 'oceanside': 'America/Los_Angeles',
260
+ 'jackson': 'America/Chicago',
261
+ 'fort lauderdale': 'America/New_York',
262
+ 'santa rosa': 'America/Los_Angeles',
263
+ 'rancho cucamonga': 'America/Los_Angeles',
264
+ 'port st. lucie': 'America/New_York',
265
+ 'tempe': 'America/Phoenix',
266
+ 'ontario': 'America/Los_Angeles',
267
+ 'vancouver': 'America/Los_Angeles',
268
+ 'cape coral': 'America/New_York',
269
+ 'sioux falls': 'America/Chicago',
270
+ 'springfield': 'America/Chicago',
271
+ 'peoria': 'America/Chicago',
272
+ 'pembroke pines': 'America/New_York',
273
+ 'elk grove': 'America/Los_Angeles',
274
+ 'salem': 'America/Los_Angeles',
275
+ 'lancaster': 'America/Los_Angeles',
276
+ 'corona': 'America/Los_Angeles',
277
+ 'eugene': 'America/Los_Angeles',
278
+ 'palmdale': 'America/Los_Angeles',
279
+ 'salinas': 'America/Los_Angeles',
280
+ 'springfield': 'America/New_York',
281
+ 'pasadena': 'America/Los_Angeles',
282
+ 'fort collins': 'America/Denver',
283
+ 'hayward': 'America/Los_Angeles',
284
+ 'pomona': 'America/Los_Angeles',
285
+ 'cary': 'America/New_York',
286
+ 'rockford': 'America/Chicago',
287
+ 'alexandria': 'America/New_York',
288
+ 'escondido': 'America/Los_Angeles',
289
+ 'mckinney': 'America/Chicago',
290
+ 'kansas city': 'America/Chicago',
291
+ 'joliet': 'America/Chicago',
292
+ 'sunnyvale': 'America/Los_Angeles',
293
+ 'torrance': 'America/Los_Angeles',
294
+ 'bridgeport': 'America/New_York',
295
+ 'lakewood': 'America/Denver',
296
+ 'hollywood': 'America/New_York',
297
+ 'paterson': 'America/New_York',
298
+ 'naperville': 'America/Chicago',
299
+ 'syracuse': 'America/New_York',
300
+ 'mesquite': 'America/Chicago',
301
+ 'dayton': 'America/New_York',
302
+ 'savannah': 'America/New_York',
303
+ 'clarksville': 'America/Chicago',
304
+ 'orange': 'America/Los_Angeles',
305
+ 'pasadena': 'America/Chicago',
306
+ 'fullerton': 'America/Los_Angeles',
307
+ 'killeen': 'America/Chicago',
308
+ 'frisco': 'America/Chicago',
309
+ 'hampton': 'America/New_York',
310
+ 'mcallen': 'America/Chicago',
311
+ 'warren': 'America/New_York',
312
+ 'west valley city': 'America/Denver',
313
+ 'columbia': 'America/New_York',
314
+ 'olathe': 'America/Chicago',
315
+ 'sterling heights': 'America/New_York',
316
+ 'new haven': 'America/New_York',
317
+ 'miramar': 'America/New_York',
318
+ 'waco': 'America/Chicago',
319
+ 'thousand oaks': 'America/Los_Angeles',
320
+ 'cedar rapids': 'America/Chicago',
321
+ 'charleston': 'America/New_York',
322
+ 'visalia': 'America/Los_Angeles',
323
+ 'topeka': 'America/Chicago',
324
+ 'elizabeth': 'America/New_York',
325
+ 'gainesville': 'America/New_York',
326
+ 'thornton': 'America/Denver',
327
+ 'roseville': 'America/Los_Angeles',
328
+ 'carrollton': 'America/Chicago',
329
+ 'coral springs': 'America/New_York',
330
+ 'stamford': 'America/New_York',
331
+ 'simi valley': 'America/Los_Angeles',
332
+ 'concord': 'America/Los_Angeles',
333
+ 'hartford': 'America/New_York',
334
+ 'kent': 'America/Los_Angeles',
335
+ 'lafayette': 'America/Chicago',
336
+ 'midland': 'America/Chicago',
337
+ 'surprise': 'America/Phoenix',
338
+ 'denton': 'America/Chicago',
339
+ 'victorville': 'America/Los_Angeles',
340
+ 'evansville': 'America/Chicago',
341
+ 'santa clara': 'America/Los_Angeles',
342
+ 'abilene': 'America/Chicago',
343
+ 'athens': 'America/New_York',
344
+ 'vallejo': 'America/Los_Angeles',
345
+ 'allentown': 'America/New_York',
346
+ 'norman': 'America/Chicago',
347
+ 'beaumont': 'America/Chicago',
348
+ 'independence': 'America/Chicago',
349
+ 'murfreesboro': 'America/Chicago',
350
+ 'ann arbor': 'America/New_York',
351
+ 'fargo': 'America/Chicago',
352
+ 'temecula': 'America/Los_Angeles',
353
+ 'bellevue': 'America/Los_Angeles',
354
+ 'westminster': 'America/Denver',
355
+ 'arvada': 'America/Denver',
356
+ 'clearwater': 'America/New_York',
357
+ 'richardson': 'America/Chicago',
358
+ 'rochester': 'America/Chicago',
359
+ 'pueblo': 'America/Denver',
360
+ 'carlsbad': 'America/Los_Angeles',
361
+ 'fairfield': 'America/Los_Angeles',
362
+ 'west palm beach': 'America/New_York',
363
+ 'lowell': 'America/New_York',
364
+ 'billings': 'America/Denver',
365
+ 'san mateo': 'America/Los_Angeles',
366
+ 'el monte': 'America/Los_Angeles',
367
+ 'jurupa valley': 'America/Los_Angeles',
368
+ 'las cruces': 'America/Denver',
369
+ 'burbank': 'America/Los_Angeles',
370
+ 'fort smith': 'America/Chicago',
371
+ 'albany': 'America/New_York',
372
+ 'clovis': 'America/Los_Angeles',
373
+ 'inglewood': 'America/Los_Angeles',
374
+ 'sandy': 'America/Denver',
375
+ 'sandy springs': 'America/New_York',
376
+ 'hillsboro': 'America/Los_Angeles',
377
+ 'waterbury': 'America/New_York',
378
+ 'santa maria': 'America/Los_Angeles',
379
+ 'boulder': 'America/Denver',
380
+ 'greeley': 'America/Denver',
381
+ 'daly city': 'America/Los_Angeles',
382
+ 'meridian': 'America/Boise',
383
+ 'lewisville': 'America/Chicago',
384
+ 'davie': 'America/New_York',
385
+ 'west jordan': 'America/Denver',
386
+ 'league city': 'America/Chicago',
387
+ 'tyler': 'America/Chicago',
388
+ 'pearland': 'America/Chicago',
389
+ 'college station': 'America/Chicago',
390
+ 'kenosha': 'America/Chicago',
391
+ 'sandy': 'America/Denver',
392
+ 'missoula': 'America/Denver',
393
+ 'richardson': 'America/Chicago',
394
+ 'spokane valley': 'America/Los_Angeles',
395
+ 'arvada': 'America/Denver',
396
+ 'centennial': 'America/Denver',
397
+ 'roswell': 'America/New_York',
398
+ 'rialto': 'America/Los_Angeles',
399
+ 'el cajon': 'America/Los_Angeles',
400
+ 'las vegas': 'America/Los_Angeles',
401
+ 'miami gardens': 'America/New_York',
402
+ 'burbank': 'America/Los_Angeles',
403
+ 'south bend': 'America/New_York',
404
+ 'renton': 'America/Los_Angeles',
405
+ 'berkeley': 'America/Los_Angeles',
406
+ 'pompano beach': 'America/New_York',
407
+ 'woodbridge': 'America/New_York',
408
+ 'reading': 'America/New_York',
409
+ 'richmond': 'America/Los_Angeles',
410
+ 'beaverton': 'America/Los_Angeles',
411
+ 'broken arrow': 'America/Chicago',
412
+ 'west palm beach': 'America/New_York',
413
+ 'cambridge': 'America/New_York',
414
+ 'clearwater': 'America/New_York',
415
+ 'west valley city': 'America/Denver',
416
+ 'round rock': 'America/Chicago',
417
+ 'lakeland': 'America/New_York',
418
+ 'livermore': 'America/Los_Angeles',
419
+ 'sugar land': 'America/Chicago',
420
+ 'longmont': 'America/Denver',
421
+ 'boca raton': 'America/New_York',
422
+ 'san mateo': 'America/Los_Angeles',
423
+ 'hesperia': 'America/Los_Angeles',
424
+ 'baldwin park': 'America/Los_Angeles',
425
+ 'chico': 'America/Los_Angeles',
426
+ 'odessa': 'America/Chicago',
427
+ 'roanoke': 'America/New_York',
428
+ 'carson': 'America/Los_Angeles',
429
+ 'fort collins': 'America/Denver',
430
+ 'albany': 'America/New_York',
431
+ 'danbury': 'America/New_York',
432
+ 'compton': 'America/Los_Angeles',
433
+ 'san leandro': 'America/Los_Angeles',
434
+ 'tuscaloosa': 'America/Chicago',
435
+ 'spokane': 'America/Los_Angeles',
436
+ 'antioch': 'America/Los_Angeles',
437
+ 'high point': 'America/New_York',
438
+ 'norwalk': 'America/Los_Angeles',
439
+ 'centennial': 'America/Denver',
440
+ 'everett': 'America/Los_Angeles',
441
+ 'elgin': 'America/Chicago',
442
+ 'wichita falls': 'America/Chicago',
443
+ 'erie': 'America/New_York',
444
+ 'frederick': 'America/New_York',
445
+ 'gresham': 'America/Los_Angeles',
446
+ 'santa barbara': 'America/Los_Angeles',
447
+ 'pueblo': 'America/Denver',
448
+ 'dearborn': 'America/New_York',
449
+ 'lawton': 'America/Chicago',
450
+ 'san angelo': 'America/Chicago',
451
+ 'murrieta': 'America/Los_Angeles',
452
+ 'rochester': 'America/Chicago',
453
+ 'champaign': 'America/Chicago',
454
+ 'ogden': 'America/Denver',
455
+ 'concord': 'America/New_York',
456
+ 'denton': 'America/Chicago',
457
+ 'davenport': 'America/Chicago',
458
+ 'garden grove': 'America/Los_Angeles',
459
+ 'yakima': 'America/Los_Angeles',
460
+ 'new bedford': 'America/New_York',
461
+ 'south gate': 'America/Los_Angeles',
462
+ 'st. joseph': 'America/Chicago',
463
+ 'kalamazoo': 'America/New_York',
464
+ 'birmingham': 'America/New_York',
465
+ 'racine': 'America/Chicago',
466
+ 'orem': 'America/Denver',
467
+ 'flint': 'America/New_York',
468
+ 'las cruces': 'America/Denver',
469
+ 'springfield': 'America/Chicago',
470
+ 'brockton': 'America/New_York',
471
+ 'fayetteville': 'America/Chicago',
472
+ 'carson city': 'America/Los_Angeles',
473
+ 'santa monica': 'America/Los_Angeles',
474
+ 'fall river': 'America/New_York',
475
+ 'lynchburg': 'America/New_York',
476
+ 'nampa': 'America/Boise',
477
+ 'troy': 'America/New_York',
478
+ 'quincy': 'America/New_York',
479
+ 'duluth': 'America/Chicago',
480
+ 'chula vista': 'America/Los_Angeles',
481
+ 'dayton': 'America/New_York',
482
+ 'springfield': 'America/New_York',
483
+ 'orange': 'America/Los_Angeles',
484
+ 'akron': 'America/New_York',
485
+ 'huntington beach': 'America/Los_Angeles',
486
+ 'little rock': 'America/Chicago',
487
+ 'augusta': 'America/New_York',
488
+ 'amarillo': 'America/Chicago',
489
+ 'glendale': 'America/Los_Angeles',
490
+ 'mobile': 'America/Chicago',
491
+ 'grand rapids': 'America/New_York',
492
+ 'salt lake city': 'America/Denver',
493
+ 'tallahassee': 'America/New_York',
494
+ 'huntsville': 'America/Chicago',
495
+ 'grand prairie': 'America/Chicago',
496
+ 'knoxville': 'America/New_York',
497
+ 'worcester': 'America/New_York',
498
+ 'newport news': 'America/New_York',
499
+ 'brownsville': 'America/Chicago',
500
+ 'overland park': 'America/Chicago',
501
+ 'santa clarita': 'America/Los_Angeles',
502
+ 'providence': 'America/New_York',
503
+ 'garden grove': 'America/Los_Angeles',
504
+ 'chattanooga': 'America/New_York',
505
+ 'oceanside': 'America/Los_Angeles',
506
+ 'jackson': 'America/Chicago',
507
+ 'fort lauderdale': 'America/New_York',
508
+ 'santa rosa': 'America/Los_Angeles',
509
+ 'rancho cucamonga': 'America/Los_Angeles',
510
+ 'port st. lucie': 'America/New_York',
511
+ 'tempe': 'America/Phoenix',
512
+ 'ontario': 'America/Los_Angeles',
513
+ 'vancouver': 'America/Los_Angeles',
514
+ 'cape coral': 'America/New_York',
515
+ 'sioux falls': 'America/Chicago',
516
+ 'springfield': 'America/Chicago',
517
+ 'peoria': 'America/Chicago',
518
+ 'pembroke pines': 'America/New_York',
519
+ 'elk grove': 'America/Los_Angeles',
520
+ 'salem': 'America/Los_Angeles',
521
+ 'lancaster': 'America/Los_Angeles',
522
+ 'corona': 'America/Los_Angeles',
523
+ 'eugene': 'America/Los_Angeles',
524
+ 'palmdale': 'America/Los_Angeles',
525
+ 'salinas': 'America/Los_Angeles',
526
+ 'springfield': 'America/New_York',
527
+ 'pasadena': 'America/Los_Angeles',
528
+ 'fort collins': 'America/Denver',
529
+ 'hayward': 'America/Los_Angeles',
530
+ 'pomona': 'America/Los_Angeles',
531
+ 'cary': 'America/New_York',
532
+ 'rockford': 'America/Chicago',
533
+ 'alexandria': 'America/New_York',
534
+ 'escondido': 'America/Los_Angeles',
535
+ 'mckinney': 'America/Chicago',
536
+ 'kansas city': 'America/Chicago',
537
+ 'joliet': 'America/Chicago',
538
+ 'sunnyvale': 'America/Los_Angeles',
539
+ 'torrance': 'America/Los_Angeles',
540
+ 'bridgeport': 'America/New_York',
541
+ 'lakewood': 'America/Denver',
542
+ 'hollywood': 'America/New_York',
543
+ 'paterson': 'America/New_York',
544
+ 'naperville': 'America/Chicago',
545
+ 'syracuse': 'America/New_York',
546
+ 'mesquite': 'America/Chicago',
547
+ 'dayton': 'America/New_York',
548
+ 'savannah': 'America/New_York',
549
+ 'clarksville': 'America/Chicago',
550
+ 'orange': 'America/Los_Angeles',
551
+ 'pasadena': 'America/Chicago',
552
+ 'fullerton': 'America/Los_Angeles',
553
+ 'killeen': 'America/Chicago',
554
+ 'frisco': 'America/Chicago',
555
+ 'hampton': 'America/New_York',
556
+ 'mcallen': 'America/Chicago',
557
+ 'warren': 'America/New_York',
558
+ 'west valley city': 'America/Denver',
559
+ 'columbia': 'America/New_York',
560
+ 'olathe': 'America/Chicago',
561
+ 'sterling heights': 'America/New_York',
562
+ 'new haven': 'America/New_York',
563
+ 'miramar': 'America/New_York',
564
+ 'waco': 'America/Chicago',
565
+ 'thousand oaks': 'America/Los_Angeles',
566
+ 'cedar rapids': 'America/Chicago',
567
+ 'charleston': 'America/New_York',
568
+ 'visalia': 'America/Los_Angeles',
569
+ 'topeka': 'America/Chicago',
570
+ 'elizabeth': 'America/New_York',
571
+ 'gainesville': 'America/New_York',
572
+ 'thornton': 'America/Denver',
573
+ 'roseville': 'America/Los_Angeles',
574
+ 'carrollton': 'America/Chicago',
575
+ 'coral springs': 'America/New_York',
576
+ 'stamford': 'America/New_York',
577
+ 'simi valley': 'America/Los_Angeles',
578
+ 'concord': 'America/Los_Angeles',
579
+ 'hartford': 'America/New_York',
580
+ 'kent': 'America/Los_Angeles',
581
+ 'lafayette': 'America/Chicago',
582
+ 'midland': 'America/Chicago',
583
+ 'surprise': 'America/Phoenix',
584
+ 'denton': 'America/Chicago',
585
+ 'victorville': 'America/Los_Angeles',
586
+ 'evansville': 'America/Chicago',
587
+ 'santa clara': 'America/Los_Angeles',
588
+ 'abilene': 'America/Chicago',
589
+ 'athens': 'America/New_York',
590
+ 'vallejo': 'America/Los_Angeles',
591
+ 'allentown': 'America/New_York',
592
+ 'norman': 'America/Chicago',
593
+ 'beaumont': 'America/Chicago',
594
+ 'independence': 'America/Chicago',
595
+ 'murfreesboro': 'America/Chicago',
596
+ 'ann arbor': 'America/New_York',
597
+ 'fargo': 'America/Chicago',
598
+ 'temecula': 'America/Los_Angeles',
599
+ 'bellevue': 'America/Los_Angeles',
600
+ 'westminster': 'America/Denver',
601
+ 'arvada': 'America/Denver',
602
+ 'clearwater': 'America/New_York',
603
+ 'richardson': 'America/Chicago',
604
+ 'rochester': 'America/Chicago',
605
+ 'pueblo': 'America/Denver',
606
+ 'carlsbad': 'America/Los_Angeles',
607
+ 'fairfield': 'America/Los_Angeles',
608
+ 'west palm beach': 'America/New_York',
609
+ 'lowell': 'America/New_York',
610
+ 'billings': 'America/Denver',
611
+ 'san mateo': 'America/Los_Angeles',
612
+ 'el monte': 'America/Los_Angeles',
613
+ 'jurupa valley': 'America/Los_Angeles',
614
+ 'las cruces': 'America/Denver',
615
+ 'burbank': 'America/Los_Angeles',
616
+ 'fort smith': 'America/Chicago',
617
+ 'albany': 'America/New_York',
618
+ 'clovis': 'America/Los_Angeles',
619
+ 'inglewood': 'America/Los_Angeles',
620
+ 'sandy': 'America/Denver',
621
+ 'sandy springs': 'America/New_York',
622
+ 'hillsboro': 'America/Los_Angeles',
623
+ 'waterbury': 'America/New_York',
624
+ 'santa maria': 'America/Los_Angeles',
625
+ 'boulder': 'America/Denver',
626
+ 'greeley': 'America/Denver',
627
+ 'daly city': 'America/Los_Angeles',
628
+ 'meridian': 'America/Boise',
629
+ 'lewisville': 'America/Chicago',
630
+ 'davie': 'America/New_York',
631
+ 'west jordan': 'America/Denver',
632
+ 'league city': 'America/Chicago',
633
+ 'tyler': 'America/Chicago',
634
+ 'pearland': 'America/Chicago',
635
+ 'college station': 'America/Chicago',
636
+ 'kenosha': 'America/Chicago',
637
+ 'sandy': 'America/Denver',
638
+ 'missoula': 'America/Denver',
639
+ 'richardson': 'America/Chicago',
640
+ 'spokane valley': 'America/Los_Angeles',
641
+ 'arvada': 'America/Denver',
642
+ 'centennial': 'America/Denver',
643
+ 'roswell': 'America/New_York',
644
+ 'rialto': 'America/Los_Angeles',
645
+ 'el cajon': 'America/Los_Angeles',
646
+ 'las vegas': 'America/Los_Angeles',
647
+ 'miami gardens': 'America/New_York',
648
+ 'burbank': 'America/Los_Angeles',
649
+ 'south bend': 'America/New_York',
650
+ 'renton': 'America/Los_Angeles',
651
+ 'berkeley': 'America/Los_Angeles',
652
+ 'pompano beach': 'America/New_York',
653
+ 'woodbridge': 'America/New_York',
654
+ 'reading': 'America/New_York',
655
+ 'richmond': 'America/Los_Angeles',
656
+ 'beaverton': 'America/Los_Angeles',
657
+ 'broken arrow': 'America/Chicago',
658
+ 'west palm beach': 'America/New_York',
659
+ 'cambridge': 'America/New_York',
660
+ 'clearwater': 'America/New_York',
661
+ 'west valley city': 'America/Denver',
662
+ 'round rock': 'America/Chicago',
663
+ 'lakeland': 'America/New_York',
664
+ 'livermore': 'America/Los_Angeles',
665
+ 'sugar land': 'America/Chicago',
666
+ 'longmont': 'America/Denver',
667
+ 'boca raton': 'America/New_York',
668
+ 'san mateo': 'America/Los_Angeles',
669
+ 'hesperia': 'America/Los_Angeles',
670
+ 'baldwin park': 'America/Los_Angeles',
671
+ 'chico': 'America/Los_Angeles',
672
+ 'odessa': 'America/Chicago',
673
+ 'roanoke': 'America/New_York',
674
+ 'carson': 'America/Los_Angeles',
675
+ 'fort collins': 'America/Denver',
676
+ 'albany': 'America/New_York',
677
+ 'danbury': 'America/New_York',
678
+ 'compton': 'America/Los_Angeles',
679
+ 'san leandro': 'America/Los_Angeles',
680
+ 'tuscaloosa': 'America/Chicago',
681
+ 'spokane': 'America/Los_Angeles',
682
+ 'antioch': 'America/Los_Angeles',
683
+ 'high point': 'America/New_York',
684
+ 'norwalk': 'America/Los_Angeles',
685
+ 'centennial': 'America/Denver',
686
+ 'everett': 'America/Los_Angeles',
687
+ 'elgin': 'America/Chicago',
688
+ 'wichita falls': 'America/Chicago',
689
+ 'erie': 'America/New_York',
690
+ 'frederick': 'America/New_York',
691
+ 'gresham': 'America/Los_Angeles',
692
+ 'santa barbara': 'America/Los_Angeles',
693
+ 'pueblo': 'America/Denver',
694
+ 'dearborn': 'America/New_York',
695
+ 'lawton': 'America/Chicago',
696
+ 'san angelo': 'America/Chicago',
697
+ 'murrieta': 'America/Los_Angeles',
698
+ 'rochester': 'America/Chicago',
699
+ 'champaign': 'America/Chicago',
700
+ 'ogden': 'America/Denver',
701
+ 'concord': 'America/New_York',
702
+ 'denton': 'America/Chicago',
703
+ 'davenport': 'America/Chicago',
704
+ 'garden grove': 'America/Los_Angeles',
705
+ 'yakima': 'America/Los_Angeles',
706
+ 'new bedford': 'America/New_York',
707
+ 'south gate': 'America/Los_Angeles',
708
+ 'st. joseph': 'America/Chicago',
709
+ 'kalamazoo': 'America/New_York',
710
+ 'birmingham': 'America/New_York',
711
+ 'racine': 'America/Chicago',
712
+ 'orem': 'America/Denver',
713
+ 'flint': 'America/New_York',
714
+ 'las cruces': 'America/Denver',
715
+ 'springfield': 'America/Chicago',
716
+ 'brockton': 'America/New_York',
717
+ 'fayetteville': 'America/Chicago',
718
+ 'carson city': 'America/Los_Angeles',
719
+ 'santa monica': 'America/Los_Angeles',
720
+ 'fall river': 'America/New_York',
721
+ 'lynchburg': 'America/New_York',
722
+ 'nampa': 'America/Boise',
723
+ 'troy': 'America/New_York',
724
+ 'quincy': 'America/New_York',
725
+ 'duluth': 'America/Chicago',
726
+
727
+ # International cities
728
+ 'london': 'Europe/London',
729
+ 'paris': 'Europe/Paris',
730
+ 'berlin': 'Europe/Berlin',
731
+ 'madrid': 'Europe/Madrid',
732
+ 'rome': 'Europe/Rome',
733
+ 'amsterdam': 'Europe/Amsterdam',
734
+ 'stockholm': 'Europe/Stockholm',
735
+ 'oslo': 'Europe/Oslo',
736
+ 'copenhagen': 'Europe/Copenhagen',
737
+ 'helsinki': 'Europe/Helsinki',
738
+ 'warsaw': 'Europe/Warsaw',
739
+ 'moscow': 'Europe/Moscow',
740
+ 'tokyo': 'Asia/Tokyo',
741
+ 'shanghai': 'Asia/Shanghai',
742
+ 'beijing': 'Asia/Shanghai',
743
+ 'mumbai': 'Asia/Kolkata',
744
+ 'delhi': 'Asia/Kolkata',
745
+ 'bangalore': 'Asia/Kolkata',
746
+ 'singapore': 'Asia/Singapore',
747
+ 'bangkok': 'Asia/Bangkok',
748
+ 'ho chi minh city': 'Asia/Ho_Chi_Minh',
749
+ 'saigon': 'Asia/Ho_Chi_Minh',
750
+ 'manila': 'Asia/Manila',
751
+ 'jakarta': 'Asia/Jakarta',
752
+ 'kuala lumpur': 'Asia/Kuala_Lumpur',
753
+ 'seoul': 'Asia/Seoul',
754
+ 'sydney': 'Australia/Sydney',
755
+ 'melbourne': 'Australia/Melbourne',
756
+ 'auckland': 'Pacific/Auckland',
757
+ 'sao paulo': 'America/Sao_Paulo',
758
+ 'buenos aires': 'America/Argentina/Buenos_Aires',
759
+ 'johannesburg': 'Africa/Johannesburg',
760
+ 'cairo': 'Africa/Cairo',
761
+ 'tel aviv': 'Asia/Jerusalem',
762
+ 'dubai': 'Asia/Dubai',
763
+ 'riyadh': 'Asia/Riyadh',
764
+ 'toronto': 'America/Toronto',
765
+ 'vancouver': 'America/Vancouver',
766
+ 'montreal': 'America/Toronto',
767
+ 'mexico city': 'America/Mexico_City'
768
+ }
769
+
770
+ def detect_timezone(self, customer_data: Dict[str, Any]) -> str:
771
+ """
772
+ Detect customer timezone from various data sources.
773
+
774
+ Args:
775
+ customer_data: Customer information
776
+
777
+ Returns:
778
+ Timezone string (e.g., 'America/New_York')
779
+ """
780
+ try:
781
+ # Check if timezone is explicitly provided
782
+ if 'customer_timezone' in customer_data:
783
+ return customer_data['customer_timezone']
784
+
785
+ # Try to extract from address
786
+ address_timezone = self._detect_from_address(customer_data)
787
+ if address_timezone:
788
+ return address_timezone
789
+
790
+ # Try to extract from company info
791
+ company_timezone = self._detect_from_company_info(customer_data)
792
+ if company_timezone:
793
+ return company_timezone
794
+
795
+ # Try to extract from contact info
796
+ contact_timezone = self._detect_from_contact_info(customer_data)
797
+ if contact_timezone:
798
+ return contact_timezone
799
+
800
+ # Default fallback
801
+ self.logger.info("Could not detect timezone, using default: Asia/Bangkok")
802
+ return 'Asia/Bangkok'
803
+
804
+ except Exception as e:
805
+ self.logger.error(f"Timezone detection failed: {str(e)}")
806
+ return 'Asia/Bangkok'
807
+
808
+ def _detect_from_address(self, customer_data: Dict[str, Any]) -> Optional[str]:
809
+ """Detect timezone from address information."""
810
+ try:
811
+ # Check various address fields
812
+ address_fields = [
813
+ customer_data.get('customer_address', ''),
814
+ customer_data.get('companyInfo', {}).get('address', ''),
815
+ customer_data.get('primaryContact', {}).get('address', ''),
816
+ customer_data.get('address', '')
817
+ ]
818
+
819
+ for address in address_fields:
820
+ if not address:
821
+ continue
822
+
823
+ address_lower = address.lower()
824
+
825
+ # Check for country matches
826
+ for country, timezone in self.country_timezones.items():
827
+ if country in address_lower:
828
+ self.logger.info(f"Detected timezone from country '{country}': {timezone}")
829
+ return timezone
830
+
831
+ # Check for US state matches
832
+ for state, timezone in self.us_state_timezones.items():
833
+ if state in address_lower:
834
+ self.logger.info(f"Detected timezone from US state '{state}': {timezone}")
835
+ return timezone
836
+
837
+ # Check for city matches
838
+ for city, timezone in self.city_timezones.items():
839
+ if city in address_lower:
840
+ self.logger.info(f"Detected timezone from city '{city}': {timezone}")
841
+ return timezone
842
+
843
+ return None
844
+
845
+ except Exception as e:
846
+ self.logger.error(f"Address timezone detection failed: {str(e)}")
847
+ return None
848
+
849
+ def _detect_from_company_info(self, customer_data: Dict[str, Any]) -> Optional[str]:
850
+ """Detect timezone from company information."""
851
+ try:
852
+ company_info = customer_data.get('companyInfo', {})
853
+
854
+ # Check company location fields
855
+ location_fields = [
856
+ company_info.get('location', ''),
857
+ company_info.get('headquarters', ''),
858
+ company_info.get('country', ''),
859
+ company_info.get('region', '')
860
+ ]
861
+
862
+ for location in location_fields:
863
+ if not location:
864
+ continue
865
+
866
+ location_lower = location.lower()
867
+
868
+ # Check for matches
869
+ for country, timezone in self.country_timezones.items():
870
+ if country in location_lower:
871
+ return timezone
872
+
873
+ for city, timezone in self.city_timezones.items():
874
+ if city in location_lower:
875
+ return timezone
876
+
877
+ return None
878
+
879
+ except Exception as e:
880
+ self.logger.error(f"Company info timezone detection failed: {str(e)}")
881
+ return None
882
+
883
+ def _detect_from_contact_info(self, customer_data: Dict[str, Any]) -> Optional[str]:
884
+ """Detect timezone from contact information."""
885
+ try:
886
+ contact_info = customer_data.get('primaryContact', {})
887
+
888
+ # Check contact location fields
889
+ location_fields = [
890
+ contact_info.get('location', ''),
891
+ contact_info.get('city', ''),
892
+ contact_info.get('country', '')
893
+ ]
894
+
895
+ for location in location_fields:
896
+ if not location:
897
+ continue
898
+
899
+ location_lower = location.lower()
900
+
901
+ # Check for matches
902
+ for country, timezone in self.country_timezones.items():
903
+ if country in location_lower:
904
+ return timezone
905
+
906
+ for city, timezone in self.city_timezones.items():
907
+ if city in location_lower:
908
+ return timezone
909
+
910
+ return None
911
+
912
+ except Exception as e:
913
+ self.logger.error(f"Contact info timezone detection failed: {str(e)}")
914
+ return None