Implement proper time zone support

Cosmopolitan now supports 104 time zones. They're embedded inside any
binary that links the localtime() function. Doing so adds about 100kb
to the binary size. This change also gets time zones working properly
on Windows for the first time. It's not needed to have /etc/localtime
exist on Windows, since we can get this information from WIN32. We're
also now updated to the latest version of Paul Eggert's TZ library.
This commit is contained in:
Justine Tunney 2024-05-04 23:05:36 -07:00
parent d5ebb1fa5b
commit b0df6c1fce
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
627 changed files with 3052 additions and 2077 deletions

View file

@ -47,12 +47,12 @@ TEST_LIBC_CALLS_DIRECTDEPS = \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
THIRD_PARTY_COMPILER_RT \
TOOL_DECODE_LIB \
THIRD_PARTY_XED
THIRD_PARTY_XED \
THIRD_PARTY_TZ
TEST_LIBC_CALLS_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x))))

View file

@ -21,7 +21,7 @@
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/clock.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
struct timespec ts;

View file

@ -29,7 +29,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
TEST(clock_gettime, nullResult_validatesClockParam) {
ASSERT_SYS(EINVAL, -1, clock_gettime(666, 0));

View file

@ -30,7 +30,7 @@
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
void OnAlrm(int sig) {
// do nothing

View file

@ -21,7 +21,7 @@
#include "libc/errno.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
TEST(getitimer, testBadParam_returnsEinval) {
struct itimerval it;

View file

@ -58,7 +58,7 @@
#include "libc/testlib/testlib.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/x.h"
void SetUpOnce(void) {

View file

@ -20,7 +20,7 @@
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/x.h"
TEST(readansi, test) {

View file

@ -40,8 +40,7 @@
#include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h"
#include "libc/thread/tls.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
__static_yoink("zipos");
__static_yoink("libc/testlib/hyperion.txt");
@ -70,7 +69,7 @@ TEST(reservefd, testGrowthOfFdsDataStructure) {
errno = 0;
}
for (i = 0; i < n; ++i) {
ASSERT_SYS(0, i + 3, open("/zip/usr/share/zoneinfo/UTC", O_RDONLY));
ASSERT_SYS(0, i + 3, open("/zip/usr/share/zoneinfo/GMT", O_RDONLY));
}
ASSERT_GT(g_fds.n, 16);
for (i = 0; i < n; ++i) {

View file

@ -35,7 +35,7 @@
#include "libc/sysv/consts/rlimit.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/xsigaction.h"
#include "libc/x/xspawn.h"

View file

@ -29,7 +29,7 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/utime.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
void SetUpOnce(void) {
testlib_enable_tmp_setup_teardown();

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/calls/struct/timeval.h"
#include "libc/fmt/wintime.internal.h"
#include "libc/nt/struct/filetime.h"

View file

@ -24,7 +24,7 @@
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* @fileoverview Lock Waiter Scalability Test

View file

@ -42,7 +42,7 @@
#include "libc/testlib/subprocess.h"
#include "libc/testlib/testlib.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
#define N 1024
#define M 20

View file

@ -6,7 +6,6 @@ int main(int argc, char *argv[]) {
s = strdup(argv[0]);
s[0] = 'Z';
f = fopen("/dev/null", "w");
/* fputs(gc(xiso8601ts(NULL)), f); */
fputs(gc(xasprintf("hello world %d %s\n", argc, s)), f);
fclose(f);
free(s);

View file

@ -28,7 +28,7 @@
#include "libc/sock/sock.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
bool gotsig;

View file

@ -35,7 +35,7 @@
#include "libc/sysv/consts/sol.h"
#include "libc/testlib/subprocess.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
void SetUpOnce(void) {
testlib_enable_tmp_setup_teardown();

View file

@ -38,7 +38,6 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
LIBC_TINYMATH \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_LOG \
LIBC_X \
THIRD_PARTY_GDTOA \
@ -46,7 +45,8 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \
THIRD_PARTY_ZLIB \
THIRD_PARTY_ZLIB_GZ
THIRD_PARTY_ZLIB_GZ \
THIRD_PARTY_TZ
TEST_LIBC_STDIO_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_STDIO_DIRECTDEPS),$($(x))))

View file

@ -39,11 +39,10 @@
#include "libc/sysv/consts/s.h"
#include "libc/testlib/testlib.h"
#include "libc/x/xasprintf.h"
#include "libc/x/xiso8601.h"
__static_yoink("zipos");
__static_yoink("usr/share/zoneinfo/");
__static_yoink("usr/share/zoneinfo/New_York");
__static_yoink("usr/share/zoneinfo/GMT");
__static_yoink("libc/testlib/hyperion.txt");
__static_yoink("libc/testlib/moby.txt");
@ -159,7 +158,7 @@ TEST(dirstream, zipTest) {
const char *path = "/zip/usr/share/zoneinfo/";
ASSERT_NE(NULL, (dir = opendir(path)));
while ((ent = readdir(dir))) {
foundNewYork |= !strcmp(ent->d_name, "New_York");
foundNewYork |= !strcmp(ent->d_name, "GMT");
}
EXPECT_SYS(0, 0, closedir(dir));
EXPECT_TRUE(foundNewYork);
@ -195,7 +194,7 @@ TEST(rewinddir, test) {
}
TEST(dirstream, zipTest_notDir) {
ASSERT_EQ(NULL, opendir("/zip/usr/share/zoneinfo/New_York"));
ASSERT_EQ(NULL, opendir("/zip/usr/share/zoneinfo/GMT"));
ASSERT_EQ(ENOTDIR, errno);
}
@ -431,7 +430,7 @@ TEST(dirstream, walk) {
"FTW_F /zip/libc/testlib/moby.txt\n"
"FTW_DP /zip/libc/testlib\n"
"FTW_DP /zip/libc\n"
"FTW_F /zip/usr/share/zoneinfo/New_York\n"
"FTW_F /zip/usr/share/zoneinfo/GMT\n"
"FTW_DP /zip/usr/share/zoneinfo\n"
"FTW_DP /zip/usr/share\n"
"FTW_DP /zip/usr\n"

View file

@ -29,7 +29,7 @@
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
#define PATH "hog"

View file

@ -38,7 +38,7 @@ __static_yoink("libc/testlib/hyperion.txt");
__static_yoink("libc/testlib/moby.txt");
__static_yoink("libc/testlib-test.txt");
__static_yoink("usr/share/zoneinfo/");
__static_yoink("usr/share/zoneinfo/New_York");
__static_yoink("usr/share/zoneinfo/America/New_York");
DIR *dir;
struct dirent *ent;

View file

@ -45,11 +45,11 @@ TEST_LIBC_THREAD_DIRECTDEPS = \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_X \
THIRD_PARTY_LIBCXXABI \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM
THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_TZ
TEST_LIBC_THREAD_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_THREAD_DIRECTDEPS),$($(x))))

View file

@ -35,7 +35,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/subprocess.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
atomic_int gotsig;
atomic_int gottid;

View file

@ -24,10 +24,11 @@ TEST_LIBC_TIME_DIRECTDEPS = \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_TIME \
LIBC_X
LIBC_X \
THIRD_PARTY_TZ
TEST_LIBC_TIME_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_TIME_DIRECTDEPS),$($(x))))

View file

@ -18,8 +18,7 @@
*/
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
TEST(iso8601, test) {
char p[20];

View file

@ -20,11 +20,10 @@
#include "libc/limits.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
__attribute__((__constructor__)) void init(void) {
setenv("TZ", "GST", true);
setenv("TZ", "America/Los_Angeles", true);
}
char *FormatTime(const char *fmt, struct tm *tm) {
@ -39,7 +38,7 @@ TEST(strftime_100, iso8601_ShakaZuluTime) {
FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t)));
}
TEST(xiso8601, testUnixYearZero) {
TEST(iso8601, testUnixYearZero) {
int64_t t = 0;
ASSERT_STREQ("1970-01-01T00:00:00Z",
FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t)));
@ -59,7 +58,7 @@ TEST(strftime_100, rfc822_ShakaZuluTime) {
TEST(strftime_201, iso8601_GoogleStandardTime) {
int64_t t = 0x5cd04d0e;
ASSERT_STREQ("GST", getenv("TZ"));
ASSERT_STREQ("America/Los_Angeles", getenv("TZ"));
ASSERT_STREQ("2019-05-06T08:04:46PDT",
FormatTime("%Y-%m-%dT%H:%M:%S%Z", localtime(&t)));
}
@ -76,25 +75,25 @@ TEST(strftime_201, rfc822_GoogleStandardTime) {
FormatTime("%a, %d %b %y %T %z", localtime(&t)));
}
/* TEST(xiso8601, testModernity_TODO) { */
/* TEST(iso8601, testModernity_TODO) { */
/* int64_t t = (1600 - 1970) * 31536000; */
/* ASSERT_STREQ("1600-01-01T00:00:00Z", */
/* FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t))); */
/* } */
TEST(xiso8601, testAtLeastBetterThanTraditionalUnixLimit) {
TEST(iso8601, testAtLeastBetterThanTraditionalUnixLimit) {
int64_t t = 10737418235;
ASSERT_STREQ("2310-04-04T16:10:35Z",
FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t)));
}
TEST(xiso8601, testSomethingHuge) {
TEST(iso8601, testSomethingHuge) {
int64_t t = 7707318812667;
ASSERT_STREQ("246205-03-18T20:24:27Z",
FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t)));
}
/* TEST(xiso8601, testMostOfStelliferousEra_TODO) { */
/* TEST(iso8601, testMostOfStelliferousEra_TODO) { */
/* int64_t t = INT64_MAX; */
/* ASSERT_STREQ("somethinghuge-01-01T00:00:00Z", */
/* FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t))); */