localtime(3) always returns UTC

"Alvar Penning" <[email protected]> Fri, 15 May 2026 15:04:16 +0200
Newsgroups gmane.os.openbsd.bugs
Message-ID <[email protected]>
>Synopsis:	localtime(3) always returns UTC
>Category:	library
>Environment:
	System      : OpenBSD 7.9
	Details     : OpenBSD 7.9-current (GENERIC.MP) #476: Fri May 15 03:34:47 UTC 2026
			 [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

	Architecture: OpenBSD.amd64
	Machine     : amd64
>Description:
	Since today's sysupgrade -s, all my clocks are in UTC. After taking a
	second look, this seems to be localtime(3)'s fault.

	Please consider the following short C program as an example.

		#include <err.h>
		#include <stdio.h>
		#include <stdlib.h>
		#include <time.h>

		int
		main(int argc, char *argv[])
		{
			struct tm *tp;
			time_t tval;
			char buf[1024];

			if (time(&tval) == 1)
				err(1, "time");

			tp = localtime(&tval);
			if (!tp)
				err(1, "localtime");

			strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", tp);
			printf("%s\n", buf);

			return EXIT_SUCCESS;
		}

	On an OpenBSD 7.8, OpenBSD 7.8 GENERIC.MP#7 amd64, the output matched
	/etc/localtime and honored TZ.

		$ ./a.out
		Fri May 15 14:02:06 CEST 2026
		$ TZ=UTC ./a.out
		Fri May 15 12:02:11 UTC 2026
		$ TZ=Europe/London ./a.out
		Fri May 15 13:02:19 BST 2026


	However, on my -current system, it's UTC all the way.

		$ ./a.out
		Fri May 15 12:04:37 UTC 2026
		$ TZ=UTC ./a.out
		Fri May 15 12:04:43 UTC 2026
		$ TZ=Europe/London ./a.out
		Fri May 15 12:04:48 UTC 2026

	There was a really recent change from deraadt to lib/libc/time/localtime.c,
	which goes in this direction but I am uncertain how much it is related.

	  - https://marc.info/?l=openbsd-cvs&m=177881228902319&w=2
	  - https://cvsweb.openbsd.org/diff/src/lib/libc/time/localtime.c,v?rev=1.78&prev=1.77

>How-To-Repeat:
	Upgrade a current OpenBSD to "OpenBSD 7.9 GENERIC.MP#476 amd64" and either
	try the C code above or just use date(1).