Figure Out What It Is Right Now Without Third-Party Apps
San Francisco sits in the Pacific Time Zone, which runs UTC-8 during standard time and UTC-7 once daylight saving kicks in. That's the whole answer on paper. The practical version is messier, because the changeover dates don't line up cleanly with anything recognizable, and people still get tripped up when they're coordinating calls across the country. If you want the current time without opening a browser tab that loads a billion ads, just ask your system clock. On Windows, open Settings, search for "Date and time," and verify the time zone is set to Pacific. On macOS it's under System Settings, Date & Time, then turn off automatic zone if you're doing any cross-zone work. Linux users can run `timedatectl` from a terminal, or check /etc/timezone to see what's actually configured. If you're building an app, don't roll your own conversion logic. Use the IANA database—`pytz` or `zoneinfo` for Python, `java.time` for Java, Moment-Timezone or the built-in `Intl` for JavaScript. The system libraries handle transitions correctly. Your custom if-statements won't. I ran into this during a multi-region product launch about three years ago. We had a staging server in one timezone, the database in another, and a deployment script that logged everything in UTC but formatted timestamps locally before pushing them to a ticketing system. What looked like a routine release at 4pm Pacific ended up showing as 11:01pm in the logs because the script picked up the OS locale, not the variable we thought it was reading. The fix was straightforward but annoying: I hardcoded `TZ=America/Los_Angeles` at the top of the deployment shell script, plus I added an explicit UTC conversion step before the log formatting. It took about twenty minutes to patch and saved us from another weekend of confused incident tickets.
Daylight Saving Transitions Are Where Everything Breaks
Pacific Time doesn't just flip once a year on a schedule everyone remembers. Since 2007, DST starts on the second Sunday in March and ends on the first Sunday in November. Before that, the dates were different, and if you're working with historical data going back further, the rules changed again in 1986 and 1966. You will lose hours if you assume the current schedule applies retroactively. There are two edge cases I see people fail on repeatedly. First, the spring-forward gap creates an hour that never exists. If your system tries to schedule something at 2:30am Pacific on a transition day, it either jumps to 4:30am or throws an error depending on the language. Second, fall-back creates an ambiguous hour. 1:30am happens twice. If you're storing instants as naive local timestamps, you have no way of knowing which 1:30am you're looking at without additional context. Always store instants in UTC internally. Only convert to Pacific for display at the last possible moment. The counter-intuitive part most beginners miss is that a naive datetime object in your local code is not a timestamp. It's a label. Treating it like an instant is what causes the bugs. When I consult on these kinds of problems, the fix is rarely a timezone library addition. It's usually convincing the team to stop passing around local datetime objects between services.
How to Actually Coordinate Across the Coast Without Scheduling Wars
Here's the practical rule I use now and recommend to anyone managing a distributed team. Never schedule anything based on what time zone the invite says. Confirm it in UTC. A meeting at "9am Pacific" is fine for the subject line, but the calendar entry should be stored as 16:00 UTC so it resolves correctly regardless of whether someone is reading it in Phoenix, Chicago, or Reykjavik. Phoenix doesn't observe DST, which means for roughly half the year Pacific and Mountain are the same offset, then they diverge, and your recurring invites drift by an hour if you let the calendar app auto-adjust them. I keep a small Python snippet in my dotfiles that maps the current Pacific offset against UTC and warns me when we're within fourteen days of a transition. It's not elegant, but it catches the window where most scheduling mistakes happen.
Get the Full Details

import zoneinfo, datetime, calendar
tz = zoneinfo.ZoneInfo("America/Los_Angeles")
today = datetime.date.today()
year = today.year
march = calendar.monthcalendar(year, 3)
second_sun = [d for d in march[1] if d != 0][1]
november = calendar.monthcalendar(year, 11)
first_sun = november[0]
spring = datetime.date(year, 3, second_sun)
fall = datetime.date(year, 11, first_sun)
threshold = datetime.timedelta(days=14)
if abs((spring - today).days) <= threshold:
print("Pacific DST spring transition approaching")
if abs((fall - today).days) = threshold:
print("Pacific DST fall transition approaching")
This cuts scheduling confusion from maybe an hour per month to almost zero, once the team stops relying on the invite subject line as the source of truth. No method above helps if you're dealing with legacy systems that store timestamps as integers without unit documentation. I've seen databases where "epoch" meant different things on different machines—some seconds, some milliseconds, some microseconds—and the application layer assumed one while the migration tool used another. The numbers look right until you compare them against actual events and everything is off by a factor of a thousand. In those cases, the workaround is audit logs, binary dumps, and finding a reference point you can trust, like a physically labeled hardware clock or a signed commit that records the exact second. It takes longer than you want, usually two to four hours for a medium system, but it's the only reliable way to resolve the ambiguity. If you're building something new and need to show Pacific time to users, just serve the data in UTC and let the client convert it using the device's timezone settings. The client knows its own offset better than your server will, especially when travel schedules blur the lines.
Quick Reference for Common Mistakes
Don't use `datetime.now()` and treat the result as an instant. Use `datetime.now(tz)` or `datetime.utcnow()` and attach the zone at display time. Don't parse time strings without specifying a zone, because the parser will assume local time and you'll inherit whatever zone the machine happened to be in when the code was deployed. Don't store timezone abbreviations like PST or PDT, because they're ambiguous and shift with the calendar. Don't assume two Pacific locations are in the same zone, since places like Navajo Nation sit in Mountain Time despite being geographically surrounded by Pacific. Don't skip the offset when logging cross-region events, because "9am" means nothing without the zone attached. Keep the zone explicit at every boundary. The rest of this topic is just details after that.