OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 1997-2014, International Business Machines Corporation and | 3 * Copyright (C) 1997-2015, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 * | 6 * |
7 * File TIMEZONE.CPP | 7 * File TIMEZONE.CPP |
8 * | 8 * |
9 * Modification History: | 9 * Modification History: |
10 * | 10 * |
11 * Date Name Description | 11 * Date Name Description |
12 * 12/05/96 clhuang Creation. | 12 * 12/05/96 clhuang Creation. |
13 * 04/21/97 aliu General clean-up and bug fixing. | 13 * 04/21/97 aliu General clean-up and bug fixing. |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 433 } |
434 if (result == 0) { | 434 if (result == 0) { |
435 U_DEBUG_TZ_MSG(("failed to load time zone with id - falling to Etc/Unkno
wn(GMT)")); | 435 U_DEBUG_TZ_MSG(("failed to load time zone with id - falling to Etc/Unkno
wn(GMT)")); |
436 result = getUnknown().clone(); | 436 result = getUnknown().clone(); |
437 } | 437 } |
438 return result; | 438 return result; |
439 } | 439 } |
440 | 440 |
441 // ------------------------------------- | 441 // ------------------------------------- |
442 | 442 |
443 /** | 443 TimeZone* U_EXPORT2 |
444 * Initialize DEFAULT_ZONE from the system default time zone. | 444 TimeZone::detectHostTimeZone() |
445 * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() | |
446 * returns NULL. | |
447 */ | |
448 static void U_CALLCONV initDefault() | |
449 { | 445 { |
450 ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); | |
451 | |
452 // If setDefault() has already been called we can skip getting the | |
453 // default zone information from the system. | |
454 if (DEFAULT_ZONE != NULL) { | |
455 return; | |
456 } | |
457 | |
458 // We access system timezone data through TPlatformUtilities, | 446 // We access system timezone data through TPlatformUtilities, |
459 // including tzset(), timezone, and tzname[]. | 447 // including tzset(), timezone, and tzname[]. |
460 int32_t rawOffset = 0; | 448 int32_t rawOffset = 0; |
461 const char *hostID; | 449 const char *hostID; |
462 | 450 |
463 // First, try to create a system timezone, based | 451 // First, try to create a system timezone, based |
464 // on the string ID in tzname[0]. | 452 // on the string ID in tzname[0]. |
465 | 453 |
466 // NOTE: this code is safely single threaded, being only | |
467 // run via umtx_initOnce(). | |
468 // | |
469 // Some of the locale/timezone OS functions may not be thread safe, | |
470 // | |
471 // The operating system might actually use ICU to implement timezones. | |
472 // So we may have ICU calling ICU here, like on AIX. | |
473 // There shouldn't be a problem with this; initOnce does not hold a mutex | |
474 // while the init function is being run. | |
475 | |
476 uprv_tzset(); // Initialize tz... system data | 454 uprv_tzset(); // Initialize tz... system data |
477 | 455 |
478 // Get the timezone ID from the host. This function should do | 456 // Get the timezone ID from the host. This function should do |
479 // any required host-specific remapping; e.g., on Windows this | 457 // any required host-specific remapping; e.g., on Windows this |
480 // function maps the Date and Time control panel setting to an | 458 // function maps the Date and Time control panel setting to an |
481 // ICU timezone ID. | 459 // ICU timezone ID. |
482 hostID = uprv_tzname(0); | 460 hostID = uprv_tzname(0); |
483 | 461 |
484 // Invert sign because UNIX semantics are backwards | 462 // Invert sign because UNIX semantics are backwards |
485 rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND; | 463 rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND; |
486 | 464 |
487 TimeZone* default_zone = NULL; | 465 TimeZone* hostZone = NULL; |
488 | 466 |
489 /* Make sure that the string is NULL terminated to prevent BoundsChecker/Pur
ify warnings. */ | 467 /* Make sure that the string is NULL terminated to prevent BoundsChecker/Pur
ify warnings. */ |
490 UnicodeString hostStrID(hostID, -1, US_INV); | 468 UnicodeString hostStrID(hostID, -1, US_INV); |
491 hostStrID.append((UChar)0); | 469 hostStrID.append((UChar)0); |
492 hostStrID.truncate(hostStrID.length()-1); | 470 hostStrID.truncate(hostStrID.length()-1); |
493 default_zone = createSystemTimeZone(hostStrID); | 471 hostZone = createSystemTimeZone(hostStrID); |
494 | 472 |
495 #if U_PLATFORM_USES_ONLY_WIN32_API | 473 #if U_PLATFORM_USES_ONLY_WIN32_API |
496 // hostID points to a heap-allocated location on Windows. | 474 // hostID points to a heap-allocated location on Windows. |
497 uprv_free(const_cast<char *>(hostID)); | 475 uprv_free(const_cast<char *>(hostID)); |
498 #endif | 476 #endif |
499 | 477 |
500 int32_t hostIDLen = hostStrID.length(); | 478 int32_t hostIDLen = hostStrID.length(); |
501 if (default_zone != NULL && rawOffset != default_zone->getRawOffset() | 479 if (hostZone != NULL && rawOffset != hostZone->getRawOffset() |
502 && (3 <= hostIDLen && hostIDLen <= 4)) | 480 && (3 <= hostIDLen && hostIDLen <= 4)) |
503 { | 481 { |
504 // Uh oh. This probably wasn't a good id. | 482 // Uh oh. This probably wasn't a good id. |
505 // It was probably an ambiguous abbreviation | 483 // It was probably an ambiguous abbreviation |
506 delete default_zone; | 484 delete hostZone; |
507 default_zone = NULL; | 485 hostZone = NULL; |
508 } | 486 } |
509 | 487 |
510 // Construct a fixed standard zone with the host's ID | 488 // Construct a fixed standard zone with the host's ID |
511 // and raw offset. | 489 // and raw offset. |
512 if (default_zone == NULL) { | 490 if (hostZone == NULL) { |
513 default_zone = new SimpleTimeZone(rawOffset, hostStrID); | 491 hostZone = new SimpleTimeZone(rawOffset, hostStrID); |
514 } | 492 } |
515 | 493 |
516 // If we _still_ don't have a time zone, use GMT. | 494 // If we _still_ don't have a time zone, use GMT. |
517 if (default_zone == NULL) { | 495 // |
| 496 // Note: This is extremely unlikely situation. If |
| 497 // new SimpleTimeZone(...) above fails, the following |
| 498 // code may also fail. |
| 499 if (hostZone == NULL) { |
518 const TimeZone* temptz = TimeZone::getGMT(); | 500 const TimeZone* temptz = TimeZone::getGMT(); |
519 // If we can't use GMT, get out. | 501 // If we can't use GMT, get out. |
520 if (temptz == NULL) { | 502 if (temptz == NULL) { |
521 return; | 503 return NULL; |
522 } | 504 } |
523 default_zone = temptz->clone(); | 505 hostZone = temptz->clone(); |
524 } | 506 } |
525 | 507 |
| 508 return hostZone; |
| 509 } |
| 510 |
| 511 // ------------------------------------- |
| 512 |
| 513 /** |
| 514 * Initialize DEFAULT_ZONE from the system default time zone. |
| 515 * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() |
| 516 * returns NULL. |
| 517 */ |
| 518 static void U_CALLCONV initDefault() |
| 519 { |
| 520 ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); |
| 521 |
| 522 // If setDefault() has already been called we can skip getting the |
| 523 // default zone information from the system. |
| 524 if (DEFAULT_ZONE != NULL) { |
| 525 return; |
| 526 } |
| 527 |
| 528 // NOTE: this code is safely single threaded, being only |
| 529 // run via umtx_initOnce(). |
| 530 // |
| 531 // Some of the locale/timezone OS functions may not be thread safe, |
| 532 // |
| 533 // The operating system might actually use ICU to implement timezones. |
| 534 // So we may have ICU calling ICU here, like on AIX. |
| 535 // There shouldn't be a problem with this; initOnce does not hold a mutex |
| 536 // while the init function is being run. |
| 537 |
| 538 // The code detecting the host time zone was separated from this |
| 539 // and implemented as TimeZone::detectHostTimeZone() |
| 540 |
| 541 TimeZone *default_zone = TimeZone::detectHostTimeZone(); |
| 542 |
526 // The only way for DEFAULT_ZONE to be non-null at this point is if the user | 543 // The only way for DEFAULT_ZONE to be non-null at this point is if the user |
527 // made a thread-unsafe call to setDefault() or adoptDefault() in another | 544 // made a thread-unsafe call to setDefault() or adoptDefault() in another |
528 // thread while this thread was doing something that required getting the de
fault. | 545 // thread while this thread was doing something that required getting the de
fault. |
529 U_ASSERT(DEFAULT_ZONE == NULL); | 546 U_ASSERT(DEFAULT_ZONE == NULL); |
530 | 547 |
531 DEFAULT_ZONE = default_zone; | 548 DEFAULT_ZONE = default_zone; |
532 } | 549 } |
533 | 550 |
534 // ------------------------------------- | 551 // ------------------------------------- |
535 | 552 |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 return id; | 1684 return id; |
1668 } | 1685 } |
1669 #endif /* U_HIDE_DRAFT_API */ | 1686 #endif /* U_HIDE_DRAFT_API */ |
1670 | 1687 |
1671 | 1688 |
1672 U_NAMESPACE_END | 1689 U_NAMESPACE_END |
1673 | 1690 |
1674 #endif /* #if !UCONFIG_NO_FORMATTING */ | 1691 #endif /* #if !UCONFIG_NO_FORMATTING */ |
1675 | 1692 |
1676 //eof | 1693 //eof |
OLD | NEW |