Function: current-time-zone

current-time-zone is a function defined in timefns.c.

Signature

(current-time-zone &optional SPECIFIED-TIME ZONE)

Documentation

Return the offset and name for the local time zone.

This returns a list of the form (OFFSET NAME). OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).
    A negative value means west of Greenwich.
NAME is a string giving the name of the time zone. If SPECIFIED-TIME is given, the time zone offset is determined from it instead of using the current time. The argument should be a Lisp time value; see format-time-string for the various forms of a time value.

The optional ZONE is omitted or nil for Emacs local time, t for Universal Time, wall for system wall clock time, or a string as in the TZ environment variable. It can also be a list (as from current-time-zone) or an integer (as from decode-time) applied without consideration for daylight saving time.

Some operating systems cannot provide all this information to Emacs; in this case, current-time-zone returns a list containing nil for the data it can't find.

View in manual

Probably introduced at or before Emacs version 25.1.

Source Code

// Defined in /usr/src/emacs/src/timefns.c
{
  struct timespec value;
  struct tm local_tm, gmt_tm;
  Lisp_Object zone_offset, zone_name;

  zone_offset = Qnil;
  value = make_timespec (lisp_seconds_argument (specified_time), 0);
  zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value,
				  zone, &local_tm);

  /* gmtime_r expects a pointer to time_t, but tv_sec of struct
     timespec on some systems (MinGW) is a 64-bit field.  */
  time_t tsec = value.tv_sec;
  if (HAVE_TM_GMTOFF || gmtime_r (&tsec, &gmt_tm))
    {
      long int offset = (HAVE_TM_GMTOFF
			 ? tm_gmtoff (&local_tm)
			 : tm_diff (&local_tm, &gmt_tm));
      zone_offset = make_fixnum (offset);
      if (SCHARS (zone_name) == 0)
	{
	  /* No local time zone name is available; use numeric zone instead.  */
	  long int hour = offset / 3600;
	  int min_sec = offset % 3600;
	  int amin_sec = min_sec < 0 ? - min_sec : min_sec;
	  int min = amin_sec / 60;
	  int sec = amin_sec % 60;
	  int min_prec = min_sec ? 2 : 0;
	  int sec_prec = sec ? 2 : 0;
	  char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)];
	  zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d",
					     (offset < 0 ? '-' : '+'),
					     hour, min_prec, min, sec_prec, sec);
	}
    }

  return list2 (zone_offset, zone_name);
}