In which case we'd have to fall back to a TZ environment variable? FreeBSD drops "what is your timezone for programming purposes" on the floor??
It turns out that /var/db/zoneinfo, if it exists, is in fact a plain file containing the timezone name. Other possible files to look at are /etc/sysconf/clock (one line, format is ZONE="America/Chicago") and /etc/conf.d/{hw,}clock (many lines, format is TIMEZONE="America/Chicago"). Also, /usr/local/etc/timezone apparently takes precedence over /etc/timezone if it exists.
Bleah, and systemsetup is not in PATH?
Apparently it's in /usr/sbin, at least in some releases. Mac OS changes things like crazy.
Hard to imagine POSIX dropped "what is your timezone for programming purposes" on the floor.
Strictly speaking, Posix doesn't have the concept of named timezones at all; that's an IANA concept. In pure Posix, the value of TZ is something like "CST6CDT1,M3.2.0/2,M11.1.0/2" in America/Chicago. This deciphers as:
CST = standard time abbreviation
6 = standard time offset from UTC, negated
CDT = daylight time abbreviation
1 = daylight time minus standard time in hours
M3.2.0 = first day of daylight time is month 3, week 2, day 0 (Sunday)
/2 = time changes to daylight at 2 AM local
M11.1.0 = first day of standard time is month 11, week 1, day 0
/2 time changes to standard at 2 AM
This can be compressed to "CST6CDT,M3.2.0,M11.1.0", because 1 hour DST offset and 2 AM are defaults. As I was saying, decoding this is too much trouble and is wrong for historical data anyway. In place of the M-sequence you can write Jnnn or nnn, where nnn is the day of the year, excluding February 29.
What will you do with the timezone name anyway?
It's a path to the zoneinfo file relative to the zoneinfo directory, which is typically in /usr/share. Those files are easy to decode. The snag is when zoneinfo is somewhere else.
The reason for the continent/city system is relative stability. Continents don't change their names and cities rarely do; countries often do and the boundaries of timezones within a country often do.