diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-03-10 21:23:37 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-03-10 21:23:37 (GMT) |
commit | 5151f841c625d30f9c987410520d0e68e73f1ed6 (patch) | |
tree | 06501cb1c8ab127b1eb4d984e7abcde654bb5ab2 /generic/tclClock.c | |
parent | 66cc680d51f41f796bc53ea10e34c84e1a7a0564 (diff) | |
parent | 212886f5186a18c0a0b9c007ff82f9627f88de28 (diff) | |
download | tcl-5151f841c625d30f9c987410520d0e68e73f1ed6.zip tcl-5151f841c625d30f9c987410520d0e68e73f1ed6.tar.gz tcl-5151f841c625d30f9c987410520d0e68e73f1ed6.tar.bz2 |
Merge 8.7
Diffstat (limited to 'generic/tclClock.c')
-rw-r--r-- | generic/tclClock.c | 89 |
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) { |