shithub: riscv

Download patch

ref: 88412aa050adddde5cacf3a45e914bad9a5d3e22
parent: 37f710de39e9cf06240907053f3ab931f81d8e9a
author: rodri <rgl@antares-labs.eu>
date: Sun Aug 13 16:17:09 EDT 2023

tmdate: add ordinal day of month format specifier

--- a/sys/man/2/tmdate
+++ b/sys/man/2/tmdate
@@ -122,6 +122,9 @@
 .B a, A
 Lower and uppercase 'am' and 'pm' specifiers, respectively.
 .TP
+.B o
+Ordinal day of month suffix specifier.
+.TP
 .B [...]
 Quoted text, copied directly to the output.
 .TP
--- a/sys/src/libc/port/date.c
+++ b/sys/src/libc/port/date.c
@@ -454,6 +454,15 @@
 			default: goto badfmt;
 			}
 			break;
+		case 'o':
+			if(w != 1) goto badfmt;
+			switch(tm->mday){
+			case 1: case 21: case 31: n += fmtprint(f, "st");		break;
+			case 2: case 22: n += fmtprint(f, "nd");			break;
+			case 3: case 23: n += fmtprint(f, "rd");			break;
+			default: n += fmtprint(f, "th");
+			}
+			break;
 		case 'W':
 			switch(w){
 			case 1:	n += fmtprint(f, "%*d", pad, tm->wday + 1);		break;
@@ -696,6 +705,15 @@
 			case 2: tm->mday = getnum(&s, 2, &ok);		break;
 			default: goto badfmt;
 			}
+			break;
+		case 'o':
+			if(strncmp(s, "th", 2) == 0
+			|| strncmp(s, "rd", 2) == 0
+			|| strncmp(s, "nd", 2) == 0
+			|| strncmp(s, "st", 2) == 0)
+				s += 2;
+			else
+				goto badfmt;
 			break;
 		case 'W':
 			switch(w){
--- a/sys/src/libc/test/date.c
+++ b/sys/src/libc/test/date.c
@@ -278,6 +278,25 @@
 			print("bad am/pm parsed: %s != %s (%lld != %lld)\n", buf, buf1, tmnorm(&tm), tmnorm(&tt));
 	}
 
+	/* ordinal day suffix parsing and formatting */
+	for(i = 1; i < 32; i++){
+		snprint(buf, sizeof(buf), "2023 08 %d", i);
+		snprint(buf1, sizeof(buf1), "2023 08 %02d%s", i,
+			i == 1 || i == 21 || i == 31? "st": i == 2 || i == 22? "nd": i == 3 || i == 23? "rd": "th");
+		if(tmparse(&tm, "YYYY MM DD", buf, nil, nil) == nil)
+			fail("parse: %r\n");
+		if(tmparse(&tt, "YYYY MM DDo", buf1, nil, nil) == nil)
+			fail("parse: %r\n");
+		if(tmnorm(&tm) != tmnorm(&tt))
+			print("bad ordinal day suffix parsed: %s != %s (%lld != %lld)\n", buf, buf1, tmnorm(&tm), tmnorm(&tt));
+		if(tmparse(&tm, "YYYY MM DDo", buf, nil, nil) != nil)
+			print("ordinal day suffix parsed when absent\n");
+		if(snprint(buf, sizeof(buf), "%τ", tmfmt(&tm, "YYYY MM DDo")) == -1)
+			fail("format: %r");
+		if(strcmp(buf, buf1) != 0)
+			print("bad ordinal day suffix formatted: %s != %s\n", buf, buf1);
+	}
+
 	/* Time zone boundaries: entering DST */
 	if(tmtime(&tm, 1520733600, us_eastern) == nil)
 		fail("tmtime: tz boundary");