This works (by reading /etc/localtime) on NetBSD, but not on Android
since we have no such file. Fix that by using our equivalent system
property instead.
Also s/time zone/timezone/ in documentation and comments. We've always
been inconsistent about this (as is upstream in code comments and
documentation) but it seems especially odd now we expose a _type_ that
spells it "timezone" to talk of "time zone" even as we're describing
that type and its associated functions.
Bug: https://github.com/chronotope/chrono/issues/499
Test: treehugger
Change-Id: I142995a3ab4deff1073a0aa9e63ce8eac850b93d
* Rationale
The question often comes up of how to use multiple time zones in C code.
If you're single-threaded, you can just use setenv() to manipulate $TZ.
toybox does this, for example. But that's not thread-safe in two
distinct ways: firstly, getenv() is not thread-safe with respect to
modifications to the environment (and between the way putenv() is
specified and the existence of environ, it's not obvious how to fully
fix that), and secondly the _caller_ needs to ensure that no other
threads are using tzset() or any function that behaves "as if" tzset()
was called (which is neither easy to determine nor easy to ensure).
This isn't a bigger problem because most of the time the right answer
is to stop pretending that libc is at all suitable for any i18n, and
switch to icu4c instead. (The NDK icu4c headers do not include ucal_*,
so this is not a realistic option for most applications.)
But what if you're somewhere in between? Like the rust chrono library,
for example? What then?
Currently their "least worst" option is to reinvent the entire wheel and
read our tzdata files. Which isn't a great solution for anyone, for
obvious maintainability reasons.
So it's probably time we broke the catch-22 here and joined NetBSD in
offering a less broken API than standard C has for the last 40 years.
Sure, any would-be caller will have to have a separate "is this
Android?" and even "is this API level >= 35?" path, but that will fix
itself sometime in the 2030s when developers can just assume "yes, it
is", whereas if we keep putting off exposing anything, this problem
never gets solved.
(No-one's bothered to try to implement the std::chrono::time_zone
functionality in libc++ yet, but they'll face a similar problem if/when
they do.)
* Implementation
The good news is that tzcode already implements these functions, so
there's relatively little here.
I've chosen not to expose `struct state` because `struct __timezone_t`
makes for clearer error messages, given that compiler diagnostics will
show the underlying type name (`struct __timezone_t*`) rather than the
typedef name (`timezone_t`) that's used in calling code.
I've moved us over to FreeBSD's wcsftime() rather than keep the OpenBSD
one building --- I've long wanted to only have one implementation here,
and FreeBSD is already doing the "convert back and forth, calling the
non-wide function in the middle" dance that I'd hoped to get round to
doing myself someday. This should mean that our strftime() and
wcsftime() behaviors can't easily diverge in future, plus macOS/iOS are
mostly FreeBSD, so any bugs will likely be interoperable with the other
major mobile operating system, so there's something nice for everyone
there!
The FreeBSD wcsftime() implementation includes a wcsftime_l()
implementation, so that's one stub we can remove. The flip side of that
is that it uses mbsrtowcs_l() and wcsrtombs_l() which we didn't
previously have. So expose those as aliases of mbsrtowcs() and
wcsrtombs().
Bug: https://github.com/chronotope/chrono/issues/499
Test: treehugger
Change-Id: Iee1b9d763ead15eef3d2c33666b3403b68940c3c
57b8fc957a
changes the way overflows are tracked: now compiler builtins
are used instead of manual arithmetics. But as int_fast32_t on
64-bit Android takes 8 bytes, new logic behaves differently.
See time_test.cpp changes for more details.
Changes were applied using following commands:
1) Checkout tzcode repo
2) Prepare patches for all tzcode file using
git diff 2022a 2023a -- <file-name> > <file-name-patch>
3) Apply these patches to files in bionic using
patch -p1 <file-name> <file-name-patch>
Bug: 279742606
Test: CtsBionicTestCases
Test: CtsLibcoreTestCases
Test: CtsLibcoreOjTestCases
Test: atest toybox-tests
Change-Id: I7772a90538b8185bdd2f4be6e9d1740c95509d6c
Upstream made a change similar to our %s change, so we don't need that
difference any more. (But they didn't seem interested in our GNU
extensions, even though they're sensible ones that just ensure symmetry
between strftime() and strptime().)
Bug: http://b/167569813
Test: treehugger
Change-Id: I1d86d69c87b51719f0583341fafa7802869cd37e
We still have local differences, but this minimizes (and documents) them.
Bug: http://b/167569813
Test: treehugger
Change-Id: Ib90e6ccc5ec1224e7ee89224a51b87fc48c9931f
For correct %z output tzcode requires tm struct to be modified by
mktime call or be output of localtime. But as TM_ZONE is null, we
are comparing against +0000.
See https://mm.icann.org/pipermail/tz/2022-July/031674.html
Europe/Lisbon test is added to confirm that current implementation
deviates from libc specification and uses more than just tm_isdst
to find out a time zone's offset.
Bug: 239128167
Test: adb shell /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static
Test: adb shell /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
Change-Id: Ic27775c840467c4e9ef55bc730a313709372314b
This reverts commit 4e013233b8.
Issue was in unexpected returned fd and errno value combination.
See comments in bionic.cpp and time_test.cpp.
Bug: 236967833
Fix: 236967833
Test: atest CtsBionicTestCases
Test: atest toybox-tests
Change-Id: I51b3e1527ff16b2a6ea4d6fedf8102019f7fd896
That was place where APK update mechanism placed tzdata file. Now
the mechanism is removed, so no need to look for tzdata there.
Bug: 148144561
Test: atest CtsBionicTestCases
Test: atest BionicTzdbConsistencyTest
Change-Id: I584400a75651cf24a25df74c7007fcd584838395
Upstream has renamed tzsetlcl to tzset_unlocked. As bionic's
implementation of tzset_unlock differs from upstream, these changes were
skipped.
Also, upstream has removed constants (SECSPERMIN, etc) from tzfile.h. As
they are used in strptime.c, I've decided to leave them in tzfile.h and
to not bring them into strptime.c.
HAVE_TZNAME and USG_COMPAT flags semantics were updated, thus setting
their values to 2 in Android.bp file. See
1a27ec76bc
* 4742526b7e
and 0e8f0b06ac
were picked up, which are not part of 2022a.
Changes were applied using following commands:
1) Checkout tzcode repo
2) Prepare patches for all tzcode file using
git diff 2016g 2021e -- <file-name> > <file-name-patch>
3) Apply these patches to files in bionic using
patch -p1 <file-name> <file-name-patch>
Bug: 25413083
Test: CtsLibcoreTestCases
Test: CtsLibcoreOjTestCases
Test: CtsBionicTestCases
Change-Id: I9aba4cbeab30171a32f94d20c8e4057804a4c01f
A decent chunk of the logcat profile is spent formatting the timestamps
for each line, and most of that time was going to snprintf(3). We should
find all the places that could benefit from a lighter-weight "format an
integer" and share something between them, but this is easy for now.
Before:
-----------------------------------------------------------
Benchmark Time CPU Iterations
-----------------------------------------------------------
BM_time_strftime 781 ns 775 ns 893102
After:
-----------------------------------------------------------
Benchmark Time CPU Iterations
-----------------------------------------------------------
BM_time_strftime 149 ns 147 ns 4750782
Much of the remaining time is in tzset() which seems unfortunate.
Test: treehugger
Change-Id: Ie0f7ee462ff1b1abea6f87d4a9a996d768e51056
I made toybox use strptime %Z recently (so that it can parse the default
POSIX date(1) output), forgetting that bionic's strptime(3) doesn't
support %Z. Neither does glibc, for that matter; the toybox change works
on glibc effectively by accident --- glibc just ignores the next word
when parsing %Z and assumes that the current time zone ($TZ) is
appropriate. Which it is for the only obvious use case of "round trip
date(1) output".
The related %z is potentially quite a bit more useful in general (parsing
any valid RFC822 time zone), though sadly not useful for the toybox case
that prompted.
Every time I touch this file I promise that I'll actually get us back in
sync with upstream, and every time I fail to get round to it. Maybe
2020 or 2021 will finally be the year...
Also add corresponding tests.
Bug: https://b/167455975
Test: treehugger
Change-Id: I13a7fb7e3ad01ae855750b9314d2eec661fe034f
It's a historical accident that we try all the other files even if a
higher-priority file doesn't contain the sought-for olson id. Stop
doing that.
Also remove a TODO that has never been warranted, and add one that it
will be many years before anyone can do anything about it, but by that
time the historical knowledge may have been lost.
Bug: http://b/159613340
Test: treehugger
Change-Id: I873579268753c84b0bb721ea56f71ba64506d45a
The tzdata format has changed:
Firstly, there is now a "final_offset", which serves as a pointer to the
beginning of the section after the last known section. The pointer means
that file size is no longer a factor when reading the last section and
new sections could be added to the end of the file in future in a
backwards compatible way.
Secondly, since nothing uses zone.tab on Android it is being removed and
the zonetab_offset is replaced by final_offset.
The net effect for bionic is zero besides some comment / name changes.
Test: build only
Change-Id: Ia315083879c891f2d3fc84cf48e304c323ca89f2
The tzdata file is being removed from the runtime mainline module
in an upcoming commit. This commit removes the bionic references
to it.
This commit also contains general comment tidy-ups.
Bug: 132168458
Test: build only
Change-Id: I83cd9ff756b36e1d1222b7830f97c8bde2885ce4
Our strptime was missing `%F`, `%G`, `%g`, `%P`, `%u`, `%V`, and
`%v`. Most of these are already supported upstream (and I've just pulled
their current implementation), but some aren't. We're horribly out of
sync anyway, so I'll upstream the missing pieces and then try to get us
back in sync later.
Test: new tests, but originally found by toybox trying to use %F
Change-Id: Ib1a10801a7a3b9c9189440c3b300109bde535fd9
To mirror device code more closely, look for time zone data using
ANDROID_TZDATA_ROOT on host. For device usecases the path is still
hardcoded.
Bug: 128422035
Test: build only
Change-Id: I5762745349338bcc3e3a173c1c9b18ea5a3324dd
The "if defined(__ANDROID__)" else branch is there to support
bionic when running on host environments.
The code now checks the
${ANDROID_RUNTIME_ROOT}/etc/tz/tzdata path as well.
This is similar to the current on-device expectations.
Eventually, we may remove the /system / ANDROID_ROOT cases.
Bug: 119293618
Test: build only
Change-Id: I8310f7b5a1c14567a648673970c636c7c84ff818
Look for the tzdata file in the runtime module before looking
in /system. It is still an open question how the removal of
tzdata will be handled, if at all. Until it is worked out it
will be duplicated.
Bug: 119293618
Bug: 119390260
Test: build / boot
Change-Id: I7e14ef41d0ec226caa595c56be61df5ecf50c382
The same prebuilts will be used in both runtime and time zone
modules. Having the rules put the files in etc/tz/ will make
them more appropriate for the runtime module.
Bug: 119026403
Test: build /boot only
Change-Id: Ia1370457e9d1547b35ed56bb385213d3727c8b9a
The package name in the manifest.json is changing to
remove apex so the hardcoded path must change.
Bug: 119026403
Test: build
Change-Id: I906b595a1325b40f8af8c37d7d08cd543c988cc8
The changes needed to pick up time zone data files from
a mounted APEX directory. Code that looks for time zone
data now looks in a new location after checking for
data installed by the time zone updates via APK feature.
This hasn't been tested in combination with a real APEX but
it shouldn't do anything bad if the new path does not exist.
Bug: 115612964
Test: CTS: run cts-dev -m CtsBionicTests
Test: Build / boot without APEX support
Change-Id: I56ae50e26f2cbfa0e537029a0e6f679fa2394327
Since localtime.c is C, this entails pulling our code out into its own
C++ file, which we should probably have done years ago anyway.
Bug: N/A
Test: ran tests, and manually tested via Settings
Change-Id: Ifc787a553e8f739a87641a2d35321aca40a47286
It's faster and safer to skip them on the device, where we know where
everything is anyway.
(cherrypick of cf6365690cc68bdd7e16648fb7881ba0b5cae93d.)
Bug: http://b/36807787
Test: ran tests
Change-Id: I0bb7879cc46f194152c67ddaf072cbebb424f789
Android uses one large file of tzdata, so the "read up to the maximum
possible length of a valid tzfile" code in upstream localtime.c is
broken: there is always data after the current tzfile (even the
last tzfile is followed by the zone.tab data). This patch passes the
exact length through to the read(2) call so we don't over-read, rather
than have to rewrite upstream code that measures back from the "end" of
the tzfile.
The old code failed the existing time.strftime_null_tm_zone test after
updating to tzdata2016g.
Bug: http://b/31848040
Test: time.strftime_null_tm_zone
Change-Id: Iee059b5a8c051bd4952cfd80f02b00d83e489d5e
We need to make a clearer distinction for bionic on the host. This patch
doesn't fully address things like "should host bionic try to talk to netd?"
for now, but is a step in the right direction.
Bug: http://b/31559095
Test: bionic tests.
Change-Id: I49812f8b75d9d78c4fd8a8ddf5df1201d63771d6
POSIX and Java disagree about the sign in a timezone string like "GMT+3".
This means that if you set "persist.sys.timezone" to such a string, native
code and Java code disagree about what time it is. Resolve this by
translating to POSIX form for native code.
Bug: http://b/25463955
Change-Id: I7c08c459dd8514348a12ce419edcbfbfe8f6d327
Test: manually tested with setprop and date.
We should fall back to GMT if neither the environment variable nor the
system property is set. This is the case if you wipe a WiFi-only device,
because we currently only take the time zone from cell networks.
Bug: http://b/24773112
Change-Id: I90d236d4d492b6562d75021bd312030b91c1e298
Upstream tzcode said "On platforms with tm_zone, strftime.c now assumes it
is not NULL". Which is fine for any struct tm generated by tzcode, but not
necessarily true of a struct tm constructed by arbitrary code. In particular,
Netflix on Nexus Player was failing to start because they format "%Z" with
a struct tm whose tm_zone is null (the other fields are valid, but, yeah,
that's probably not intentional).
glibc takes a null tm_zone to mean "the current time zone", so let's do that
too. (Historically Android would use the empty string, and POSIX doesn't
clarify which of this is the appropriate behavior when tm_zone is null.)
Bug: http://b/25170306
Change-Id: Idbf68bfe90d143aca7dada8607742905188b1d33
The original comment implied that Android 32 bit was the only one
using a bad time_t, but it turns out 32 bit glibc has the same time_t
as Android. Update the comment to reflect this reality.
Change-Id: I72cdd2c677a6521f7b43d4695a52fd8fdc3305bd
This is quite a large patch because we haven't updated for some time,
but the good news is that upstream is now thread-safe so a lot of our
changes go away in this update and the remaining diff is a lot smaller.
(Note that our whitespace still doesn't match upstream. I use diff -wub
to compare. Upstream doesn't even really have a consistent style. New
code seems to be two spaces, old code tabs.)
From the intervening changelogs (eliding the changes that only affected
the tools, which we don't use):
2014a:
An uninitialized-storage bug in 'localtime' has been fixed.
(Thanks to Logan Chien.)
2014b:
'zic' and 'localtime' no longer reject locations needing four
transitions per year for the forseeable future. (Thanks to Andrew
Main (Zefram).)
2014c:
<None>
2014d:
<None>
2014e:
<None>
2014f:
'localtime', 'mktime', etc. now use much less stack space if
ALL_STATE is defined. (Thanks to Elliott Hughes for reporting the
problem.)
Some lint has been removed when using GCC_DEBUG_FLAGS with GCC
4.9.0.
2014g:
Unless NETBSD_INSPIRED is defined to 0, the tz library now
supplies functions for creating and using objects that represent
time zones. The new functions are tzalloc, tzfree, localtime_rz,
mktime_z, and (if STD_INSPIRED is also defined) posix2time_z and
time2posix_z. They are intended for performance: for example,
localtime_rz (unlike localtime_r) is trivially thread-safe without
locking. (Thanks to Christos Zoulas for proposing NetBSD-inspired
functions, and to Alan Barrett and Jonathan Lennox for helping to
debug the change.)
If THREAD_SAFE is defined to 1, the tz library is now thread-safe.
Although not needed for tz's own applications, which are single-threaded,
this supports POSIX better if the tz library is used in multithreaded apps.
Some crashes have been fixed when zdump or the tz library is given
invalid or outlandish input.
The tz library no longer mishandles leap seconds on platforms with
unsigned time_t in time zones that lack ordinary transitions after 1970.
The tz code now attempts to infer TM_GMTOFF and TM_ZONE if not
already defined, to make it easier to configure on common platforms.
Define NO_TM_GMTOFF and NO_TM_ZONE to suppress this.
Unless the new macro UNINIT_TRAP is defined to 1, the tz code now
assumes that reading uninitialized memory yields garbage values
but does not cause other problems such as traps.
If TM_GMTOFF is defined and UNINIT_TRAP is 0, mktime is now
more likely to guess right for ambiguous time stamps near
transitions where tm_isdst does not change.
If HAVE_STRFTIME_L is defined to 1, the tz library now defines
strftime_l for compatibility with recent versions of POSIX.
Only the C locale is supported, though. HAVE_STRFTIME_L defaults
to 1 on recent POSIX versions, and to 0 otherwise.
tzselect -c now uses a hybrid distance measure that works better
in Africa. (Thanks to Alan Barrett for noting the problem.)
The C source code now ports to NetBSD when GCC_DEBUG_FLAGS is used,
or when time_tz is defined.
When HAVE_UTMPX_H is set the 'date' command now builds on systems
whose <utmpx.h> file does not define WTMPX_FILE, and when setting
the date it updates the wtmpx file if _PATH_WTMPX is defined.
This affects GNU/Linux and similar systems.
For easier maintenance later, some C code has been simplified,
some lint has been removed, and the code has been tweaked so that
plain 'make' is more likely to work.
The C type 'bool' is now used for boolean values, instead of 'int'.
The long-obsolete LOCALE_HOME code has been removed.
The long-obsolete 'gtime' function has been removed.
2014h:
The tz library's localtime and mktime functions now set tzname to a value
appropriate for the requested time stamp, and zdump now uses this
on platforms not defining TM_ZONE, fixing a 2014g regression.
(Thanks to Tim Parenti for reporting the problem.)
The tz library no longer sets tzname if localtime or mktime fails.
An access to uninitalized data has been fixed.
(Thanks to Jörg Richter for reporting the problem.)
When THREAD_SAFE is defined, the code ports to the C11 memory model.
A memory leak has been fixed if ALL_STATE and THREAD_SAFE are defined
and two threads race to initialize data used by gmtime-like functions.
(Thanks to Andy Heninger for reporting the problems.)
2014i:
The time-related library functions now set errno on failure,
and some crashes in the new tzalloc-related library functions
have been fixed. (Thanks to Christos Zoulas for reporting
most of these problems and for suggesting fixes.)
If USG_COMPAT is defined and the requested time stamp is
standard time, the tz library's localtime and mktime functions
now set the extern variable timezone to a value appropriate
for that time stamp; and similarly for ALTZONE, daylight
saving time, and the altzone variable. This change is a
companion to the tzname change in 2014h, and is designed to
make timezone and altzone more compatible with tzname.
The tz library's functions now set errno to EOVERFLOW if they
fail because the result cannot be represented. ctime and
ctime_r now return NULL and set errno when a time stamp is out
of range, rather than having undefined behavior.
Some bugs associated with the new 2014g functions have been
fixed. This includes a bug that largely incapacitated the new
functions time2posix_z and posix2time_z. (Thanks to Christos
Zoulas.) It also includes some uses of uninitialized
variables after tzalloc. The new code uses the standard type
'ssize_t', which the Makefile now gives porting advice about.
2014j:
<None>
2015a:
tzalloc now scrubs time zone abbreviations compatibly with the way
that tzset always has, by replacing invalid bytes with '_' and by
shortening too-long abbreviations.
2015b:
Fix integer overflow bug in reference 'mktime' implementation.
(Problem reported by Jörg Richter.)
Allow -Dtime_tz=time_t compilations, and allow -Dtime_tz=... libraries
to be used in the same executable as standard-library time_t functions.
(Problems reported by Bradley White.)
2015c:
<None>
2015d:
<None>
2015e:
<None>
2015f:
<None>
2015g:
localtime no longer mishandles America/Anchorage after 2037.
(Thanks to Bradley White for reporting the bug.)
On hosts with signed 32-bit time_t, localtime no longer mishandles
Pacific/Fiji after 2038-01-16 14:00 UTC.
The localtime module allows the variables 'timezone', 'daylight',
and 'altzone' to be in common storage shared with other modules,
and declares them in case the system <time.h> does not.
(Problems reported by Kees Dekker.)
On platforms with tm_zone, strftime.c now assumes it is not NULL.
This simplifies the code and is consistent with zdump.c.
(Problem reported by Christos Zoulas.)
Change-Id: I9eb0a8323cb8bd9968fcfe612dc14f45aa3b59d2
logd makes a non-insignificant number of calls to localtime, 3% of
the time in logd is spent performing __system_property_get within the
context of tzset_locked().
Bug: 23685592
Change-Id: I75f8c2d436b60374e92c166b87393abda9487af7
Bug: 24492248
Shifting sign bits left is considered undefined behavior, so we need to
switch these uses to unsigned equivalents. The time_t-related code is
updated relative to upstream sources.
Change-Id: I226e5a929a10f5c57dfcb90c748fdac34eb377c2
The mktime API returned an uncorrect time when TZ is set as empty.
A timezone UTC/GMT+0 should be implied in the empty case. However
mktime keeps previous information about timezone. If mktime was called
with a timezone which has DST before, the "defaulttype" member of
"state" structure wouldn't be 0. Then it would be used next time,
even though UTC/GMT+0 doesn't have DST.
Added initialization of the "defaulttype" in the empty TZ case.
Change-Id: Ic480c63c548c05444134e0aefb30a7b380e3f40b
This change should probably be made upstream as well, but they have a
note about not using it because it isn't available on all systems.
Change-Id: I6d8404c031bd2f486532ced55d94bbb4a4cd2e71
The recent libcore ZoneInfo changes mean that we can no longer
compile libcore's ZoneInfo against the RI. Luckily, the field in
our data file that we needed ZoneInfo for isn't actually used.
This change removes our dependence on libcore.
I've left the field in to avoid a file format change. We can remove
the field if/when we next have a real need to bump the file format.
(cherry-pick of 90cb5ffb85a9bc2e725824b3ca8db932d02c45db.)
Bug: 16168653
Change-Id: Iedad2252c2b49f4d8bb2c7d9078b39b622444ca7
This also brings our copy of strftime.c much closer to upstream, though
we still have several GNU extensions and hacks to deal with Android32's
broken time_t.
Bug: 15765976
Change-Id: Ic9ef36e8acd3619504ecc4d73feec2b61fd4dfa1