summaryrefslogtreecommitdiffstats
path: root/generic/tclClock.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2024-03-10 21:23:37 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2024-03-10 21:23:37 (GMT)
commit5151f841c625d30f9c987410520d0e68e73f1ed6 (patch)
tree06501cb1c8ab127b1eb4d984e7abcde654bb5ab2 /generic/tclClock.c
parent66cc680d51f41f796bc53ea10e34c84e1a7a0564 (diff)
parent212886f5186a18c0a0b9c007ff82f9627f88de28 (diff)
downloadtcl-5151f841c625d30f9c987410520d0e68e73f1ed6.zip
tcl-5151f841c625d30f9c987410520d0e68e73f1ed6.tar.gz
tcl-5151f841c625d30f9c987410520d0e68e73f1ed6.tar.bz2
Merge 8.7
Diffstat (limited to 'generic/tclClock.c')
-rw-r--r--generic/tclClock.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 4951f04..4bd9ad2 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -43,10 +43,6 @@
* Table of the days in each month, leap and common years
*/
-static const int hath[2][12] = {
- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-};
static const int daysInPriorMonths[2][13] = {
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
@@ -160,7 +156,7 @@ static void GetMonthDay(TclDateFields *);
static void GetJulianDayFromEraYearWeekDay(TclDateFields *, int);
static void GetJulianDayFromEraYearMonthDay(TclDateFields *, int);
static int IsGregorianLeapYear(TclDateFields *);
-static int WeekdayOnOrBefore(int, int);
+static Tcl_WideInt WeekdayOnOrBefore(int, Tcl_WideInt);
static Tcl_ObjCmdProc ClockClicksObjCmd;
static Tcl_ObjCmdProc ClockConvertlocaltoutcObjCmd;
static Tcl_ObjCmdProc ClockGetdatefieldsObjCmd;
@@ -189,16 +185,16 @@ struct ClockCommand {
};
static const struct ClockCommand clockCommands[] = {
- { "getenv", ClockGetenvObjCmd },
- { "Oldscan", TclClockOldscanObjCmd },
- { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd },
- { "GetDateFields", ClockGetdatefieldsObjCmd },
- { "GetJulianDayFromEraYearMonthDay",
- ClockGetjuliandayfromerayearmonthdayObjCmd },
- { "GetJulianDayFromEraYearWeekDay",
- ClockGetjuliandayfromerayearweekdayObjCmd },
- { "ParseFormatArgs", ClockParseformatargsObjCmd },
- { NULL, NULL }
+ {"getenv", ClockGetenvObjCmd},
+ {"Oldscan", TclClockOldscanObjCmd},
+ {"ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd},
+ {"GetDateFields", ClockGetdatefieldsObjCmd},
+ {"GetJulianDayFromEraYearMonthDay",
+ ClockGetjuliandayfromerayearmonthdayObjCmd},
+ {"GetJulianDayFromEraYearWeekDay",
+ ClockGetjuliandayfromerayearweekdayObjCmd},
+ {"ParseFormatArgs", ClockParseformatargsObjCmd},
+ {NULL, NULL}
};
/*
@@ -318,7 +314,6 @@ ClockConvertlocaltoutcObjCmd(
Tcl_Obj *const *objv) /* Parameter vector */
{
ClockClientData *data = (ClockClientData *)clientData;
- Tcl_Obj *const *lit = data->literals;
Tcl_Obj *secondsObj;
Tcl_Obj *dict;
int changeover;
@@ -335,7 +330,7 @@ ClockConvertlocaltoutcObjCmd(
return TCL_ERROR;
}
dict = objv[1];
- if (Tcl_DictObjGet(interp, dict, lit[LIT_LOCALSECONDS],
+ if (Tcl_DictObjGet(interp, dict, data->literals[LIT_LOCALSECONDS],
&secondsObj)!= TCL_OK) {
return TCL_ERROR;
}
@@ -361,7 +356,7 @@ ClockConvertlocaltoutcObjCmd(
created = 1;
Tcl_IncrRefCount(dict);
}
- status = Tcl_DictObjPut(interp, dict, lit[LIT_SECONDS],
+ status = Tcl_DictObjPut(interp, dict, data->literals[LIT_SECONDS],
Tcl_NewWideIntObj(fields.seconds));
if (status == TCL_OK) {
Tcl_SetObjResult(interp, dict);
@@ -1045,7 +1040,7 @@ ConvertUTCToLocalUsingC(
if ((Tcl_WideInt) tock != fields->seconds) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"number too large to represent as a Posix time", -1));
- Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", (void *)NULL);
+ Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", (char *)NULL);
return TCL_ERROR;
}
TzsetIfNecessary();
@@ -1054,7 +1049,7 @@ ConvertUTCToLocalUsingC(
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"localtime failed (clock value may be too "
"large/small to represent)", -1));
- Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", (void *)NULL);
+ Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", (char *)NULL);
return TCL_ERROR;
}
@@ -1121,8 +1116,7 @@ LookupLastTransition(
Tcl_Size rowc, /* Number of rows of tzdata */
Tcl_Obj *const *rowv) /* Rows in tzdata */
{
- Tcl_Size l;
- Tcl_Size u;
+ Tcl_Size l, u;
Tcl_Obj *compObj;
Tcl_WideInt compVal;
@@ -1151,7 +1145,7 @@ LookupLastTransition(
l = 0;
u = rowc-1;
while (l < u) {
- int m = (l + u + 1) / 2;
+ Tcl_Size m = (l + u + 1) / 2;
if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
@@ -1256,10 +1250,10 @@ GetGregorianEraYearDay(
TclDateFields *fields, /* Date fields containing 'julianDay' */
int changeover) /* Gregorian transition date */
{
- int jday = fields->julianDay;
- int day;
- int year;
- int n;
+ Tcl_WideInt jday = fields->julianDay;
+ Tcl_WideInt day;
+ Tcl_WideInt year;
+ Tcl_WideInt n;
if (jday >= changeover) {
/*
@@ -1373,11 +1367,27 @@ GetMonthDay(
{
int day = fields->dayOfYear;
int month;
- const int *h = hath[IsGregorianLeapYear(fields)];
+ const int *dipm = daysInPriorMonths[IsGregorianLeapYear(fields)];
- for (month = 0; month < 12 && day > h[month]; ++month) {
- day -= h[month];
+ /*
+ * Estimate month by calculating `dayOfYear / (365/12)`
+ */
+ month = (day*12) / dipm[12];
+ /* then do forwards backwards correction */
+ while (1) {
+ if (day > dipm[month]) {
+ if (month >= 11 || day <= dipm[month+1]) {
+ break;
+ }
+ month++;
+ } else {
+ if (month == 0) {
+ break;
+ }
+ month--;
+ }
}
+ day -= dipm[month];
fields->month = month+1;
fields->dayOfMonth = day;
}
@@ -1405,7 +1415,7 @@ GetJulianDayFromEraYearWeekDay(
int changeover) /* Julian Day Number of the Gregorian
* transition */
{
- int firstMonday; /* Julian day number of week 1, day 1 in the
+ Tcl_WideInt firstMonday; /* Julian day number of week 1, day 1 in the
* given year */
TclDateFields firstWeek;
@@ -1455,7 +1465,8 @@ GetJulianDayFromEraYearMonthDay(
TclDateFields *fields, /* Date to convert */
int changeover) /* Gregorian transition date as a Julian Day */
{
- int year, ym1, month, mm1, q, r, ym1o4, ym1o100, ym1o400;
+ Tcl_WideInt year, ym1, ym1o4, ym1o100, ym1o400;
+ int month, mm1, q, r;
if (fields->isBce) {
year = 1 - fields->year;
@@ -1561,7 +1572,7 @@ static int
IsGregorianLeapYear(
TclDateFields *fields) /* Date to test */
{
- int year = fields->year;
+ Tcl_WideInt year = fields->year;
if (fields->isBce) {
year = 1 - year;
@@ -1593,10 +1604,10 @@ IsGregorianLeapYear(
*----------------------------------------------------------------------
*/
-static int
+static Tcl_WideInt
WeekdayOnOrBefore(
int dayOfWeek, /* Day of week; Sunday == 0 or 7 */
- int julianDay) /* Reference date */
+ Tcl_WideInt julianDay) /* Reference date */
{
int k = (dayOfWeek + 6) % 7;
if (k < 0) {
@@ -1763,7 +1774,7 @@ ClockClicksObjCmd(
switch (index) {
case CLICKS_MILLIS:
Tcl_GetTime(&now);
- clicks = (Tcl_WideInt)(unsigned long long)now.sec * 1000 + now.usec / 1000;
+ clicks = (Tcl_WideInt)now.sec * 1000 + now.usec / 1000;
break;
case CLICKS_NATIVE:
#ifdef TCL_WIDE_CLICKS
@@ -1905,7 +1916,7 @@ ClockParseformatargsObjCmd(
Tcl_WrongNumArgs(interp, 0, objv,
"clock format clockval ?-format string? "
"?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?");
- Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", (void *)NULL);
+ Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", (char *)NULL);
return TCL_ERROR;
}
@@ -1920,7 +1931,7 @@ ClockParseformatargsObjCmd(
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
&optionIndex) != TCL_OK) {
Tcl_SetErrorCode(interp, "CLOCK", "badOption",
- TclGetString(objv[i]), (void *)NULL);
+ TclGetString(objv[i]), (char *)NULL);
return TCL_ERROR;
}
switch (optionIndex) {
@@ -1952,7 +1963,7 @@ ClockParseformatargsObjCmd(
if ((saw & (1 << CLOCK_FORMAT_GMT))
&& (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
- Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", (void *)NULL);
+ Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", (char *)NULL);
return TCL_ERROR;
}
if (gmtFlag) {