Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108672990
D47977.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D47977.diff
View Options
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -382,6 +382,8 @@
..
stdlib
..
+ stdtime
+ ..
string
..
sys
diff --git a/lib/libc/stdtime/strptime.3 b/lib/libc/stdtime/strptime.3
--- a/lib/libc/stdtime/strptime.3
+++ b/lib/libc/stdtime/strptime.3
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" "
-.Dd October 2, 2014
+.Dd December 9, 2024
.Dt STRPTIME 3
.Os
.Sh NAME
@@ -135,6 +135,11 @@
.Pp
This man page was written by
.An J\(:org Wunsch .
+.Sh CAVEATS
+The
+.Fn strptime
+function assumes the Gregorian calendar and will produce incorrect
+results for dates prior to its introduction.
.Sh BUGS
Both the
.Fa %e
diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c
--- a/lib/libc/stdtime/strptime.c
+++ b/lib/libc/stdtime/strptime.c
@@ -62,17 +62,16 @@
#define FLAG_WDAY (1 << 5)
/*
- * Calculate the week day of the first day of a year. Valid for
- * the Gregorian calendar, which began Sept 14, 1752 in the UK
- * and its colonies. Ref:
- * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week
+ * Gauss's algorithm for the day of the week of the first day of any year
+ * in the Gregorian calendar.
*/
-
static int
first_wday_of(int year)
{
- return (((2 * (3 - (year / 100) % 4)) + (year % 100) +
- ((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7);
+ return ((1 +
+ 5 * ((year - 1) % 4) +
+ 4 * ((year - 1) % 100) +
+ 6 * ((year - 1) % 400)) % 7);
}
static char *
@@ -674,13 +673,8 @@
flags |= FLAG_MDAY;
}
if (!(flags & FLAG_WDAY)) {
- i = 0;
- wday_offset = first_wday_of(tm->tm_year);
- while (i++ <= tm->tm_yday) {
- if (wday_offset++ >= 6)
- wday_offset = 0;
- }
- tm->tm_wday = wday_offset;
+ wday_offset = first_wday_of(tm->tm_year + TM_YEAR_BASE);
+ tm->tm_wday = (wday_offset + tm->tm_yday) % 7;
flags |= FLAG_WDAY;
}
}
diff --git a/lib/libc/tests/Makefile b/lib/libc/tests/Makefile
--- a/lib/libc/tests/Makefile
+++ b/lib/libc/tests/Makefile
@@ -16,6 +16,7 @@
TESTS_SUBDIRS+= setjmp
TESTS_SUBDIRS+= stdio
TESTS_SUBDIRS+= stdlib
+TESTS_SUBDIRS+= stdtime
TESTS_SUBDIRS+= string
TESTS_SUBDIRS+= sys
TESTS_SUBDIRS+= termios
diff --git a/lib/libc/tests/stdtime/Makefile b/lib/libc/tests/stdtime/Makefile
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/stdtime/Makefile
@@ -0,0 +1,7 @@
+.include <bsd.own.mk>
+
+ATF_TESTS_C+= strptime_test
+
+TESTSDIR:= ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/}
+
+.include <bsd.test.mk>
diff --git a/lib/libc/tests/stdtime/strptime_test.c b/lib/libc/tests/stdtime/strptime_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/stdtime/strptime_test.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2024 Dag-Erling Smørgrav
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <time.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(dayofweek);
+ATF_TC_BODY(dayofweek, tc)
+{
+ static const struct {
+ const char *str;
+ int wday;
+ } cases[] = {
+ { "1582-12-20", 1 },
+ { "1700-03-01", 1 },
+ { "1752-09-14", 4 },
+ { "1800-12-31", 3 },
+ { "1801-01-01", 4 },
+ { "1900-12-31", 1 },
+ { "1901-01-01", 2 },
+ { "2000-12-31", 0 },
+ { "2001-01-01", 1 },
+ { "2100-12-31", 5 },
+ { "2101-01-01", 6 },
+ { "2200-12-31", 3 },
+ { "2201-01-01", 4 },
+ { },
+ };
+ struct tm tm;
+
+ for (unsigned int i = 0; cases[i].str != NULL; i++) {
+ if (strptime(cases[i].str, "%Y-%m-%d", &tm) == NULL) {
+ atf_tc_fail_nonfatal("failed to parse %s",
+ cases[i].str);
+ } else if (tm.tm_wday != cases[i].wday) {
+ atf_tc_fail_nonfatal("expected %d for %s, got %d",
+ cases[i].wday, cases[i].str, tm.tm_wday);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, dayofweek);
+ return (atf_no_error());
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 5:30 AM (10 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16252262
Default Alt Text
D47977.diff (3 KB)
Attached To
Mode
D47977: strptime: Fix day-of-week calculation.
Attached
Detach File
Event Timeline
Log In to Comment