Set the Hardware Clock to the current System Time.
.TP
.B \-\-systz
-Reset the System Time based on the current timezone.
+Set the kernel's timezone and reset the System Time based on the current timezone.
-Also set the kernel's timezone value to the local timezone
-as indicated by the TZ environment variable and/or
+The system time is only reset on the first call after boot.
+
+The local timezone is taken to be what is
+indicated by the TZ environment variable and/or
.IR /usr/share/zoneinfo ,
as
.BR tzset (3)
.B \-\-hctosys
that does not read the hardware clock, and may be used in system startup
scripts for recent 2.6 kernels where you know the System Time contains
-the Hardware Clock time.
+the Hardware Clock time. If the Hardware Clock is already in UTC, it is
+not reset.
.TP
.B \-\-adjust
Add or subtract time from the Hardware Clock to account for systematic
struct timeval tv;
struct tm *broken;
int minuteswest;
- int rc;
gettimeofday(&tv, NULL);
if (debug) {
("Not setting system clock because running in test mode.\n"));
retcode = 0;
} else {
+ const struct timezone tz_utc = { 0, 0 };
const struct timezone tz = { minuteswest, 0 };
const struct timeval *tv_null = NULL;
+ int rc = 0;
+
+ /* The first call to settimeofday after boot will assume the systemtime
+ * is in localtime, and adjust it according to the given timezone to
+ * compensate. If the systemtime is in fact in UTC, then this is wrong
+ * so we first do a dummy call to make sure the time is not shifted.
+ */
+ if (universal)
+ rc = settimeofday(tv_null, &tz_utc);
+
+ /* Now we set the real timezone. Due to the above dummy call, this will
+ * only warp the systemtime if the RTC is not in UTC. */
+ if (!rc)
+ rc = settimeofday(tv_null, &tz);
- rc = settimeofday(tv_null, &tz);
if (rc) {
if (errno == EPERM) {
warnx(_