summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-01-10 22:02:10 (GMT)
committersebres <sebres@users.sourceforge.net>2017-01-10 22:02:10 (GMT)
commitf70ebac8b8c9c01999150364b4155b0d50911cbc (patch)
tree7ee977c045032f7763000f522709ce2999cb2dad
parent980f0e3d6b56fbddec0b97988c695f912caa5082 (diff)
downloadtcl-f70ebac8b8c9c01999150364b4155b0d50911cbc.zip
tcl-f70ebac8b8c9c01999150364b4155b0d50911cbc.tar.gz
tcl-f70ebac8b8c9c01999150364b4155b0d50911cbc.tar.bz2
[temp-commit]: ClockFreeScan ready, test case passed (2 failure because of wrong :localtime zone by TZ-switch, to be fixed)
-rw-r--r--generic/tclClock.c26
-rwxr-xr-xlibrary/clock.tcl198
-rw-r--r--library/init.tcl2
-rw-r--r--tests/clock.test12
4 files changed, 37 insertions, 201 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 5710d6d..7256320 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -122,6 +122,7 @@ typedef struct ClockClientData {
Tcl_Obj *GMTSetupTZData;
Tcl_Obj *LastSetupTimeZone;
Tcl_Obj *LastSetupTZData;
+ Tcl_Obj *LastUsedSetupTimeZone;
} ClockClientData;
/*
@@ -324,6 +325,7 @@ TclClockInit(
data->GMTSetupTZData = NULL;
data->LastSetupTimeZone = NULL;
data->LastSetupTZData = NULL;
+ data->LastUsedSetupTimeZone = NULL;
/*
* Install the commands.
@@ -477,6 +479,7 @@ ClockConfigureObjCmd(
if (i+1 < objc) {
timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]);
if (optionIndex == CLOCK_SETUP_TZ) {
+ dataPtr->LastUsedSetupTimeZone = timezoneObj;
if (timezoneObj == litPtr[LIT_GMT]) {
optionIndex = CLOCK_SETUP_GMT;
} else if (timezoneObj == dataPtr->LastSystemTimeZone) {
@@ -510,14 +513,15 @@ ClockConfigureObjCmd(
if (i+1 < objc) {
Tcl_IncrRefCount(
dataPtr->LastSetupTimeZone = timezoneObj);
- } else if (dataPtr->LastSetupTimeZone) {
- Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone);
+ } else if (dataPtr->LastUsedSetupTimeZone) {
+ Tcl_SetObjResult(interp, dataPtr->LastUsedSetupTimeZone);
}
}
}
}
if (optionIndex == CLOCK_CLEAR_CACHE) {
dataPtr->LastTZEpoch = 0;
+ dataPtr->LastUsedSetupTimeZone = NULL;
}
}
@@ -605,6 +609,11 @@ ClockSetupTimeZone(
Tcl_Obj **literals = dataPtr->literals;
Tcl_Obj *callargs[2];
+ /* if cached (if already setup this one) */
+ if (timezoneObj == dataPtr->LastUsedSetupTimeZone) {
+ return timezoneObj;
+ }
+
/* differentiate GMT and system zones, because used often and already set */
timezoneObj = NormTimezoneObj(dataPtr, timezoneObj);
if ( timezoneObj == dataPtr->GMTSetupTimeZone
@@ -2546,6 +2555,15 @@ ClockScanObjCmd(
}
*/
+ if (1) {
+ /* TODO: Tcled Scan proc - */
+ Tcl_Obj *callargs[10];
+ memcpy(callargs, objv, objc * sizeof(*objv));
+ callargs[0] = Tcl_NewStringObj("::tcl::clock::__org_scan", -1);
+ return Tcl_EvalObjv(interp, objc, callargs, 0);
+ }
+ // Tcl_SetObjResult(interp, Tcl_NewWideIntObj(10000000));
+
return TCL_OK;
}
@@ -2635,10 +2653,10 @@ ClockFreeScan(
if (yy.dateHaveDate) {
if (yy.dateYear < 100) {
- yy.dateYear += ClockCurrentYearCentury(clientData, interp);
- if (yy.dateYear > ClockGetYearOfCenturySwitch(clientData, interp)) {
+ if (yy.dateYear >= ClockGetYearOfCenturySwitch(clientData, interp)) {
yy.dateYear -= 100;
}
+ yy.dateYear += ClockCurrentYearCentury(clientData, interp);
}
date.era = CE;
date.year = yy.dateYear;
diff --git a/library/clock.tcl b/library/clock.tcl
index 90b3c69..b4a7639 100755
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -289,7 +289,7 @@ proc ::tcl::clock::Initialize {} {
# Current year century and year of century switch
variable CurrentYearCentury 2000
- variable YearOfCenturySwitch 37
+ variable YearOfCenturySwitch 38
# Translation table to map Windows TZI onto cities, so that the Olson
# rules can apply. In some cases the mapping is ambiguous, so it's wise
@@ -1249,18 +1249,6 @@ proc ::tcl::clock::__org_scan { args } {
set timezone :GMT
}
- if { ![info exists saw(-format)] } {
- # Perhaps someday we'll localize the legacy code. Right now, it's not
- # localized.
- 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]
- }
-
# Change locale if a fresh locale has been given on the command line.
EnterLocale $locale
@@ -1279,184 +1267,6 @@ proc ::tcl::clock::__org_scan { args } {
#----------------------------------------------------------------------
#
-# FreeScan --
-#
-# Scans a time in free format
-#
-# Parameters:
-# string - String containing the time to scan
-# base - Base time, expressed in seconds from the Epoch
-# timezone - Default time zone in which the time will be expressed
-# locale - (Unused) Name of the locale where the time will be scanned.
-#
-# Results:
-# Returns the date and time extracted from the string in seconds from
-# the epoch
-#
-#----------------------------------------------------------------------
-
-proc ::tcl::clock::__org_FreeScan { string base timezone locale } {
-
- variable TZData
-
- # Get the data for time changes in the given zone
- if {$timezone eq {}} {
- set timezone [GetSystemTimeZone]
- }
- try {
- SetupTimeZone $timezone
- } on error {retval opts} {
- dict unset opts -errorinfo
- return -options $opts $retval
- }
-
- # Extract year, month and day from the base time for the parser to use as
- # defaults
-
- set date [GetDateFields $base $TZData($timezone) 2361222]
- dict set date secondOfDay [expr {
- [dict get $date localSeconds] % 86400
- }]
-
- # Parse the date. The parser will return a list comprising date, time,
- # time zone, relative month/day/seconds, relative weekday, ordinal month.
-
- 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 the caller supplied a date in the string, update the 'date' dict with
- # the value. If the caller didn't specify a time with the date, default to
- # midnight.
-
- if { [llength $parseDate] > 0 } {
- lassign $parseDate y m d
- if { $y < 100 } {
- variable YearOfCenturySwitch
- if { $y > $YearOfCenturySwitch } {
- 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 the caller supplied a time zone in the string, it comes back as a
- # two-element list; the first element is the number of minutes east of
- # Greenwich, and the second is a Daylight Saving Time indicator (1 == yes,
- # 0 == no, -1 == unknown). We make it into a time zone indicator of
- # +-hhmm.
-
- if { [llength $parseZone] > 0 } {
- lassign $parseZone minEast dstFlag
- set timezone [FormatNumericTimeZone \
- [expr { 60 * $minEast + 3600 * $dstFlag }]]
- SetupTimeZone $timezone
- }
- dict set date tzName $timezone
-
- # Assemble date, time, zone into seconds-from-epoch
-
- 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]
-
- # Do relative times
-
- if { [llength $parseRel] > 0 } {
- lassign $parseRel relMonth relDay relSecond
- set seconds [add $seconds \
- $relMonth months $relDay days $relSecond seconds \
- -timezone $timezone -locale $locale]
- }
-
- # Do relative weekday
-
- 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]
-
- }
-
- # Do relative month
-
- 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
-}
-
-
-#----------------------------------------------------------------------
-#
# ParseClockScanFormat --
#
# Parses a format string given to [clock scan -format]
@@ -2723,10 +2533,10 @@ proc ::tcl::clock::InterpretTwoDigitYear { date baseTime
variable CurrentYearCentury
variable YearOfCenturySwitch
set yr [dict get $date $twoDigitField]
- incr yr $CurrentYearCentury
- if { $yr <= $YearOfCenturySwitch } {
+ if { $yr >= $YearOfCenturySwitch } {
incr yr -100
}
+ incr yr $CurrentYearCentury
dict set date $fourDigitField $yr
return $date
}
@@ -3120,7 +2930,7 @@ proc ::tcl::clock::SetupTimeZone { timezone } {
LoadZoneinfoFile [string range $timezone 1 end]
}]
} then {
- dict set TimeZoneBad $timezone 1
+ dict set TimeZoneBad $timezone 1
return -code error \
-errorcode [list CLOCK badTimeZone $timezone] \
"time zone \"$timezone\" not found"
diff --git a/library/init.tcl b/library/init.tcl
index 5e452b0..06a9459 100644
--- a/library/init.tcl
+++ b/library/init.tcl
@@ -178,7 +178,7 @@ if {[interp issafe]} {
# Auto-loading stubs for 'clock.tcl'
- foreach cmd {add format SetupTimeZone} {
+ foreach cmd {add format SetupTimeZone GetSystemTimeZone __org_scan} {
proc ::tcl::clock::$cmd args {
variable TclLibDir
source -encoding utf-8 [file join $TclLibDir clock.tcl]
diff --git a/tests/clock.test b/tests/clock.test
index 6a0fecd..ecc6f5f 100644
--- a/tests/clock.test
+++ b/tests/clock.test
@@ -35662,7 +35662,7 @@ test clock-34.8 {clock scan tests} {
} {Oct 23,1992 15:00 GMT}
test clock-34.9 {clock scan tests} {
list [catch {clock scan "Jan 12" -bad arg} msg] $msg
-} {1 {bad option "-bad", must be -base, -format, -gmt, -locale or -timezone}}
+} {1 {bad option "-bad": must be -format, -gmt, -locale, -timezone, or -base}}
# The following two two tests test the two year date policy
test clock-34.10 {clock scan tests} {
set time [clock scan "1/1/71" -gmt true]
@@ -35672,7 +35672,15 @@ test clock-34.11 {clock scan tests} {
set time [clock scan "1/1/37" -gmt true]
clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,2037 00:00 GMT}
-
+test clock-34.11.1 {clock scan tests: same century switch} {
+ set times [clock scan "1/1/37" -gmt true]
+} [clock scan "1/1/37" -format "%m/%d/%y" -gmt true]
+test clock-34.11.2 {clock scan tests: same century switch} {
+ set times [clock scan "1/1/38" -gmt true]
+} [clock scan "1/1/38" -format "%m/%d/%y" -gmt true]
+test clock-34.11.3 {clock scan tests: same century switch} {
+ set times [clock scan "1/1/39" -gmt true]
+} [clock scan "1/1/39" -format "%m/%d/%y" -gmt true]
test clock-34.12 {clock scan, relative times} {
set time [clock scan "Oct 23, 1992 -1 day"]
clock format $time -format {%b %d, %Y}