| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | uplevel \#0 { |
| | package require msgcat 1.6 |
| | if { $::tcl_platform(platform) eq {windows} } { |
| | if { [catch { package require registry 1.1 }] } { |
| | namespace eval ::tcl::clock [list variable NoRegistry {}] |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | namespace eval ::tcl::clock \ |
| | [list variable LibDir [file dirname [info script]]] |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | namespace eval ::tcl::clock { |
| |
|
| | |
| |
|
| | namespace export format |
| | namespace export clicks |
| | namespace export microseconds |
| | namespace export milliseconds |
| | namespace export scan |
| | namespace export seconds |
| | namespace export add |
| |
|
| | |
| |
|
| | namespace import ::msgcat::mcload |
| | namespace import ::msgcat::mclocale |
| | namespace import ::msgcat::mc |
| | namespace import ::msgcat::mcpackagelocale |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::Initialize {} { |
| |
|
| | rename ::tcl::clock::Initialize {} |
| |
|
| | variable LibDir |
| |
|
| | |
| |
|
| | proc InitTZData {} { |
| | variable TZData |
| | array unset TZData |
| | set TZData(:Etc/GMT) { |
| | {-9223372036854775808 0 0 GMT} |
| | } |
| | set TZData(:GMT) $TZData(:Etc/GMT) |
| | set TZData(:Etc/UTC) { |
| | {-9223372036854775808 0 0 UTC} |
| | } |
| | set TZData(:UTC) $TZData(:Etc/UTC) |
| | set TZData(:localtime) {} |
| | } |
| | InitTZData |
| |
|
| | mcpackagelocale set {} |
| | ::msgcat::mcpackageconfig set mcfolder [file join $LibDir msgs] |
| | ::msgcat::mcpackageconfig set unknowncmd "" |
| | ::msgcat::mcpackageconfig set changecmd ChangeCurrentLocale |
| |
|
| | |
| |
|
| | ::msgcat::mcmset {} { |
| | AM {am} |
| | BCE {B.C.E.} |
| | CE {C.E.} |
| | DATE_FORMAT {%m/%d/%Y} |
| | DATE_TIME_FORMAT {%a %b %e %H:%M:%S %Y} |
| | DAYS_OF_WEEK_ABBREV { |
| | Sun Mon Tue Wed Thu Fri Sat |
| | } |
| | DAYS_OF_WEEK_FULL { |
| | Sunday Monday Tuesday Wednesday Thursday Friday Saturday |
| | } |
| | GREGORIAN_CHANGE_DATE 2299161 |
| | LOCALE_DATE_FORMAT {%m/%d/%Y} |
| | LOCALE_DATE_TIME_FORMAT {%a %b %e %H:%M:%S %Y} |
| | LOCALE_ERAS {} |
| | LOCALE_NUMERALS { |
| | 00 01 02 03 04 05 06 07 08 09 |
| | 10 11 12 13 14 15 16 17 18 19 |
| | 20 21 22 23 24 25 26 27 28 29 |
| | 30 31 32 33 34 35 36 37 38 39 |
| | 40 41 42 43 44 45 46 47 48 49 |
| | 50 51 52 53 54 55 56 57 58 59 |
| | 60 61 62 63 64 65 66 67 68 69 |
| | 70 71 72 73 74 75 76 77 78 79 |
| | 80 81 82 83 84 85 86 87 88 89 |
| | 90 91 92 93 94 95 96 97 98 99 |
| | } |
| | LOCALE_TIME_FORMAT {%H:%M:%S} |
| | LOCALE_YEAR_FORMAT {%EC%Ey} |
| | MONTHS_ABBREV { |
| | Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec |
| | } |
| | MONTHS_FULL { |
| | January February March |
| | April May June |
| | July August September |
| | October November December |
| | } |
| | PM {pm} |
| | TIME_FORMAT {%H:%M:%S} |
| | TIME_FORMAT_12 {%I:%M:%S %P} |
| | TIME_FORMAT_24 {%H:%M} |
| | TIME_FORMAT_24_SECS {%H:%M:%S} |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | ::msgcat::mcset it GREGORIAN_CHANGE_DATE 2299161 |
| | ::msgcat::mcset es GREGORIAN_CHANGE_DATE 2299161 |
| | ::msgcat::mcset pt GREGORIAN_CHANGE_DATE 2299161 |
| | ::msgcat::mcset pl GREGORIAN_CHANGE_DATE 2299161 |
| |
|
| | |
| |
|
| | ::msgcat::mcset fr GREGORIAN_CHANGE_DATE 2299227 |
| |
|
| | |
| | |
| |
|
| | ::msgcat::mcset fr_BE GREGORIAN_CHANGE_DATE 2299238 |
| | ::msgcat::mcset nl_BE GREGORIAN_CHANGE_DATE 2299238 |
| |
|
| | |
| |
|
| | ::msgcat::mcset de_AT GREGORIAN_CHANGE_DATE 2299527 |
| |
|
| | |
| |
|
| | ::msgcat::mcset hu GREGORIAN_CHANGE_DATE 2301004 |
| |
|
| | |
| |
|
| | ::msgcat::mcset de_DE GREGORIAN_CHANGE_DATE 2342032 |
| | ::msgcat::mcset nb GREGORIAN_CHANGE_DATE 2342032 |
| | ::msgcat::mcset nn GREGORIAN_CHANGE_DATE 2342032 |
| | ::msgcat::mcset no GREGORIAN_CHANGE_DATE 2342032 |
| | ::msgcat::mcset da GREGORIAN_CHANGE_DATE 2342032 |
| |
|
| | |
| | |
| |
|
| | ::msgcat::mcset nl GREGORIAN_CHANGE_DATE 2342165 |
| |
|
| | |
| |
|
| | ::msgcat::mcset fr_CH GREGORIAN_CHANGE_DATE 2361342 |
| | ::msgcat::mcset it_CH GREGORIAN_CHANGE_DATE 2361342 |
| | ::msgcat::mcset de_CH GREGORIAN_CHANGE_DATE 2361342 |
| |
|
| | |
| |
|
| | ::msgcat::mcset en GREGORIAN_CHANGE_DATE 2361222 |
| |
|
| | |
| |
|
| | ::msgcat::mcset sv GREGORIAN_CHANGE_DATE 2361390 |
| |
|
| | |
| |
|
| | ::msgcat::mcset ru GREGORIAN_CHANGE_DATE 2421639 |
| |
|
| | |
| | |
| |
|
| | ::msgcat::mcset ro GREGORIAN_CHANGE_DATE 2422063 |
| |
|
| | |
| |
|
| | ::msgcat::mcset el GREGORIAN_CHANGE_DATE 2423480 |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | variable ZoneinfoPaths {} |
| | foreach path { |
| | /usr/share/zoneinfo |
| | /usr/share/lib/zoneinfo |
| | /usr/lib/zoneinfo |
| | /usr/local/etc/zoneinfo |
| | } { |
| | if { [file isdirectory $path] } { |
| | lappend ZoneinfoPaths $path |
| | } |
| | } |
| |
|
| | |
| |
|
| | variable DataDir [file join $LibDir tzdata] |
| |
|
| | |
| |
|
| | variable DaysInRomanMonthInCommonYear \ |
| | { 31 28 31 30 31 30 31 31 30 31 30 31 } |
| | variable DaysInRomanMonthInLeapYear \ |
| | { 31 29 31 30 31 30 31 31 30 31 30 31 } |
| | variable DaysInPriorMonthsInCommonYear [list 0] |
| | variable DaysInPriorMonthsInLeapYear [list 0] |
| | set i 0 |
| | foreach j $DaysInRomanMonthInCommonYear { |
| | lappend DaysInPriorMonthsInCommonYear [incr i $j] |
| | } |
| | set i 0 |
| | foreach j $DaysInRomanMonthInLeapYear { |
| | lappend DaysInPriorMonthsInLeapYear [incr i $j] |
| | } |
| |
|
| | |
| |
|
| | variable Roddenberry 1946 |
| |
|
| | |
| |
|
| | variable MINWIDE -9223372036854775808 |
| | variable MAXWIDE 9223372036854775807 |
| |
|
| | |
| |
|
| | variable FEB_28 58 |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | variable WinZoneInfo [dict create {*}{ |
| | {-43200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Kwajalein |
| | {-39600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Midway |
| | {-36000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Honolulu |
| | {-32400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Anchorage |
| | {-28800 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Los_Angeles |
| | {-28800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Tijuana |
| | {-25200 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Denver |
| | {-25200 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Chihuahua |
| | {-25200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Phoenix |
| | {-21600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Regina |
| | {-21600 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Chicago |
| | {-21600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Mexico_City |
| | {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/New_York |
| | {-18000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Indianapolis |
| | {-14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Caracas |
| | {-14400 0 3600 0 3 6 2 23 59 59 999 0 10 6 2 23 59 59 999} |
| | :America/Santiago |
| | {-14400 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Manaus |
| | {-14400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Halifax |
| | {-12600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/St_Johns |
| | {-10800 0 3600 0 2 0 2 2 0 0 0 0 10 0 3 2 0 0 0} :America/Sao_Paulo |
| | {-10800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Godthab |
| | {-10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Buenos_Aires |
| | {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Bahia |
| | {-10800 0 3600 0 3 0 2 2 0 0 0 0 10 0 1 2 0 0 0} :America/Montevideo |
| | {-7200 0 3600 0 9 0 5 2 0 0 0 0 3 0 5 2 0 0 0} :America/Noronha |
| | {-3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Atlantic/Azores |
| | {-3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Atlantic/Cape_Verde |
| | {0 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :UTC |
| | {0 0 3600 0 10 0 5 2 0 0 0 0 3 0 5 1 0 0 0} :Europe/London |
| | {3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Africa/Kinshasa |
| | {3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :CET |
| | {7200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Africa/Harare |
| | {7200 0 3600 0 9 4 5 23 59 59 0 0 4 4 5 23 59 59 0} |
| | :Africa/Cairo |
| | {7200 0 3600 0 10 0 5 4 0 0 0 0 3 0 5 3 0 0 0} :Europe/Helsinki |
| | {7200 0 3600 0 9 0 3 2 0 0 0 0 3 5 5 2 0 0 0} :Asia/Jerusalem |
| | {7200 0 3600 0 9 0 5 1 0 0 0 0 3 0 5 0 0 0 0} :Europe/Bucharest |
| | {7200 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Europe/Athens |
| | {7200 0 3600 0 9 5 5 1 0 0 0 0 3 4 5 0 0 0 0} :Asia/Amman |
| | {7200 0 3600 0 10 6 5 23 59 59 999 0 3 0 5 0 0 0 0} |
| | :Asia/Beirut |
| | {7200 0 -3600 0 4 0 1 2 0 0 0 0 9 0 1 2 0 0 0} :Africa/Windhoek |
| | {10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Riyadh |
| | {10800 0 3600 0 10 0 1 4 0 0 0 0 4 0 1 3 0 0 0} :Asia/Baghdad |
| | {10800 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Europe/Moscow |
| | {12600 0 3600 0 9 2 4 2 0 0 0 0 3 0 1 2 0 0 0} :Asia/Tehran |
| | {14400 0 3600 0 10 0 5 5 0 0 0 0 3 0 5 4 0 0 0} :Asia/Baku |
| | {14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Muscat |
| | {14400 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Tbilisi |
| | {16200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Kabul |
| | {18000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Karachi |
| | {18000 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Yekaterinburg |
| | {19800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Calcutta |
| | {20700 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Katmandu |
| | {21600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Dhaka |
| | {21600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Novosibirsk |
| | {23400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Rangoon |
| | {25200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Bangkok |
| | {25200 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Krasnoyarsk |
| | {28800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Chongqing |
| | {28800 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Irkutsk |
| | {32400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Tokyo |
| | {32400 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Yakutsk |
| | {34200 0 3600 0 3 0 5 3 0 0 0 0 10 0 5 2 0 0 0} :Australia/Adelaide |
| | {34200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Australia/Darwin |
| | {36000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Australia/Brisbane |
| | {36000 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Vladivostok |
| | {36000 0 3600 0 3 0 5 3 0 0 0 0 10 0 1 2 0 0 0} :Australia/Hobart |
| | {36000 0 3600 0 3 0 5 3 0 0 0 0 10 0 5 2 0 0 0} :Australia/Sydney |
| | {39600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Noumea |
| | {43200 0 3600 0 3 0 3 3 0 0 0 0 10 0 1 2 0 0 0} :Pacific/Auckland |
| | {43200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Fiji |
| | {46800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Tongatapu |
| | }] |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | variable DateParseActions { |
| |
|
| | { seconds } 0 {} |
| |
|
| | { julianDay } 1 {} |
| |
|
| | { era century yearOfCentury month dayOfMonth } 2 { |
| | dict set date year [expr { 100 * [dict get $date century] |
| | + [dict get $date yearOfCentury] }] |
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { era century yearOfCentury dayOfYear } 2 { |
| | dict set date year [expr { 100 * [dict get $date century] |
| | + [dict get $date yearOfCentury] }] |
| | set date [GetJulianDayFromEraYearDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | { century yearOfCentury month dayOfMonth } 3 { |
| | dict set date era CE |
| | dict set date year [expr { 100 * [dict get $date century] |
| | + [dict get $date yearOfCentury] }] |
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { century yearOfCentury dayOfYear } 3 { |
| | dict set date era CE |
| | dict set date year [expr { 100 * [dict get $date century] |
| | + [dict get $date yearOfCentury] }] |
| | set date [GetJulianDayFromEraYearDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { iso8601Century iso8601YearOfCentury iso8601Week dayOfWeek } 3 { |
| | dict set date era CE |
| | dict set date iso8601Year \ |
| | [expr { 100 * [dict get $date iso8601Century] |
| | + [dict get $date iso8601YearOfCentury] }] |
| | set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | { yearOfCentury month dayOfMonth } 4 { |
| | set date [InterpretTwoDigitYear $date[set date {}] $baseTime] |
| | dict set date era CE |
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { yearOfCentury dayOfYear } 4 { |
| | set date [InterpretTwoDigitYear $date[set date {}] $baseTime] |
| | dict set date era CE |
| | set date [GetJulianDayFromEraYearDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { iso8601YearOfCentury iso8601Week dayOfWeek } 4 { |
| | set date [InterpretTwoDigitYear \ |
| | $date[set date {}] $baseTime \ |
| | iso8601YearOfCentury iso8601Year] |
| | dict set date era CE |
| | set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | { month dayOfMonth } 5 { |
| | set date [AssignBaseYear $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { dayOfYear } 5 { |
| | set date [AssignBaseYear $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | set date [GetJulianDayFromEraYearDay $date[set date {}] \ |
| | $changeover] |
| | } |
| | { iso8601Week dayOfWeek } 5 { |
| | set date [AssignBaseIso8601Year $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | { dayOfMonth } 6 { |
| | set date [AssignBaseMonth $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | { dayOfWeek } 7 { |
| | set date [AssignBaseWeek $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ |
| | $changeover] |
| | } |
| |
|
| | {} 8 { |
| | set date [AssignBaseJulianDay $date[set date {}] \ |
| | $baseTime $timeZone $changeover] |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | variable TimeParseActions { |
| |
|
| | seconds 1 {} |
| |
|
| | { hourAMPM minute second amPmIndicator } 2 { |
| | dict set date secondOfDay [InterpretHMSP $date] |
| | } |
| | { hour minute second } 2 { |
| | dict set date secondOfDay [InterpretHMS $date] |
| | } |
| |
|
| | { hourAMPM minute amPmIndicator } 3 { |
| | dict set date second 0 |
| | dict set date secondOfDay [InterpretHMSP $date] |
| | } |
| | { hour minute } 3 { |
| | dict set date second 0 |
| | dict set date secondOfDay [InterpretHMS $date] |
| | } |
| |
|
| | { hourAMPM amPmIndicator } 4 { |
| | dict set date minute 0 |
| | dict set date second 0 |
| | dict set date secondOfDay [InterpretHMSP $date] |
| | } |
| | { hour } 4 { |
| | dict set date minute 0 |
| | dict set date second 0 |
| | dict set date secondOfDay [InterpretHMS $date] |
| | } |
| |
|
| | { } 5 { |
| | dict set date secondOfDay 0 |
| | } |
| | } |
| |
|
| | |
| |
|
| | variable LegacyTimeZone [dict create \ |
| | gmt +0000 \ |
| | ut +0000 \ |
| | utc +0000 \ |
| | bst +0100 \ |
| | wet +0000 \ |
| | wat -0100 \ |
| | at -0200 \ |
| | nft -0330 \ |
| | nst -0330 \ |
| | ndt -0230 \ |
| | ast -0400 \ |
| | adt -0300 \ |
| | est -0500 \ |
| | edt -0400 \ |
| | cst -0600 \ |
| | cdt -0500 \ |
| | mst -0700 \ |
| | mdt -0600 \ |
| | pst -0800 \ |
| | pdt -0700 \ |
| | yst -0900 \ |
| | ydt -0800 \ |
| | hst -1000 \ |
| | hdt -0900 \ |
| | cat -1000 \ |
| | ahst -1000 \ |
| | nt -1100 \ |
| | idlw -1200 \ |
| | cet +0100 \ |
| | cest +0200 \ |
| | met +0100 \ |
| | mewt +0100 \ |
| | mest +0200 \ |
| | swt +0100 \ |
| | sst +0200 \ |
| | fwt +0100 \ |
| | fst +0200 \ |
| | eet +0200 \ |
| | eest +0300 \ |
| | bt +0300 \ |
| | it +0330 \ |
| | zp4 +0400 \ |
| | zp5 +0500 \ |
| | ist +0530 \ |
| | zp6 +0600 \ |
| | wast +0700 \ |
| | wadt +0800 \ |
| | jt +0730 \ |
| | cct +0800 \ |
| | jst +0900 \ |
| | kst +0900 \ |
| | cast +0930 \ |
| | jdt +1000 \ |
| | kdt +1000 \ |
| | cadt +1030 \ |
| | east +1000 \ |
| | eadt +1030 \ |
| | gst +1000 \ |
| | nzt +1200 \ |
| | nzst +1200 \ |
| | nzdt +1300 \ |
| | idle +1200 \ |
| | a +0100 \ |
| | b +0200 \ |
| | c +0300 \ |
| | d +0400 \ |
| | e +0500 \ |
| | f +0600 \ |
| | g +0700 \ |
| | h +0800 \ |
| | i +0900 \ |
| | k +1000 \ |
| | l +1100 \ |
| | m +1200 \ |
| | n -0100 \ |
| | o -0200 \ |
| | p -0300 \ |
| | q -0400 \ |
| | r -0500 \ |
| | s -0600 \ |
| | t -0700 \ |
| | u -0800 \ |
| | v -0900 \ |
| | w -1000 \ |
| | x -1100 \ |
| | y -1200 \ |
| | z +0000 \ |
| | ] |
| |
|
| | |
| |
|
| | variable LocaleNumeralCache {} |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | variable TimeZoneBad {} |
| | |
| | |
| | |
| | variable TZData |
| | |
| | |
| | |
| | |
| | variable FormatProc |
| | |
| | |
| | } |
| | ::tcl::clock::Initialize |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::format { args } { |
| |
|
| | variable FormatProc |
| | variable TZData |
| |
|
| | lassign [ParseFormatArgs {*}$args] format locale timezone |
| | set locale [string tolower $locale] |
| | set clockval [lindex $args 0] |
| |
|
| | |
| |
|
| | if {$timezone eq ""} { |
| | set timezone [GetSystemTimeZone] |
| | } |
| | if {![info exists TZData($timezone)]} { |
| | if {[catch {SetupTimeZone $timezone} retval opts]} { |
| | dict unset opts -errorinfo |
| | return -options $opts $retval |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | set procName formatproc'$format'$locale |
| | set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName] |
| | if {[info exists FormatProc($procName)]} { |
| | set procName $FormatProc($procName) |
| | } else { |
| | set FormatProc($procName) \ |
| | [ParseClockFormatFormat $procName $format $locale] |
| | } |
| |
|
| | return [$procName $clockval $timezone] |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ParseClockFormatFormat {procName format locale} { |
| |
|
| | if {[namespace which $procName] ne {}} { |
| | return $procName |
| | } |
| |
|
| | |
| |
|
| | EnterLocale $locale |
| |
|
| | |
| |
|
| | try { |
| | return [ParseClockFormatFormat2 $format $locale $procName] |
| | } trap CLOCK {result opts} { |
| | dict unset opts -errorinfo |
| | return -options $opts $result |
| | } |
| | } |
| |
|
| | proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} { |
| | set didLocaleEra 0 |
| | set didLocaleNumerals 0 |
| | set preFormatCode \ |
| | [string map [list @GREGORIAN_CHANGE_DATE@ \ |
| | [mc GREGORIAN_CHANGE_DATE]] \ |
| | { |
| | variable TZData |
| | set date [GetDateFields $clockval \ |
| | $TZData($timezone) \ |
| | @GREGORIAN_CHANGE_DATE@] |
| | }] |
| | set formatString {} |
| | set substituents {} |
| | set state {} |
| |
|
| | set format [LocalizeFormat $locale $format] |
| |
|
| | foreach char [split $format {}] { |
| | switch -exact -- $state { |
| | {} { |
| | if { [string equal % $char] } { |
| | set state percent |
| | } else { |
| | append formatString $char |
| | } |
| | } |
| | percent { # Character following a '%' character |
| | set state {} |
| | switch -exact -- $char { |
| | % { # A literal character, '%' |
| | append formatString %% |
| | } |
| | a { # Day of week, abbreviated |
| | append formatString %s |
| | append substituents \ |
| | [string map \ |
| | [list @DAYS_OF_WEEK_ABBREV@ \ |
| | [list [mc DAYS_OF_WEEK_ABBREV]]] \ |
| | { [lindex @DAYS_OF_WEEK_ABBREV@ \ |
| | [expr {[dict get $date dayOfWeek] \ |
| | % 7}]]}] |
| | } |
| | A { # Day of week, spelt out. |
| | append formatString %s |
| | append substituents \ |
| | [string map \ |
| | [list @DAYS_OF_WEEK_FULL@ \ |
| | [list [mc DAYS_OF_WEEK_FULL]]] \ |
| | { [lindex @DAYS_OF_WEEK_FULL@ \ |
| | [expr {[dict get $date dayOfWeek] \ |
| | % 7}]]}] |
| | } |
| | b - h { # Name of month, abbreviated. |
| | append formatString %s |
| | append substituents \ |
| | [string map \ |
| | [list @MONTHS_ABBREV@ \ |
| | [list [mc MONTHS_ABBREV]]] \ |
| | { [lindex @MONTHS_ABBREV@ \ |
| | [expr {[dict get $date month]-1}]]}] |
| | } |
| | B { # Name of month, spelt out |
| | append formatString %s |
| | append substituents \ |
| | [string map \ |
| | [list @MONTHS_FULL@ \ |
| | [list [mc MONTHS_FULL]]] \ |
| | { [lindex @MONTHS_FULL@ \ |
| | [expr {[dict get $date month]-1}]]}] |
| | } |
| | C { # Century number |
| | append formatString %02d |
| | append substituents \ |
| | { [expr {[dict get $date year] / 100}]} |
| | } |
| | d { # Day of month, with leading zero |
| | append formatString %02d |
| | append substituents { [dict get $date dayOfMonth]} |
| | } |
| | e { # Day of month, without leading zero |
| | append formatString %2d |
| | append substituents { [dict get $date dayOfMonth]} |
| | } |
| | E { # Format group in a locale-dependent |
| | |
| | set state percentE |
| | if {!$didLocaleEra} { |
| | append preFormatCode \ |
| | [string map \ |
| | [list @LOCALE_ERAS@ \ |
| | [list [mc LOCALE_ERAS]]] \ |
| | { |
| | set date [GetLocaleEra \ |
| | $date[set date {}] \ |
| | @LOCALE_ERAS@]}] \n |
| | set didLocaleEra 1 |
| | } |
| | if {!$didLocaleNumerals} { |
| | append preFormatCode \ |
| | [list set localeNumerals \ |
| | [mc LOCALE_NUMERALS]] \n |
| | set didLocaleNumerals 1 |
| | } |
| | } |
| | g { # Two-digit year relative to ISO8601 |
| | |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { [dict get $date iso8601Year] % 100 }]} |
| | } |
| | G { # Four-digit year relative to ISO8601 |
| | |
| | append formatString %02d |
| | append substituents { [dict get $date iso8601Year]} |
| | } |
| | H { # Hour in the 24-hour day, leading zero |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { [dict get $date localSeconds] \ |
| | / 3600 % 24}]} |
| | } |
| | I { # Hour AM/PM, with leading zero |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { ( ( ( [dict get $date localSeconds] \ |
| | % 86400 ) \ |
| | + 86400 \ |
| | - 3600 ) \ |
| | / 3600 ) \ |
| | % 12 + 1 }] } |
| | } |
| | j { # Day of year (001-366) |
| | append formatString %03d |
| | append substituents { [dict get $date dayOfYear]} |
| | } |
| | J { # Julian Day Number |
| | append formatString %07ld |
| | append substituents { [dict get $date julianDay]} |
| | } |
| | k { # Hour (0-23), no leading zero |
| | append formatString %2d |
| | append substituents \ |
| | { [expr { [dict get $date localSeconds] |
| | / 3600 |
| | % 24 }]} |
| | } |
| | l { # Hour (12-11), no leading zero |
| | append formatString %2d |
| | append substituents \ |
| | { [expr { ( ( ( [dict get $date localSeconds] |
| | % 86400 ) |
| | + 86400 |
| | - 3600 ) |
| | / 3600 ) |
| | % 12 + 1 }]} |
| | } |
| | m { # Month number, leading zero |
| | append formatString %02d |
| | append substituents { [dict get $date month]} |
| | } |
| | M { # Minute of the hour, leading zero |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { [dict get $date localSeconds] |
| | / 60 |
| | % 60 }]} |
| | } |
| | n { # A literal newline |
| | append formatString \n |
| | } |
| | N { # Month number, no leading zero |
| | append formatString %2d |
| | append substituents { [dict get $date month]} |
| | } |
| | O { # A format group in the locale's |
| | |
| | set state percentO |
| | if {!$didLocaleNumerals} { |
| | append preFormatCode \ |
| | [list set localeNumerals \ |
| | [mc LOCALE_NUMERALS]] \n |
| | set didLocaleNumerals 1 |
| | } |
| | } |
| | p { # Localized 'AM' or 'PM' indicator |
| | |
| | append formatString %s |
| | append preFormatCode \ |
| | [list set AM [string toupper [mc AM]]] \n \ |
| | [list set PM [string toupper [mc PM]]] \n |
| | append substituents \ |
| | { [expr {(([dict get $date localSeconds] |
| | % 86400) < 43200) ? |
| | $AM : $PM}]} |
| | } |
| | P { # Localized 'AM' or 'PM' indicator |
| | append formatString %s |
| | append preFormatCode \ |
| | [list set am [mc AM]] \n \ |
| | [list set pm [mc PM]] \n |
| | append substituents \ |
| | { [expr {(([dict get $date localSeconds] |
| | % 86400) < 43200) ? |
| | $am : $pm}]} |
| |
|
| | } |
| | Q { # Hi, Jeff! |
| | append formatString %s |
| | append substituents { [FormatStarDate $date]} |
| | } |
| | s { # Seconds from the Posix Epoch |
| | append formatString %s |
| | append substituents { [dict get $date seconds]} |
| | } |
| | S { # Second of the minute, with |
| | |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { [dict get $date localSeconds] |
| | % 60 }]} |
| | } |
| | t { # A literal tab character |
| | append formatString \t |
| | } |
| | u { # Day of the week (1-Monday, 7-Sunday) |
| | append formatString %1d |
| | append substituents { [dict get $date dayOfWeek]} |
| | } |
| | U { # Week of the year (00-53). The |
| | |
| | |
| | append formatString %02d |
| | append preFormatCode { |
| | set dow [dict get $date dayOfWeek] |
| | if { $dow == 7 } { |
| | set dow 0 |
| | } |
| | incr dow |
| | set UweekNumber \ |
| | [expr { ( [dict get $date dayOfYear] |
| | - $dow + 7 ) |
| | / 7 }] |
| | } |
| | append substituents { $UweekNumber} |
| | } |
| | V { # The ISO8601 week number |
| | append formatString %02d |
| | append substituents { [dict get $date iso8601Week]} |
| | } |
| | w { # Day of the week (0-Sunday, |
| | |
| | append formatString %1d |
| | append substituents \ |
| | { [expr { [dict get $date dayOfWeek] % 7 }]} |
| | } |
| | W { # Week of the year (00-53). The first |
| | |
| | |
| | append preFormatCode { |
| | set WweekNumber \ |
| | [expr { ( [dict get $date dayOfYear] |
| | - [dict get $date dayOfWeek] |
| | + 7 ) |
| | / 7 }] |
| | } |
| | append formatString %02d |
| | append substituents { $WweekNumber} |
| | } |
| | y { # The two-digit year of the century |
| | append formatString %02d |
| | append substituents \ |
| | { [expr { [dict get $date year] % 100 }]} |
| | } |
| | Y { # The four-digit year |
| | append formatString %04d |
| | append substituents { [dict get $date year]} |
| | } |
| | z { # The time zone as hours and minutes |
| | |
| | append formatString %s |
| | append substituents { [FormatNumericTimeZone \ |
| | [dict get $date tzOffset]]} |
| | } |
| | Z { # The name of the time zone |
| | append formatString %s |
| | append substituents { [dict get $date tzName]} |
| | } |
| | % { # A literal percent character |
| | append formatString %% |
| | } |
| | default { # An unknown escape sequence |
| | append formatString %% $char |
| | } |
| | } |
| | } |
| | percentE { # Character following %E |
| | set state {} |
| | switch -exact -- $char { |
| | E { |
| | append formatString %s |
| | append substituents { } \ |
| | [string map \ |
| | [list @BCE@ [list [mc BCE]] \ |
| | @CE@ [list [mc CE]]] \ |
| | {[dict get {BCE @BCE@ CE @CE@} \ |
| | [dict get $date era]]}] |
| | } |
| | C { # Locale-dependent era |
| | append formatString %s |
| | append substituents { [dict get $date localeEra]} |
| | } |
| | y { # Locale-dependent year of the era |
| | append preFormatCode { |
| | set y [dict get $date localeYear] |
| | if { $y >= 0 && $y < 100 } { |
| | set Eyear [lindex $localeNumerals $y] |
| | } else { |
| | set Eyear $y |
| | } |
| | } |
| | append formatString %s |
| | append substituents { $Eyear} |
| | } |
| | default { # Unknown %E format group |
| | append formatString %%E $char |
| | } |
| | } |
| | } |
| | percentO { # Character following %O |
| | set state {} |
| | switch -exact -- $char { |
| | d - e { # Day of the month in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [dict get $date dayOfMonth]]} |
| | } |
| | H - k { # Hour of the day in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { [dict get $date localSeconds] |
| | / 3600 |
| | % 24 }]]} |
| | } |
| | I - l { # Hour (12-11) AM/PM in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { ( ( ( [dict get $date localSeconds] |
| | % 86400 ) |
| | + 86400 |
| | - 3600 ) |
| | / 3600 ) |
| | % 12 + 1 }]]} |
| | } |
| | m { # Month number in alternative numerals |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals [dict get $date month]]} |
| | } |
| | M { # Minute of the hour in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { [dict get $date localSeconds] |
| | / 60 |
| | % 60 }]]} |
| | } |
| | S { # Second of the minute in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { [dict get $date localSeconds] |
| | % 60 }]]} |
| | } |
| | u { # Day of the week (Monday=1,Sunday=7) |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [dict get $date dayOfWeek]]} |
| | } |
| | w { # Day of the week (Sunday=0,Saturday=6) |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { [dict get $date dayOfWeek] % 7 }]]} |
| | } |
| | y { # Year of the century in alternative |
| | |
| | append formatString %s |
| | append substituents \ |
| | { [lindex $localeNumerals \ |
| | [expr { [dict get $date year] % 100 }]]} |
| | } |
| | default { # Unknown format group |
| | append formatString %%O $char |
| | } |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| |
|
| | switch -exact -- $state { |
| | percent { |
| | append formatString %% |
| | } |
| | percentE { |
| | append retval %%E |
| | } |
| | percentO { |
| | append retval %%O |
| | } |
| | } |
| |
|
| | proc $procName {clockval timezone} " |
| | $preFormatCode |
| | return \[::format [list $formatString] $substituents\] |
| | " |
| |
|
| | |
| |
|
| | return $procName |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::scan { args } { |
| |
|
| | set format {} |
| |
|
| | |
| |
|
| | if { [llength $args] < 1 || [llength $args] % 2 != 1 } { |
| | set cmdName "clock scan" |
| | return -code error \ |
| | -errorcode [list CLOCK wrongNumArgs] \ |
| | "wrong \# args: should be\ |
| | \"$cmdName string\ |
| | ?-base seconds?\ |
| | ?-format string? ?-gmt boolean?\ |
| | ?-locale LOCALE? ?-timezone ZONE?\"" |
| | } |
| |
|
| | |
| |
|
| | set base [clock seconds] |
| | set string [lindex $args 0] |
| | set format {} |
| | set gmt 0 |
| | set locale c |
| | set timezone [GetSystemTimeZone] |
| |
|
| | |
| |
|
| | foreach { flag value } [lreplace $args 0 0] { |
| | switch -exact -- $flag { |
| | -b - -ba - -bas - -base { |
| | set base $value |
| | } |
| | -f - -fo - -for - -form - -forma - -format { |
| | set saw(-format) {} |
| | set format $value |
| | } |
| | -g - -gm - -gmt { |
| | set saw(-gmt) {} |
| | set gmt $value |
| | } |
| | -l - -lo - -loc - -loca - -local - -locale { |
| | set saw(-locale) {} |
| | set locale [string tolower $value] |
| | } |
| | -t - -ti - -tim - -time - -timez - -timezo - -timezon - -timezone { |
| | set saw(-timezone) {} |
| | set timezone $value |
| | } |
| | default { |
| | return -code error \ |
| | -errorcode [list CLOCK badOption $flag] \ |
| | "bad option \"$flag\",\ |
| | must be -base, -format, -gmt, -locale or -timezone" |
| | } |
| | } |
| | } |
| |
|
| | |
| |
|
| | if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } { |
| | return -code error \ |
| | -errorcode [list CLOCK gmtWithTimezone] \ |
| | "cannot use -gmt and -timezone in same call" |
| | } |
| | if { [catch { expr { wide($base) } } result] } { |
| | return -code error "expected integer but got \"$base\"" |
| | } |
| | if { ![string is boolean -strict $gmt] } { |
| | return -code error "expected boolean value but got \"$gmt\"" |
| | } elseif { $gmt } { |
| | set timezone :GMT |
| | } |
| |
|
| | if { ![info exists saw(-format)] } { |
| | |
| | |
| | if { [info exists saw(-locale)] } { |
| | return -code error \ |
| | -errorcode [list CLOCK flagWithLegacyFormat] \ |
| | "legacy \[clock scan\] does not support -locale" |
| |
|
| | } |
| | return [FreeScan $string $base $timezone $locale] |
| | } |
| |
|
| | |
| |
|
| | EnterLocale $locale |
| |
|
| | try { |
| | |
| |
|
| | set scanner [ParseClockScanFormat $format $locale] |
| | return [$scanner $string $base $timezone] |
| | } trap CLOCK {result opts} { |
| | |
| | dict unset opts -errorinfo |
| | return -options $opts $result |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::FreeScan { string base timezone locale } { |
| |
|
| | variable TZData |
| |
|
| | |
| |
|
| | try { |
| | SetupTimeZone $timezone |
| | } on error {retval opts} { |
| | dict unset opts -errorinfo |
| | return -options $opts $retval |
| | } |
| |
|
| | |
| | |
| |
|
| | set date [GetDateFields $base $TZData($timezone) 2361222] |
| | dict set date secondOfDay [expr { |
| | [dict get $date localSeconds] % 86400 |
| | }] |
| |
|
| | |
| | |
| |
|
| | try { |
| | set scanned [Oldscan $string \ |
| | [dict get $date year] \ |
| | [dict get $date month] \ |
| | [dict get $date dayOfMonth]] |
| | lassign $scanned \ |
| | parseDate parseTime parseZone parseRel \ |
| | parseWeekday parseOrdinalMonth |
| | } on error message { |
| | return -code error \ |
| | "unable to convert date-time string \"$string\": $message" |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | if { [llength $parseDate] > 0 } { |
| | lassign $parseDate y m d |
| | if { $y < 100 } { |
| | if { $y >= 39 } { |
| | incr y 1900 |
| | } else { |
| | incr y 2000 |
| | } |
| | } |
| | dict set date era CE |
| | dict set date year $y |
| | dict set date month $m |
| | dict set date dayOfMonth $d |
| | if { $parseTime eq {} } { |
| | set parseTime 0 |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | if { [llength $parseZone] > 0 } { |
| | lassign $parseZone minEast dstFlag |
| | set timezone [FormatNumericTimeZone \ |
| | [expr { 60 * $minEast + 3600 * $dstFlag }]] |
| | SetupTimeZone $timezone |
| | } |
| | dict set date tzName $timezone |
| |
|
| | |
| |
|
| | set date [GetJulianDayFromEraYearMonthDay $date[set date {}] 2361222] |
| | if { $parseTime ne {} } { |
| | dict set date secondOfDay $parseTime |
| | } elseif { [llength $parseWeekday] != 0 |
| | || [llength $parseOrdinalMonth] != 0 |
| | || ( [llength $parseRel] != 0 |
| | && ( [lindex $parseRel 0] != 0 |
| | || [lindex $parseRel 1] != 0 ) ) } { |
| | dict set date secondOfDay 0 |
| | } |
| |
|
| | dict set date localSeconds [expr { |
| | -210866803200 |
| | + ( 86400 * wide([dict get $date julianDay]) ) |
| | + [dict get $date secondOfDay] |
| | }] |
| | dict set date tzName $timezone |
| | set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) 2361222] |
| | set seconds [dict get $date seconds] |
| |
|
| | |
| |
|
| | if { [llength $parseRel] > 0 } { |
| | lassign $parseRel relMonth relDay relSecond |
| | set seconds [add $seconds \ |
| | $relMonth months $relDay days $relSecond seconds \ |
| | -timezone $timezone -locale $locale] |
| | } |
| |
|
| | |
| |
|
| | if { [llength $parseWeekday] > 0 } { |
| | lassign $parseWeekday dayOrdinal dayOfWeek |
| | set date2 [GetDateFields $seconds $TZData($timezone) 2361222] |
| | dict set date2 era CE |
| | set jdwkday [WeekdayOnOrBefore $dayOfWeek [expr { |
| | [dict get $date2 julianDay] + 6 |
| | }]] |
| | incr jdwkday [expr { 7 * $dayOrdinal }] |
| | if { $dayOrdinal > 0 } { |
| | incr jdwkday -7 |
| | } |
| | dict set date2 secondOfDay \ |
| | [expr { [dict get $date2 localSeconds] % 86400 }] |
| | dict set date2 julianDay $jdwkday |
| | dict set date2 localSeconds [expr { |
| | -210866803200 |
| | + ( 86400 * wide([dict get $date2 julianDay]) ) |
| | + [dict get $date secondOfDay] |
| | }] |
| | dict set date2 tzName $timezone |
| | set date2 [ConvertLocalToUTC $date2[set date2 {}] $TZData($timezone) \ |
| | 2361222] |
| | set seconds [dict get $date2 seconds] |
| |
|
| | } |
| |
|
| | |
| |
|
| | if { [llength $parseOrdinalMonth] > 0 } { |
| | lassign $parseOrdinalMonth monthOrdinal monthNumber |
| | if { $monthOrdinal > 0 } { |
| | set monthDiff [expr { $monthNumber - [dict get $date month] }] |
| | if { $monthDiff <= 0 } { |
| | incr monthDiff 12 |
| | } |
| | incr monthOrdinal -1 |
| | } else { |
| | set monthDiff [expr { [dict get $date month] - $monthNumber }] |
| | if { $monthDiff >= 0 } { |
| | incr monthDiff -12 |
| | } |
| | incr monthOrdinal |
| | } |
| | set seconds [add $seconds $monthOrdinal years $monthDiff months \ |
| | -timezone $timezone -locale $locale] |
| | } |
| |
|
| | return $seconds |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ParseClockScanFormat {formatString locale} { |
| | |
| | |
| |
|
| | set procName scanproc'$formatString'$locale |
| | set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName] |
| | if { [namespace which $procName] != {} } { |
| | return $procName |
| | } |
| |
|
| | variable DateParseActions |
| | variable TimeParseActions |
| |
|
| | |
| |
|
| | set formatString [LocalizeFormat $locale $formatString] |
| |
|
| | |
| |
|
| | regsub -all {[[:space:]]+} $formatString { } formatString |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | set re {^[[:space:]]*} |
| | set captureCount 0 |
| | set postcode {} |
| | set fieldSet [dict create] |
| | set fieldCount 0 |
| | set postSep {} |
| | set state {} |
| |
|
| | foreach c [split $formatString {}] { |
| | switch -exact -- $state { |
| | {} { |
| | if { $c eq "%" } { |
| | set state % |
| | } elseif { $c eq " " } { |
| | append re {[[:space:]]+} |
| | } else { |
| | if { ! [string is alnum $c] } { |
| | append re "\\" |
| | } |
| | append re $c |
| | } |
| | } |
| | % { |
| | set state {} |
| | switch -exact -- $c { |
| | % { |
| | append re % |
| | } |
| | { } { |
| | append re "\[\[:space:\]\]*" |
| | } |
| | a - A { # Day of week, in words |
| | set l {} |
| | foreach \ |
| | i {7 1 2 3 4 5 6} \ |
| | abr [mc DAYS_OF_WEEK_ABBREV] \ |
| | full [mc DAYS_OF_WEEK_FULL] { |
| | dict set l [string tolower $abr] $i |
| | dict set l [string tolower $full] $i |
| | incr i |
| | } |
| | lassign [UniquePrefixRegexp $l] regex lookup |
| | append re ( $regex ) |
| | dict set fieldSet dayOfWeek [incr fieldCount] |
| | append postcode "dict set date dayOfWeek \[" \ |
| | "dict get " [list $lookup] " " \ |
| | \[ {string tolower $field} [incr captureCount] \] \ |
| | "\]\n" |
| | } |
| | b - B - h { # Name of month |
| | set i 0 |
| | set l {} |
| | foreach \ |
| | abr [mc MONTHS_ABBREV] \ |
| | full [mc MONTHS_FULL] { |
| | incr i |
| | dict set l [string tolower $abr] $i |
| | dict set l [string tolower $full] $i |
| | } |
| | lassign [UniquePrefixRegexp $l] regex lookup |
| | append re ( $regex ) |
| | dict set fieldSet month [incr fieldCount] |
| | append postcode "dict set date month \[" \ |
| | "dict get " [list $lookup] \ |
| | " " \[ {string tolower $field} \ |
| | [incr captureCount] \] \ |
| | "\]\n" |
| | } |
| | C { # Gregorian century |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet century [incr fieldCount] |
| | append postcode "dict set date century \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | d - e { # Day of month |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet dayOfMonth [incr fieldCount] |
| | append postcode "dict set date dayOfMonth \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | E { # Prefix for locale-specific codes |
| | set state %E |
| | } |
| | g { # ISO8601 2-digit year |
| | append re \\s*(\\d\\d) |
| | dict set fieldSet iso8601YearOfCentury \ |
| | [incr fieldCount] |
| | append postcode \ |
| | "dict set date iso8601YearOfCentury \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | G { # ISO8601 4-digit year |
| | append re \\s*(\\d\\d)(\\d\\d) |
| | dict set fieldSet iso8601Century [incr fieldCount] |
| | dict set fieldSet iso8601YearOfCentury \ |
| | [incr fieldCount] |
| | append postcode \ |
| | "dict set date iso8601Century \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" \ |
| | "dict set date iso8601YearOfCentury \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | H - k { # Hour of day |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet hour [incr fieldCount] |
| | append postcode "dict set date hour \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | I - l { # Hour, AM/PM |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet hourAMPM [incr fieldCount] |
| | append postcode "dict set date hourAMPM \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | j { # Day of year |
| | append re \\s*(\\d\\d?\\d?) |
| | dict set fieldSet dayOfYear [incr fieldCount] |
| | append postcode "dict set date dayOfYear \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | J { # Julian Day Number |
| | append re \\s*(\\d+) |
| | dict set fieldSet julianDay [incr fieldCount] |
| | append postcode "dict set date julianDay \[" \ |
| | "::scan \$field" [incr captureCount] " %ld" \ |
| | "\]\n" |
| | } |
| | m - N { # Month number |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet month [incr fieldCount] |
| | append postcode "dict set date month \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | M { # Minute |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet minute [incr fieldCount] |
| | append postcode "dict set date minute \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | n { # Literal newline |
| | append re \\n |
| | } |
| | O { # Prefix for locale numerics |
| | set state %O |
| | } |
| | p - P { # AM/PM indicator |
| | set l [list [string tolower [mc AM]] 0 \ |
| | [string tolower [mc PM]] 1] |
| | lassign [UniquePrefixRegexp $l] regex lookup |
| | append re ( $regex ) |
| | dict set fieldSet amPmIndicator [incr fieldCount] |
| | append postcode "dict set date amPmIndicator \[" \ |
| | "dict get " [list $lookup] " \[string tolower " \ |
| | "\$field" \ |
| | [incr captureCount] \ |
| | "\]\]\n" |
| | } |
| | Q { # Hi, Jeff! |
| | append re {Stardate\s+([-+]?\d+)(\d\d\d)[.](\d)} |
| | incr captureCount |
| | dict set fieldSet seconds [incr fieldCount] |
| | append postcode {dict set date seconds } \[ \ |
| | {ParseStarDate $field} [incr captureCount] \ |
| | { $field} [incr captureCount] \ |
| | { $field} [incr captureCount] \ |
| | \] \n |
| | } |
| | s { # Seconds from Posix Epoch |
| | |
| | |
| | |
| | append re {\s*([-+]?\d+)} |
| | dict set fieldSet seconds [incr fieldCount] |
| | append postcode {dict set date seconds } \[ \ |
| | {ScanWide $field} [incr captureCount] \] \n |
| | } |
| | S { # Second |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet second [incr fieldCount] |
| | append postcode "dict set date second \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | t { # Literal tab character |
| | append re \\t |
| | } |
| | u - w { # Day number within week, 0 or 7 == Sun |
| | |
| | append re \\s*(\\d) |
| | dict set fieldSet dayOfWeek [incr fieldCount] |
| | append postcode {::scan $field} [incr captureCount] \ |
| | { %d dow} \n \ |
| | { |
| | if { $dow == 0 } { |
| | set dow 7 |
| | } elseif { $dow > 7 } { |
| | return -code error \ |
| | -errorcode [list CLOCK badDayOfWeek] \ |
| | "day of week is greater than 7" |
| | } |
| | dict set date dayOfWeek $dow |
| | } |
| | } |
| | U { # Week of year. The first Sunday of |
| | |
| | |
| | append re \\s*\\d\\d? |
| | } |
| | V { # Week of ISO8601 year |
| |
|
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet iso8601Week [incr fieldCount] |
| | append postcode "dict set date iso8601Week \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | W { # Week of the year (00-53). The first |
| | |
| | |
| | |
| | append re \\s*\\d\\d? |
| | } |
| | y { # Two-digit Gregorian year |
| | append re \\s*(\\d\\d?) |
| | dict set fieldSet yearOfCentury [incr fieldCount] |
| | append postcode "dict set date yearOfCentury \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | Y { # 4-digit Gregorian year |
| | append re \\s*(\\d\\d)(\\d\\d) |
| | dict set fieldSet century [incr fieldCount] |
| | dict set fieldSet yearOfCentury [incr fieldCount] |
| | append postcode \ |
| | "dict set date century \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" \ |
| | "dict set date yearOfCentury \[" \ |
| | "::scan \$field" [incr captureCount] " %d" \ |
| | "\]\n" |
| | } |
| | z - Z { # Time zone name |
| | append re {(?:([-+]\d\d(?::?\d\d(?::?\d\d)?)?)|([[:alnum:]]{1,4}))} |
| | dict set fieldSet tzName [incr fieldCount] |
| | append postcode \ |
| | {if } \{ { $field} [incr captureCount] \ |
| | { ne "" } \} { } \{ \n \ |
| | {dict set date tzName $field} \ |
| | $captureCount \n \ |
| | \} { else } \{ \n \ |
| | {dict set date tzName } \[ \ |
| | {ConvertLegacyTimeZone $field} \ |
| | [incr captureCount] \] \n \ |
| | \} \n \ |
| | } |
| | % { # Literal percent character |
| | append re % |
| | } |
| | default { |
| | append re % |
| | if { ! [string is alnum $c] } { |
| | append re \\ |
| | } |
| | append re $c |
| | } |
| | } |
| | } |
| | %E { |
| | switch -exact -- $c { |
| | C { # Locale-dependent era |
| | set d {} |
| | foreach triple [mc LOCALE_ERAS] { |
| | lassign $triple t symbol year |
| | dict set d [string tolower $symbol] $year |
| | } |
| | lassign [UniquePrefixRegexp $d] regex lookup |
| | append re (?: $regex ) |
| | } |
| | E { |
| | set l {} |
| | dict set l [string tolower [mc BCE]] BCE |
| | dict set l [string tolower [mc CE]] CE |
| | dict set l b.c.e. BCE |
| | dict set l c.e. CE |
| | dict set l b.c. BCE |
| | dict set l a.d. CE |
| | lassign [UniquePrefixRegexp $l] regex lookup |
| | append re ( $regex ) |
| | dict set fieldSet era [incr fieldCount] |
| | append postcode "dict set date era \["\ |
| | "dict get " [list $lookup] \ |
| | { } \[ {string tolower $field} \ |
| | [incr captureCount] \] \ |
| | "\]\n" |
| | } |
| | y { # Locale-dependent year of the era |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | incr captureCount |
| | } |
| | default { |
| | append re %E |
| | if { ! [string is alnum $c] } { |
| | append re \\ |
| | } |
| | append re $c |
| | } |
| | } |
| | set state {} |
| | } |
| | %O { |
| | switch -exact -- $c { |
| | d - e { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet dayOfMonth [incr fieldCount] |
| | append postcode "dict set date dayOfMonth \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | H - k { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet hour [incr fieldCount] |
| | append postcode "dict set date hour \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | I - l { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet hourAMPM [incr fieldCount] |
| | append postcode "dict set date hourAMPM \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | m { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet month [incr fieldCount] |
| | append postcode "dict set date month \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | M { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet minute [incr fieldCount] |
| | append postcode "dict set date minute \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | S { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet second [incr fieldCount] |
| | append postcode "dict set date second \[" \ |
| | "dict get " [list $lookup] " \$field" \ |
| | [incr captureCount] \ |
| | "\]\n" |
| | } |
| | u - w { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet dayOfWeek [incr fieldCount] |
| | append postcode "set dow \[dict get " [list $lookup] \ |
| | { $field} [incr captureCount] \] \n \ |
| | { |
| | if { $dow == 0 } { |
| | set dow 7 |
| | } elseif { $dow > 7 } { |
| | return -code error \ |
| | -errorcode [list CLOCK badDayOfWeek] \ |
| | "day of week is greater than 7" |
| | } |
| | dict set date dayOfWeek $dow |
| | } |
| | } |
| | y { |
| | lassign [LocaleNumeralMatcher $locale] regex lookup |
| | append re $regex |
| | dict set fieldSet yearOfCentury [incr fieldCount] |
| | append postcode {dict set date yearOfCentury } \[ \ |
| | {dict get } [list $lookup] { $field} \ |
| | [incr captureCount] \] \n |
| | } |
| | default { |
| | append re %O |
| | if { ! [string is alnum $c] } { |
| | append re \\ |
| | } |
| | append re $c |
| | } |
| | } |
| | set state {} |
| | } |
| | } |
| | } |
| |
|
| | |
| |
|
| | append re $state \\s*\$ |
| |
|
| | |
| |
|
| | set procBody {} |
| | append procBody "variable ::tcl::clock::TZData" \n |
| | append procBody "if \{ !\[ regexp -nocase [list $re] \$string ->" |
| | for { set i 1 } { $i <= $captureCount } { incr i } { |
| | append procBody " " field $i |
| | } |
| | append procBody "\] \} \{" \n |
| | append procBody { |
| | return -code error -errorcode [list CLOCK badInputString] \ |
| | {input string does not match supplied format} |
| | } |
| | append procBody \}\n |
| | append procBody "set date \[dict create\]" \n |
| | append procBody {dict set date tzName $timeZone} \n |
| | append procBody $postcode |
| | append procBody [list set changeover [mc GREGORIAN_CHANGE_DATE]] \n |
| |
|
| | |
| | |
| |
|
| | if { ![dict exists $fieldSet seconds] |
| | && ![dict exists $fieldSet starDate] } { |
| | if { [dict exists $fieldSet tzName] } { |
| | append procBody { |
| | set timeZone [dict get $date tzName] |
| | } |
| | } |
| | append procBody { |
| | ::tcl::clock::SetupTimeZone $timeZone |
| | } |
| | } |
| |
|
| | |
| |
|
| | append procBody [MakeParseCodeFromFields $fieldSet $DateParseActions] |
| |
|
| | |
| |
|
| | append procBody [MakeParseCodeFromFields $fieldSet $TimeParseActions] |
| |
|
| | |
| | |
| | |
| |
|
| | if { ![dict exists $fieldSet seconds] |
| | && ![dict exists $fieldSet starDate] } { |
| | append procBody { |
| | if { [dict get $date julianDay] > 5373484 } { |
| | return -code error -errorcode [list CLOCK dateTooLarge] \ |
| | "requested date too large to represent" |
| | } |
| | dict set date localSeconds [expr { |
| | -210866803200 |
| | + ( 86400 * wide([dict get $date julianDay]) ) |
| | + [dict get $date secondOfDay] |
| | }] |
| | } |
| |
|
| | |
| |
|
| | append procBody { |
| | set date [::tcl::clock::ConvertLocalToUTC $date[set date {}] \ |
| | $TZData($timeZone) $changeover] |
| | } |
| | } |
| |
|
| | |
| |
|
| | append procBody {return [dict get $date seconds]} \n |
| |
|
| | proc $procName { string baseTime timeZone } $procBody |
| |
|
| | |
| |
|
| | return $procName |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::LocaleNumeralMatcher {l} { |
| | variable LocaleNumeralCache |
| |
|
| | if { ![dict exists $LocaleNumeralCache $l] } { |
| | set d {} |
| | set i 0 |
| | set sep \( |
| | foreach n [mc LOCALE_NUMERALS] { |
| | dict set d $n $i |
| | regsub -all {[^[:alnum:]]} $n \\\\& subex |
| | append re $sep $subex |
| | set sep | |
| | incr i |
| | } |
| | append re \) |
| | dict set LocaleNumeralCache $l [list $re $d] |
| | } |
| | return [dict get $LocaleNumeralCache $l] |
| | } |
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::UniquePrefixRegexp { data } { |
| | |
| | |
| | |
| | |
| |
|
| | set prefixMapping [dict create] |
| | set successors [dict create {} {}] |
| |
|
| | |
| |
|
| | foreach { key value } $data { |
| | |
| |
|
| | set prefix {} |
| | foreach char [split $key {}] { |
| | set oldPrefix $prefix |
| | dict set successors $oldPrefix $char {} |
| | append prefix $char |
| |
|
| | |
| | |
| |
|
| | dict lappend prefixMapping $prefix $value |
| | if { ![dict exists $successors $prefix] } { |
| | dict set successors $prefix {} |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | set uniquePrefixMapping {} |
| | dict for { key valueList } $prefixMapping { |
| | if { [llength $valueList] == 1 } { |
| | dict set uniquePrefixMapping $key [lindex $valueList 0] |
| | } |
| | } |
| | foreach { key value } $data { |
| | dict set uniquePrefixMapping $key $value |
| | } |
| |
|
| | |
| |
|
| | return [list \ |
| | [MakeUniquePrefixRegexp $successors $uniquePrefixMapping {}] \ |
| | $uniquePrefixMapping] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::MakeUniquePrefixRegexp { successors |
| | uniquePrefixMapping |
| | prefixString } { |
| |
|
| | |
| |
|
| | set schars [lsort -ascii [dict keys [dict get $successors $prefixString]]] |
| | if { [llength $schars] == 0 } { |
| | return {} |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | set re {} |
| | if { |
| | [dict exists $uniquePrefixMapping $prefixString] |
| | || [llength $schars] > 1 |
| | } then { |
| | append re "(?:" |
| | } |
| |
|
| | |
| |
|
| | set sep "" |
| | foreach { c } $schars { |
| | set nextPrefix $prefixString$c |
| | regsub -all {[^[:alnum:]]} $c \\\\& rechar |
| | append re $sep $rechar \ |
| | [MakeUniquePrefixRegexp \ |
| | $successors $uniquePrefixMapping $nextPrefix] |
| | set sep | |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | if { [dict exists $uniquePrefixMapping $prefixString] } { |
| | append re ")?" |
| | } elseif { [llength $schars] > 1 } { |
| | append re ")" |
| | } |
| |
|
| | return $re |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::MakeParseCodeFromFields { dateFields parseActions } { |
| |
|
| | set currPrio 999 |
| | set currFieldPos [list] |
| | set currCodeBurst { |
| | error "in ::tcl::clock::MakeParseCodeFromFields: can't happen" |
| | } |
| |
|
| | foreach { fieldSet prio parseAction } $parseActions { |
| | |
| | |
| |
|
| | if { $prio > $currPrio } { |
| | break |
| | } |
| |
|
| | |
| | |
| |
|
| | set fieldPos [list] |
| | set ok true |
| | foreach field $fieldSet { |
| | if { ! [dict exists $dateFields $field] } { |
| | set ok 0 |
| | break |
| | } |
| | lappend fieldPos [dict get $dateFields $field] |
| | } |
| |
|
| | |
| | if { !$ok } { |
| | continue |
| | } |
| |
|
| | |
| |
|
| | set fPos [lsort -integer -decreasing $fieldPos] |
| |
|
| | if { $prio == $currPrio } { |
| | foreach currPos $currFieldPos newPos $fPos { |
| | if { |
| | ![string is integer $newPos] |
| | || ![string is integer $currPos] |
| | || $newPos > $currPos |
| | } then { |
| | break |
| | } |
| | if { $newPos < $currPos } { |
| | set ok 0 |
| | break |
| | } |
| | } |
| | } |
| | if { !$ok } { |
| | continue |
| | } |
| |
|
| | |
| |
|
| | set currPrio $prio |
| | set currFieldPos $fPos |
| | set currCodeBurst $parseAction |
| | } |
| |
|
| | return $currCodeBurst |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::EnterLocale { locale } { |
| | if { $locale eq {system} } { |
| | if { $::tcl_platform(platform) ne {windows} } { |
| | |
| | |
| |
|
| | set locale current |
| | } else { |
| | |
| | |
| | |
| | |
| |
|
| | mcpackagelocale set [mclocale] |
| |
|
| | |
| | |
| |
|
| | set locale [mclocale]_windows |
| | if { ! [mcpackagelocale present $locale] } { |
| | LoadWindowsDateTimeFormats $locale |
| | } |
| | } |
| | } |
| | if { $locale eq {current}} { |
| | set locale [mclocale] |
| | } |
| | |
| | mcpackagelocale set $locale |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } { |
| | |
| |
|
| | variable NoRegistry |
| | if { [info exists NoRegistry] } return |
| |
|
| | if { ![catch { |
| | registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ |
| | sShortDate |
| | } string] } { |
| | set quote {} |
| | set datefmt {} |
| | foreach { unquoted quoted } [split $string '] { |
| | append datefmt $quote [string map { |
| | dddd %A |
| | ddd %a |
| | dd %d |
| | d %e |
| | MMMM %B |
| | MMM %b |
| | MM %m |
| | M %N |
| | yyyy %Y |
| | yy %y |
| | y %y |
| | gg {} |
| | } $unquoted] |
| | if { $quoted eq {} } { |
| | set quote ' |
| | } else { |
| | set quote $quoted |
| | } |
| | } |
| | ::msgcat::mcset $locale DATE_FORMAT $datefmt |
| | } |
| |
|
| | if { ![catch { |
| | registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ |
| | sLongDate |
| | } string] } { |
| | set quote {} |
| | set ldatefmt {} |
| | foreach { unquoted quoted } [split $string '] { |
| | append ldatefmt $quote [string map { |
| | dddd %A |
| | ddd %a |
| | dd %d |
| | d %e |
| | MMMM %B |
| | MMM %b |
| | MM %m |
| | M %N |
| | yyyy %Y |
| | yy %y |
| | y %y |
| | gg {} |
| | } $unquoted] |
| | if { $quoted eq {} } { |
| | set quote ' |
| | } else { |
| | set quote $quoted |
| | } |
| | } |
| | ::msgcat::mcset $locale LOCALE_DATE_FORMAT $ldatefmt |
| | } |
| |
|
| | if { ![catch { |
| | registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ |
| | sTimeFormat |
| | } string] } { |
| | set quote {} |
| | set timefmt {} |
| | foreach { unquoted quoted } [split $string '] { |
| | append timefmt $quote [string map { |
| | HH %H |
| | H %k |
| | hh %I |
| | h %l |
| | mm %M |
| | m %M |
| | ss %S |
| | s %S |
| | tt %p |
| | t %p |
| | } $unquoted] |
| | if { $quoted eq {} } { |
| | set quote ' |
| | } else { |
| | set quote $quoted |
| | } |
| | } |
| | ::msgcat::mcset $locale TIME_FORMAT $timefmt |
| | } |
| |
|
| | catch { |
| | ::msgcat::mcset $locale DATE_TIME_FORMAT "$datefmt $timefmt" |
| | } |
| | catch { |
| | ::msgcat::mcset $locale LOCALE_DATE_TIME_FORMAT "$ldatefmt $timefmt" |
| | } |
| |
|
| | return |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::LocalizeFormat { locale format } { |
| |
|
| | |
| | set key FORMAT_$format |
| |
|
| | if { [::msgcat::mcexists -exactlocale -exactnamespace $key] } { |
| | return [mc $key] |
| | } |
| | |
| | |
| | |
| | |
| |
|
| | set list { |
| | %% %% |
| | %D %m/%d/%Y |
| | %+ {%a %b %e %H:%M:%S %Z %Y} |
| | } |
| | lappend list %EY [string map $list [mc LOCALE_YEAR_FORMAT]] |
| | lappend list %T [string map $list [mc TIME_FORMAT_24_SECS]] |
| | lappend list %R [string map $list [mc TIME_FORMAT_24]] |
| | lappend list %r [string map $list [mc TIME_FORMAT_12]] |
| | lappend list %X [string map $list [mc TIME_FORMAT]] |
| | lappend list %EX [string map $list [mc LOCALE_TIME_FORMAT]] |
| | lappend list %x [string map $list [mc DATE_FORMAT]] |
| | lappend list %Ex [string map $list [mc LOCALE_DATE_FORMAT]] |
| | lappend list %c [string map $list [mc DATE_TIME_FORMAT]] |
| | lappend list %Ec [string map $list [mc LOCALE_DATE_TIME_FORMAT]] |
| | set format [string map $list $format] |
| |
|
| | ::msgcat::mcset $locale $key $format |
| | return $format |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::FormatNumericTimeZone { z } { |
| | if { $z < 0 } { |
| | set z [expr { - $z }] |
| | set retval - |
| | } else { |
| | set retval + |
| | } |
| | append retval [::format %02d [expr { $z / 3600 }]] |
| | set z [expr { $z % 3600 }] |
| | append retval [::format %02d [expr { $z / 60 }]] |
| | set z [expr { $z % 60 }] |
| | if { $z != 0 } { |
| | append retval [::format %02d $z] |
| | } |
| | return $retval |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::FormatStarDate { date } { |
| | variable Roddenberry |
| |
|
| | |
| |
|
| | set doy [expr { [dict get $date dayOfYear] - 1 }] |
| |
|
| | |
| |
|
| | set lp [IsGregorianLeapYear $date] |
| |
|
| | |
| |
|
| | if { $lp } { |
| | set fractYear [expr { 1000 * $doy / 366 }] |
| | } else { |
| | set fractYear [expr { 1000 * $doy / 365 }] |
| | } |
| |
|
| | |
| |
|
| | return [::format "Stardate %02d%03d.%1d" \ |
| | [expr { [dict get $date year] - $Roddenberry }] \ |
| | $fractYear \ |
| | [expr { [dict get $date localSeconds] % 86400 |
| | / ( 86400 / 10 ) }]] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ParseStarDate { year fractYear fractDay } { |
| | variable Roddenberry |
| |
|
| | |
| |
|
| | set date [dict create \ |
| | gregorian 1 \ |
| | era CE \ |
| | year [expr { $year + $Roddenberry }] \ |
| | dayOfYear [expr { $fractYear * 365 / 1000 + 1 }]] |
| | set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]] |
| |
|
| | |
| |
|
| | set lp [IsGregorianLeapYear $date] |
| |
|
| | |
| | |
| |
|
| | if { $lp } { |
| | dict set date dayOfYear \ |
| | [expr { $fractYear * 366 / 1000 + 1 }] |
| | } else { |
| | dict set date dayOfYear \ |
| | [expr { $fractYear * 365 / 1000 + 1 }] |
| | } |
| | dict unset date julianDay |
| | dict unset date gregorian |
| | set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]] |
| |
|
| | return [expr { |
| | 86400 * [dict get $date julianDay] |
| | - 210866803200 |
| | + ( 86400 / 10 ) * $fractDay |
| | }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ScanWide { str } { |
| | set count [::scan $str {%ld %c} result junk] |
| | if { $count != 1 } { |
| | return -code error -errorcode [list CLOCK notAnInteger $str] \ |
| | "\"$str\" is not an integer" |
| | } |
| | if { [incr result 0] != $str } { |
| | return -code error -errorcode [list CLOCK integervalueTooLarge] \ |
| | "integer value too large to represent" |
| | } |
| | return $result |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::InterpretTwoDigitYear { date baseTime |
| | { twoDigitField yearOfCentury } |
| | { fourDigitField year } } { |
| | set yr [dict get $date $twoDigitField] |
| | if { $yr <= 37 } { |
| | dict set date $fourDigitField [expr { $yr + 2000 }] |
| | } else { |
| | dict set date $fourDigitField [expr { $yr + 1900 }] |
| | } |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AssignBaseYear { date baseTime timezone changeover } { |
| | variable TZData |
| |
|
| | |
| | |
| |
|
| | set date2 [GetDateFields $baseTime $TZData($timezone) $changeover] |
| |
|
| | |
| |
|
| | dict set date era [dict get $date2 era] |
| | dict set date year [dict get $date2 year] |
| |
|
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AssignBaseIso8601Year {date baseTime timeZone changeover} { |
| | variable TZData |
| |
|
| | |
| |
|
| | set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] |
| |
|
| | |
| |
|
| | dict set date era CE |
| | dict set date iso8601Year [dict get $date2 iso8601Year] |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AssignBaseMonth {date baseTime timezone changeover} { |
| | variable TZData |
| |
|
| | |
| |
|
| | set date2 [GetDateFields $baseTime $TZData($timezone) $changeover] |
| | dict set date era [dict get $date2 era] |
| | dict set date year [dict get $date2 year] |
| | dict set date month [dict get $date2 month] |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AssignBaseWeek {date baseTime timeZone changeover} { |
| | variable TZData |
| |
|
| | |
| |
|
| | set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] |
| |
|
| | |
| |
|
| | dict set date era CE |
| | dict set date iso8601Year [dict get $date2 iso8601Year] |
| | dict set date iso8601Week [dict get $date2 iso8601Week] |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AssignBaseJulianDay { date baseTime timeZone changeover } { |
| | variable TZData |
| |
|
| | |
| |
|
| | set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] |
| | dict set date julianDay [dict get $date2 julianDay] |
| |
|
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::InterpretHMSP { date } { |
| | set hr [dict get $date hourAMPM] |
| | if { $hr == 12 } { |
| | set hr 0 |
| | } |
| | if { [dict get $date amPmIndicator] } { |
| | incr hr 12 |
| | } |
| | dict set date hour $hr |
| | return [InterpretHMS $date[set date {}]] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::InterpretHMS { date } { |
| | return [expr { |
| | ( [dict get $date hour] * 60 |
| | + [dict get $date minute] ) * 60 |
| | + [dict get $date second] |
| | }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::GetSystemTimeZone {} { |
| | variable CachedSystemTimeZone |
| | variable TimeZoneBad |
| |
|
| | if {[set result [getenv TCL_TZ]] ne {}} { |
| | set timezone $result |
| | } elseif {[set result [getenv TZ]] ne {}} { |
| | set timezone $result |
| | } else { |
| | |
| | |
| | if { [info exists CachedSystemTimeZone] } { |
| | set timezone $CachedSystemTimeZone |
| | } elseif { $::tcl_platform(platform) eq {windows} } { |
| | set timezone [GuessWindowsTimeZone] |
| | } elseif { [file exists /etc/localtime] |
| | && ![catch {ReadZoneinfoFile \ |
| | Tcl/Localtime /etc/localtime}] } { |
| | set timezone :Tcl/Localtime |
| | } else { |
| | set timezone :localtime |
| | } |
| | set CachedSystemTimeZone $timezone |
| | } |
| | if { ![dict exists $TimeZoneBad $timezone] } { |
| | dict set TimeZoneBad $timezone [catch {SetupTimeZone $timezone}] |
| | } |
| | if { [dict get $TimeZoneBad $timezone] } { |
| | return :localtime |
| | } else { |
| | return $timezone |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ConvertLegacyTimeZone { tzname } { |
| | variable LegacyTimeZone |
| |
|
| | set tzname [string tolower $tzname] |
| | if { ![dict exists $LegacyTimeZone $tzname] } { |
| | return -code error -errorcode [list CLOCK badTZName $tzname] \ |
| | "time zone \"$tzname\" not found" |
| | } |
| | return [dict get $LegacyTimeZone $tzname] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::SetupTimeZone { timezone } { |
| | variable TZData |
| |
|
| | if {! [info exists TZData($timezone)] } { |
| | variable MINWIDE |
| | if { $timezone eq {:localtime} } { |
| | |
| |
|
| | } elseif { |
| | [regexp {^([-+])(\d\d)(?::?(\d\d)(?::?(\d\d))?)?} $timezone \ |
| | -> s hh mm ss] |
| | } then { |
| | |
| |
|
| | ::scan $hh %d hh |
| | if { $mm eq {} } { |
| | set mm 0 |
| | } else { |
| | ::scan $mm %d mm |
| | } |
| | if { $ss eq {} } { |
| | set ss 0 |
| | } else { |
| | ::scan $ss %d ss |
| | } |
| | set offset [expr { ( $hh * 60 + $mm ) * 60 + $ss }] |
| | if { $s eq {-} } { |
| | set offset [expr { - $offset }] |
| | } |
| | set TZData($timezone) [list [list $MINWIDE $offset -1 $timezone]] |
| |
|
| | } elseif { [string index $timezone 0] eq {:} } { |
| | |
| |
|
| | if { |
| | [catch { |
| | LoadTimeZoneFile [string range $timezone 1 end] |
| | }] && [catch { |
| | LoadZoneinfoFile [string range $timezone 1 end] |
| | }] |
| | } then { |
| | return -code error \ |
| | -errorcode [list CLOCK badTimeZone $timezone] \ |
| | "time zone \"$timezone\" not found" |
| | } |
| | } elseif { ![catch {ParsePosixTimeZone $timezone} tzfields] } { |
| | |
| |
|
| | if { [catch {ProcessPosixTimeZone $tzfields} data opts] } { |
| | if { [lindex [dict get $opts -errorcode] 0] eq {CLOCK} } { |
| | dict unset opts -errorinfo |
| | } |
| | return -options $opts $data |
| | } else { |
| | set TZData($timezone) $data |
| | } |
| |
|
| | } else { |
| | |
| | |
| |
|
| | if { [catch { LoadTimeZoneFile $timezone }] |
| | && [catch { LoadZoneinfoFile $timezone } - opts] } { |
| | dict unset opts -errorinfo |
| | return -options $opts "time zone $timezone not found" |
| | } |
| | set TZData($timezone) $TZData(:$timezone) |
| | } |
| | } |
| |
|
| | return |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::GuessWindowsTimeZone {} { |
| | variable WinZoneInfo |
| | variable NoRegistry |
| | variable TimeZoneBad |
| |
|
| | if { [info exists NoRegistry] } { |
| | return :localtime |
| | } |
| |
|
| | |
| |
|
| | if { [catch { |
| | set rpath HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\TimeZoneInformation |
| | set data [list \ |
| | [expr { -60 |
| | * [registry get $rpath Bias] }] \ |
| | [expr { -60 |
| | * [registry get $rpath StandardBias] }] \ |
| | [expr { -60 \ |
| | * [registry get $rpath DaylightBias] }]] |
| | set stdtzi [registry get $rpath StandardStart] |
| | foreach ind {0 2 14 4 6 8 10 12} { |
| | binary scan $stdtzi @${ind}s val |
| | lappend data $val |
| | } |
| | set daytzi [registry get $rpath DaylightStart] |
| | foreach ind {0 2 14 4 6 8 10 12} { |
| | binary scan $daytzi @${ind}s val |
| | lappend data $val |
| | } |
| | }] } { |
| | |
| |
|
| | return :localtime |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | if { [dict exists $WinZoneInfo $data] } { |
| | set tzname [dict get $WinZoneInfo $data] |
| | if { ! [dict exists $TimeZoneBad $tzname] } { |
| | dict set TimeZoneBad $tzname [catch {SetupTimeZone $tzname}] |
| | } |
| | } else { |
| | set tzname {} |
| | } |
| | if { $tzname eq {} || [dict get $TimeZoneBad $tzname] } { |
| | lassign $data \ |
| | bias stdBias dstBias \ |
| | stdYear stdMonth stdDayOfWeek stdDayOfMonth \ |
| | stdHour stdMinute stdSecond stdMillisec \ |
| | dstYear dstMonth dstDayOfWeek dstDayOfMonth \ |
| | dstHour dstMinute dstSecond dstMillisec |
| | set stdDelta [expr { $bias + $stdBias }] |
| | set dstDelta [expr { $bias + $dstBias }] |
| | if { $stdDelta <= 0 } { |
| | set stdSignum + |
| | set stdDelta [expr { - $stdDelta }] |
| | set dispStdSignum - |
| | } else { |
| | set stdSignum - |
| | set dispStdSignum + |
| | } |
| | set hh [::format %02d [expr { $stdDelta / 3600 }]] |
| | set mm [::format %02d [expr { ($stdDelta / 60 ) % 60 }]] |
| | set ss [::format %02d [expr { $stdDelta % 60 }]] |
| | set tzname {} |
| | append tzname < $dispStdSignum $hh $mm > $stdSignum $hh : $mm : $ss |
| | if { $stdMonth >= 0 } { |
| | if { $dstDelta <= 0 } { |
| | set dstSignum + |
| | set dstDelta [expr { - $dstDelta }] |
| | set dispDstSignum - |
| | } else { |
| | set dstSignum - |
| | set dispDstSignum + |
| | } |
| | set hh [::format %02d [expr { $dstDelta / 3600 }]] |
| | set mm [::format %02d [expr { ($dstDelta / 60 ) % 60 }]] |
| | set ss [::format %02d [expr { $dstDelta % 60 }]] |
| | append tzname < $dispDstSignum $hh $mm > $dstSignum $hh : $mm : $ss |
| | if { $dstYear == 0 } { |
| | append tzname ,M $dstMonth . $dstDayOfMonth . $dstDayOfWeek |
| | } else { |
| | |
| | |
| | |
| | |
| | |
| | return :localtime |
| | } |
| | append tzname / [::format %02d $dstHour] \ |
| | : [::format %02d $dstMinute] \ |
| | : [::format %02d $dstSecond] |
| | if { $stdYear == 0 } { |
| | append tzname ,M $stdMonth . $stdDayOfMonth . $stdDayOfWeek |
| | } else { |
| | |
| | |
| | |
| | |
| | |
| | return :localtime |
| | } |
| | append tzname / [::format %02d $stdHour] \ |
| | : [::format %02d $stdMinute] \ |
| | : [::format %02d $stdSecond] |
| | } |
| | dict set WinZoneInfo $data $tzname |
| | } |
| |
|
| | return [dict get $WinZoneInfo $data] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::LoadTimeZoneFile { fileName } { |
| | variable DataDir |
| | variable TZData |
| |
|
| | if { [info exists TZData($fileName)] } { |
| | return |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | if { ![regexp {^[[.-.][:alpha:]_]+(?:/[[.-.][:alpha:]_]+)*$} $fileName] } { |
| | return -code error \ |
| | -errorcode [list CLOCK badTimeZone $:fileName] \ |
| | "time zone \":$fileName\" not valid" |
| | } |
| | try { |
| | source -encoding utf-8 [file join $DataDir $fileName] |
| | } on error {} { |
| | return -code error \ |
| | -errorcode [list CLOCK badTimeZone :$fileName] \ |
| | "time zone \":$fileName\" not found" |
| | } |
| | return |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::LoadZoneinfoFile { fileName } { |
| | variable ZoneinfoPaths |
| |
|
| | |
| | |
| | |
| |
|
| | if { ![regexp {^[[.-.][:alpha:]_]+(?:/[[.-.][:alpha:]_]+)*$} $fileName] } { |
| | return -code error \ |
| | -errorcode [list CLOCK badTimeZone $:fileName] \ |
| | "time zone \":$fileName\" not valid" |
| | } |
| | foreach d $ZoneinfoPaths { |
| | set fname [file join $d $fileName] |
| | if { [file readable $fname] && [file isfile $fname] } { |
| | break |
| | } |
| | unset fname |
| | } |
| | ReadZoneinfoFile $fileName $fname |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ReadZoneinfoFile {fileName fname} { |
| | variable MINWIDE |
| | variable TZData |
| | if { ![file exists $fname] } { |
| | return -code error "$fileName not found" |
| | } |
| |
|
| | if { [file size $fname] > 262144 } { |
| | return -code error "$fileName too big" |
| | } |
| |
|
| | |
| |
|
| | set f [open $fname r] |
| | fconfigure $f -translation binary |
| | set d [read $f] |
| | close $f |
| |
|
| | |
| | |
| |
|
| | binary scan $d a4a1x15IIIIII \ |
| | magic version nIsGMT nIsStd nLeap nTime nType nChar |
| | set seek 44 |
| | set ilen 4 |
| | set iformat I |
| | if { $magic != {TZif} } { |
| | return -code error "$fileName not a time zone information file" |
| | } |
| | if { $nType > 255 } { |
| | return -code error "$fileName contains too many time types" |
| | } |
| | |
| | if { $nLeap != 0 } { |
| | return -code error "$fileName contains leap seconds" |
| | } |
| |
|
| | |
| | |
| |
|
| | if {$version eq "2"} { |
| | set seek [expr { |
| | 44 |
| | + 5 * $nTime |
| | + 6 * $nType |
| | + 4 * $nLeap |
| | + $nIsStd |
| | + $nIsGMT |
| | + $nChar |
| | }] |
| | binary scan $d @${seek}a4a1x15IIIIII \ |
| | magic version nIsGMT nIsStd nLeap nTime nType nChar |
| | if {$magic ne {TZif}} { |
| | return -code error "seek address $seek miscomputed, magic = $magic" |
| | } |
| | set iformat W |
| | set ilen 8 |
| | incr seek 44 |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | binary scan $d @${seek}${iformat}${nTime}c${nTime} times tempCodes |
| | incr seek [expr { ($ilen + 1) * $nTime }] |
| | set times [linsert $times 0 $MINWIDE] |
| | set codes {} |
| | foreach c $tempCodes { |
| | lappend codes [expr { $c & 0xFF }] |
| | } |
| | set codes [linsert $codes 0 0] |
| |
|
| | |
| | |
| | |
| |
|
| | for { set i 0 } { $i < $nType } { incr i } { |
| | binary scan $d @${seek}Icc gmtOff isDst abbrInd |
| | lappend types [list $gmtOff $isDst $abbrInd] |
| | incr seek 6 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | binary scan $d @${seek}a${nChar} abbrs |
| | incr seek ${nChar} |
| | set abbrList [split $abbrs \0] |
| | set i 0 |
| | set abbrevs {} |
| | foreach a $abbrList { |
| | for {set j 0} {$j <= [string length $a]} {incr j} { |
| | dict set abbrevs $i [string range $a $j end] |
| | incr i |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | set r {} |
| | set lastTime $MINWIDE |
| | foreach t $times c $codes { |
| | if { $t < $lastTime } { |
| | return -code error "$fileName has times out of order" |
| | } |
| | set lastTime $t |
| | lassign [lindex $types $c] gmtoff isDst abbrInd |
| | set abbrev [dict get $abbrevs $abbrInd] |
| | lappend r [list $t $gmtoff $isDst $abbrev] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | if {$version eq {2}} { |
| | set seek [expr {$seek + 8 * $nLeap + $nIsStd + $nIsGMT + 1}] |
| | set last [string first \n $d $seek] |
| | set posix [string range $d $seek [expr {$last-1}]] |
| | if {[llength $posix] > 0} { |
| | set posixFields [ParsePosixTimeZone $posix] |
| | foreach tuple [ProcessPosixTimeZone $posixFields] { |
| | lassign $tuple t gmtoff isDst abbrev |
| | if {$t > $lastTime} { |
| | lappend r $tuple |
| | } |
| | } |
| | } |
| | } |
| |
|
| | set TZData(:$fileName) $r |
| |
|
| | return |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ParsePosixTimeZone { tz } { |
| | if {[regexp -expanded -nocase -- { |
| | ^ |
| | |
| | ([[:alpha:]]+ | <[-+[:alnum:]]+>) |
| | |
| | ([-+]?) |
| | |
| | ([[:digit:]]{1,2}) |
| | (?: |
| | |
| | : ([[:digit:]]{1,2}) |
| | (?: |
| | |
| | : ([[:digit:]]{1,2} ) |
| | )? |
| | )? |
| | (?: |
| | |
| | ([[:alpha:]]+ | <[-+[:alnum:]]+>) |
| | (?: |
| | (?: |
| | |
| | ([-+]?) |
| | |
| | ([[:digit:]]{1,2}) |
| | (?: |
| | |
| | : ([[:digit:]]{1,2}) |
| | (?: |
| | |
| | : ([[:digit:]]{1,2}) |
| | )? |
| | )? |
| | )? |
| | (?: |
| | , |
| | (?: |
| | |
| | ( J ? ) ( [[:digit:]]+ ) |
| | | M |
| | |
| | ( [[:digit:]] + ) |
| | [.] ( [[:digit:]] + ) |
| | [.] ( [[:digit:]] + ) |
| | ) |
| | (?: |
| | |
| | / ( [[:digit:]]{1,2} ) |
| | (?: |
| | |
| | : ( [[:digit:]]{1,2} ) |
| | (?: |
| | |
| | : ( [[:digit:]]{1,2} ) |
| | )? |
| | )? |
| | )? |
| | , |
| | (?: |
| | |
| | ( J ? ) ( [[:digit:]]+ ) |
| | | M |
| | |
| | ( [[:digit:]] + ) |
| | [.] ( [[:digit:]] + ) |
| | [.] ( [[:digit:]] + ) |
| | ) |
| | (?: |
| | |
| | / ( [[:digit:]]{1,2} ) |
| | (?: |
| | |
| | : ( [[:digit:]]{1,2} ) |
| | (?: |
| | |
| | : ( [[:digit:]]{1,2} ) |
| | )? |
| | )? |
| | )? |
| | )? |
| | )? |
| | )? |
| | $ |
| | } $tz -> x(stdName) x(stdSignum) x(stdHours) x(stdMinutes) x(stdSeconds) \ |
| | x(dstName) x(dstSignum) x(dstHours) x(dstMinutes) x(dstSeconds) \ |
| | x(startJ) x(startDayOfYear) \ |
| | x(startMonth) x(startWeekOfMonth) x(startDayOfWeek) \ |
| | x(startHours) x(startMinutes) x(startSeconds) \ |
| | x(endJ) x(endDayOfYear) \ |
| | x(endMonth) x(endWeekOfMonth) x(endDayOfWeek) \ |
| | x(endHours) x(endMinutes) x(endSeconds)] } { |
| | |
| |
|
| | return [array get x] |
| | } |
| |
|
| | return -code error\ |
| | -errorcode [list CLOCK badTimeZone $tz] \ |
| | "unable to parse time zone specification \"$tz\"" |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ProcessPosixTimeZone { z } { |
| | variable MINWIDE |
| | variable TZData |
| |
|
| | |
| |
|
| | set stdName [dict get $z stdName] |
| | if { [string index $stdName 0] eq {<} } { |
| | set stdName [string range $stdName 1 end-1] |
| | } |
| | if { [dict get $z stdSignum] eq {-} } { |
| | set stdSignum +1 |
| | } else { |
| | set stdSignum -1 |
| | } |
| | set stdHours [lindex [::scan [dict get $z stdHours] %d] 0] |
| | if { [dict get $z stdMinutes] ne {} } { |
| | set stdMinutes [lindex [::scan [dict get $z stdMinutes] %d] 0] |
| | } else { |
| | set stdMinutes 0 |
| | } |
| | if { [dict get $z stdSeconds] ne {} } { |
| | set stdSeconds [lindex [::scan [dict get $z stdSeconds] %d] 0] |
| | } else { |
| | set stdSeconds 0 |
| | } |
| | set stdOffset [expr { |
| | (($stdHours * 60 + $stdMinutes) * 60 + $stdSeconds) * $stdSignum |
| | }] |
| | set data [list [list $MINWIDE $stdOffset 0 $stdName]] |
| |
|
| | |
| |
|
| | set dstName [dict get $z dstName] |
| | if { $dstName eq {} } { |
| | return $data |
| | } |
| | if { [string index $dstName 0] eq {<} } { |
| | set dstName [string range $dstName 1 end-1] |
| | } |
| |
|
| | |
| |
|
| | if { [dict get $z dstSignum] eq {-} } { |
| | set dstSignum +1 |
| | } else { |
| | set dstSignum -1 |
| | } |
| | if { [dict get $z dstHours] eq {} } { |
| | set dstOffset [expr { 3600 + $stdOffset }] |
| | } else { |
| | set dstHours [lindex [::scan [dict get $z dstHours] %d] 0] |
| | if { [dict get $z dstMinutes] ne {} } { |
| | set dstMinutes [lindex [::scan [dict get $z dstMinutes] %d] 0] |
| | } else { |
| | set dstMinutes 0 |
| | } |
| | if { [dict get $z dstSeconds] ne {} } { |
| | set dstSeconds [lindex [::scan [dict get $z dstSeconds] %d] 0] |
| | } else { |
| | set dstSeconds 0 |
| | } |
| | set dstOffset [expr { |
| | (($dstHours*60 + $dstMinutes) * 60 + $dstSeconds) * $dstSignum |
| | }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | if { |
| | [dict get $z startDayOfYear] eq {} |
| | && [dict get $z startMonth] eq {} |
| | } then { |
| | if {($stdSignum * $stdHours>=0) && ($stdSignum * $stdHours<=12)} { |
| | |
| | dict set z startWeekOfMonth 5 |
| | if {$stdHours>2} { |
| | dict set z startHours 2 |
| | } else { |
| | dict set z startHours [expr {$stdHours+1}] |
| | } |
| | } else { |
| | |
| | dict set z startWeekOfMonth 2 |
| | dict set z startHours 2 |
| | } |
| | dict set z startMonth 3 |
| | dict set z startDayOfWeek 0 |
| | dict set z startMinutes 0 |
| | dict set z startSeconds 0 |
| | } |
| | if { |
| | [dict get $z endDayOfYear] eq {} |
| | && [dict get $z endMonth] eq {} |
| | } then { |
| | if {($stdSignum * $stdHours>=0) && ($stdSignum * $stdHours<=12)} { |
| | |
| | dict set z endMonth 10 |
| | dict set z endWeekOfMonth 5 |
| | if {$stdHours>2} { |
| | dict set z endHours 3 |
| | } else { |
| | dict set z endHours [expr {$stdHours+2}] |
| | } |
| | } else { |
| | |
| | dict set z endMonth 11 |
| | dict set z endWeekOfMonth 1 |
| | dict set z endHours 2 |
| | } |
| | dict set z endDayOfWeek 0 |
| | dict set z endMinutes 0 |
| | dict set z endSeconds 0 |
| | } |
| |
|
| | |
| |
|
| | for { set y 1916 } { $y < 2100 } { incr y } { |
| | set startTime [DeterminePosixDSTTime $z start $y] |
| | incr startTime [expr { - wide($stdOffset) }] |
| | set endTime [DeterminePosixDSTTime $z end $y] |
| | incr endTime [expr { - wide($dstOffset) }] |
| | if { $startTime < $endTime } { |
| | lappend data \ |
| | [list $startTime $dstOffset 1 $dstName] \ |
| | [list $endTime $stdOffset 0 $stdName] |
| | } else { |
| | lappend data \ |
| | [list $endTime $stdOffset 0 $stdName] \ |
| | [list $startTime $dstOffset 1 $dstName] |
| | } |
| | } |
| |
|
| | return $data |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::DeterminePosixDSTTime { z bound y } { |
| |
|
| | variable FEB_28 |
| |
|
| | |
| |
|
| | set date [dict create era CE year $y] |
| | set doy [dict get $z ${bound}DayOfYear] |
| | if { $doy ne {} } { |
| |
|
| | |
| |
|
| | if { [dict get $z ${bound}J] ne {} |
| | && [IsGregorianLeapYear $y] |
| | && ( $doy > $FEB_28 ) } { |
| | incr doy |
| | } |
| | dict set date dayOfYear $doy |
| | set date [GetJulianDayFromEraYearDay $date[set date {}] 2361222] |
| | } else { |
| | |
| |
|
| | dict set date month [dict get $z ${bound}Month] |
| | dict set date dayOfWeek [dict get $z ${bound}DayOfWeek] |
| | set dowim [dict get $z ${bound}WeekOfMonth] |
| | if { $dowim >= 5 } { |
| | set dowim -1 |
| | } |
| | dict set date dayOfWeekInMonth $dowim |
| | set date [GetJulianDayFromEraYearMonthWeekDay $date[set date {}] 2361222] |
| |
|
| | } |
| |
|
| | set jd [dict get $date julianDay] |
| | set seconds [expr { |
| | wide($jd) * wide(86400) - wide(210866803200) |
| | }] |
| |
|
| | set h [dict get $z ${bound}Hours] |
| | if { $h eq {} } { |
| | set h 2 |
| | } else { |
| | set h [lindex [::scan $h %d] 0] |
| | } |
| | set m [dict get $z ${bound}Minutes] |
| | if { $m eq {} } { |
| | set m 0 |
| | } else { |
| | set m [lindex [::scan $m %d] 0] |
| | } |
| | set s [dict get $z ${bound}Seconds] |
| | if { $s eq {} } { |
| | set s 0 |
| | } else { |
| | set s [lindex [::scan $s %d] 0] |
| | } |
| | set tod [expr { ( $h * 60 + $m ) * 60 + $s }] |
| | return [expr { $seconds + $tod }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::GetLocaleEra { date etable } { |
| | set index [BSearch $etable [dict get $date localSeconds]] |
| | if { $index < 0} { |
| | dict set date localeEra \ |
| | [::format %02d [expr { [dict get $date year] / 100 }]] |
| | dict set date localeYear [expr { |
| | [dict get $date year] % 100 |
| | }] |
| | } else { |
| | dict set date localeEra [lindex $etable $index 1] |
| | dict set date localeYear [expr { |
| | [dict get $date year] - [lindex $etable $index 2] |
| | }] |
| | } |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::GetJulianDayFromEraYearDay {date changeover} { |
| | |
| |
|
| | switch -exact -- [dict get $date era] { |
| | BCE { |
| | set year [expr { 1 - [dict get $date year] }] |
| | } |
| | CE { |
| | set year [dict get $date year] |
| | } |
| | } |
| | set ym1 [expr { $year - 1 }] |
| |
|
| | |
| |
|
| | dict set date gregorian 1 |
| | set jd [expr { |
| | 1721425 |
| | + [dict get $date dayOfYear] |
| | + ( 365 * $ym1 ) |
| | + ( $ym1 / 4 ) |
| | - ( $ym1 / 100 ) |
| | + ( $ym1 / 400 ) |
| | }] |
| |
|
| | |
| |
|
| | if { $jd < $changeover } { |
| | dict set date gregorian 0 |
| | set jd [expr { |
| | 1721423 |
| | + [dict get $date dayOfYear] |
| | + ( 365 * $ym1 ) |
| | + ( $ym1 / 4 ) |
| | }] |
| | } |
| |
|
| | dict set date julianDay $jd |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::GetJulianDayFromEraYearMonthWeekDay {date changeover} { |
| | |
| | |
| | |
| |
|
| | set date2 $date |
| | set week [dict get $date dayOfWeekInMonth] |
| | if { $week >= 0 } { |
| | dict set date2 dayOfMonth 0 |
| | } else { |
| | dict incr date2 month |
| | dict set date2 dayOfMonth 7 |
| | } |
| | set date2 [GetJulianDayFromEraYearMonthDay $date2[set date2 {}] \ |
| | $changeover] |
| | set wd0 [WeekdayOnOrBefore [dict get $date dayOfWeek] \ |
| | [dict get $date2 julianDay]] |
| | dict set date julianDay [expr { $wd0 + 7 * $week }] |
| | return $date |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::IsGregorianLeapYear { date } { |
| | switch -exact -- [dict get $date era] { |
| | BCE { |
| | set year [expr { 1 - [dict get $date year]}] |
| | } |
| | CE { |
| | set year [dict get $date year] |
| | } |
| | } |
| | if { $year % 4 != 0 } { |
| | return 0 |
| | } elseif { ![dict get $date gregorian] } { |
| | return 1 |
| | } elseif { $year % 400 == 0 } { |
| | return 1 |
| | } elseif { $year % 100 == 0 } { |
| | return 0 |
| | } else { |
| | return 1 |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::WeekdayOnOrBefore { weekday j } { |
| | set k [expr { ( $weekday + 6 ) % 7 }] |
| | return [expr { $j - ( $j - $k ) % 7 }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::BSearch { list key } { |
| | if {[llength $list] == 0} { |
| | return -1 |
| | } |
| | if { $key < [lindex $list 0 0] } { |
| | return -1 |
| | } |
| |
|
| | set l 0 |
| | set u [expr { [llength $list] - 1 }] |
| |
|
| | while { $l < $u } { |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | set m [expr { ( $l + $u + 1 ) / 2 }] |
| | if { $key >= [lindex $list $m 0] } { |
| | set l $m |
| | } else { |
| | set u [expr { $m - 1 }] |
| | } |
| | } |
| |
|
| | return $l |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::add { clockval args } { |
| | if { [llength $args] % 2 != 0 } { |
| | set cmdName "clock add" |
| | return -code error \ |
| | -errorcode [list CLOCK wrongNumArgs] \ |
| | "wrong \# args: should be\ |
| | \"$cmdName clockval ?number units?...\ |
| | ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\"" |
| | } |
| | if { [catch { expr {wide($clockval)} } result] } { |
| | return -code error $result |
| | } |
| |
|
| | set offsets {} |
| | set gmt 0 |
| | set locale c |
| | set timezone [GetSystemTimeZone] |
| |
|
| | foreach { a b } $args { |
| | if { [string is integer -strict $a] } { |
| | lappend offsets $a $b |
| | } else { |
| | switch -exact -- $a { |
| | -g - -gm - -gmt { |
| | set saw(-gmt) {} |
| | set gmt $b |
| | } |
| | -l - -lo - -loc - -loca - -local - -locale { |
| | set locale [string tolower $b] |
| | } |
| | -t - -ti - -tim - -time - -timez - -timezo - -timezon - |
| | -timezone { |
| | set saw(-timezone) {} |
| | set timezone $b |
| | } |
| | default { |
| | throw [list CLOCK badOption $a] \ |
| | "bad option \"$a\",\ |
| | must be -gmt, -locale or -timezone" |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| |
|
| | if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } { |
| | return -code error \ |
| | -errorcode [list CLOCK gmtWithTimezone] \ |
| | "cannot use -gmt and -timezone in same call" |
| | } |
| | if { [catch { expr { wide($clockval) } } result] } { |
| | return -code error "expected integer but got \"$clockval\"" |
| | } |
| | if { ![string is boolean -strict $gmt] } { |
| | return -code error "expected boolean value but got \"$gmt\"" |
| | } elseif { $gmt } { |
| | set timezone :GMT |
| | } |
| |
|
| | EnterLocale $locale |
| |
|
| | set changeover [mc GREGORIAN_CHANGE_DATE] |
| |
|
| | if {[catch {SetupTimeZone $timezone} retval opts]} { |
| | dict unset opts -errorinfo |
| | return -options $opts $retval |
| | } |
| |
|
| | try { |
| | foreach { quantity unit } $offsets { |
| | switch -exact -- $unit { |
| | years - year { |
| | set clockval [AddMonths [expr { 12 * $quantity }] \ |
| | $clockval $timezone $changeover] |
| | } |
| | months - month { |
| | set clockval [AddMonths $quantity $clockval $timezone \ |
| | $changeover] |
| | } |
| |
|
| | weeks - week { |
| | set clockval [AddDays [expr { 7 * $quantity }] \ |
| | $clockval $timezone $changeover] |
| | } |
| | days - day { |
| | set clockval [AddDays $quantity $clockval $timezone \ |
| | $changeover] |
| | } |
| |
|
| | hours - hour { |
| | set clockval [expr { 3600 * $quantity + $clockval }] |
| | } |
| | minutes - minute { |
| | set clockval [expr { 60 * $quantity + $clockval }] |
| | } |
| | seconds - second { |
| | set clockval [expr { $quantity + $clockval }] |
| | } |
| |
|
| | default { |
| | throw [list CLOCK badUnit $unit] \ |
| | "unknown unit \"$unit\", must be \ |
| | years, months, weeks, days, hours, minutes or seconds" |
| | } |
| | } |
| | } |
| | return $clockval |
| | } trap CLOCK {result opts} { |
| | |
| | dict unset opts -errorinfo |
| | return -options $opts $result |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AddMonths { months clockval timezone changeover } { |
| | variable DaysInRomanMonthInCommonYear |
| | variable DaysInRomanMonthInLeapYear |
| | variable TZData |
| |
|
| | |
| |
|
| | set date [GetDateFields $clockval $TZData($timezone) $changeover] |
| | dict set date secondOfDay [expr { |
| | [dict get $date localSeconds] % 86400 |
| | }] |
| | dict set date tzName $timezone |
| |
|
| | |
| |
|
| | set m [dict get $date month] |
| | incr m $months |
| | incr m -1 |
| | set delta [expr { $m / 12 }] |
| | set mm [expr { $m % 12 }] |
| | dict set date month [expr { $mm + 1 }] |
| | dict incr date year $delta |
| |
|
| | |
| |
|
| | if { [IsGregorianLeapYear $date] } { |
| | set hath [lindex $DaysInRomanMonthInLeapYear $mm] |
| | } else { |
| | set hath [lindex $DaysInRomanMonthInCommonYear $mm] |
| | } |
| | if { [dict get $date dayOfMonth] > $hath } { |
| | dict set date dayOfMonth $hath |
| | } |
| |
|
| | |
| |
|
| | set date [GetJulianDayFromEraYearMonthDay \ |
| | $date[set date {}]\ |
| | $changeover] |
| | dict set date localSeconds [expr { |
| | -210866803200 |
| | + ( 86400 * wide([dict get $date julianDay]) ) |
| | + [dict get $date secondOfDay] |
| | }] |
| | set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \ |
| | $changeover] |
| |
|
| | return [dict get $date seconds] |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::AddDays { days clockval timezone changeover } { |
| | variable TZData |
| |
|
| | |
| |
|
| | set date [GetDateFields $clockval $TZData($timezone) $changeover] |
| | dict set date secondOfDay [expr { |
| | [dict get $date localSeconds] % 86400 |
| | }] |
| | dict set date tzName $timezone |
| |
|
| | |
| |
|
| | dict incr date julianDay $days |
| |
|
| | |
| |
|
| | dict set date localSeconds [expr { |
| | -210866803200 |
| | + ( 86400 * wide([dict get $date julianDay]) ) |
| | + [dict get $date secondOfDay] |
| | }] |
| | set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \ |
| | $changeover] |
| |
|
| | return [dict get $date seconds] |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ChangeCurrentLocale {args} { |
| | variable FormatProc |
| | variable LocaleNumeralCache |
| | variable CachedSystemTimeZone |
| | variable TimeZoneBad |
| |
|
| | foreach p [info procs [namespace current]::scanproc'*'current] { |
| | rename $p {} |
| | } |
| | foreach p [info procs [namespace current]::formatproc'*'current] { |
| | rename $p {} |
| | } |
| |
|
| | catch {array unset FormatProc *'current} |
| | set LocaleNumeralCache {} |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc ::tcl::clock::ClearCaches {} { |
| | variable FormatProc |
| | variable LocaleNumeralCache |
| | variable CachedSystemTimeZone |
| | variable TimeZoneBad |
| |
|
| | foreach p [info procs [namespace current]::scanproc'*] { |
| | rename $p {} |
| | } |
| | foreach p [info procs [namespace current]::formatproc'*] { |
| | rename $p {} |
| | } |
| |
|
| | catch {unset FormatProc} |
| | set LocaleNumeralCache {} |
| | catch {unset CachedSystemTimeZone} |
| | set TimeZoneBad {} |
| | InitTZData |
| | } |
| |
|