Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Contributors:
* Chris Rose (offbyone/offby1)
* Mathieu Dupuy (deronnax)
* Chris Novakovic
* Max Smolin (maximsmol)
* Josh Lynch (josh-lynch)
* Fabio (3ximus)

Expand Down
7 changes: 7 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Dev
==================

Features
--------
* The session time zone setting is set to the system time zone by default

4.2.0 (2025-03-06)
==================

Expand Down
53 changes: 52 additions & 1 deletion pgcli/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from zoneinfo import ZoneInfoNotFoundError
from configobj import ConfigObj, ParseError
from pgspecial.namedqueries import NamedQueries
from .config import skip_initial_comment
Expand All @@ -23,6 +24,7 @@
from cli_helpers.utils import strip_ansi
from .explain_output_formatter import ExplainOutputFormatter
import click
import tzlocal

try:
import setproctitle
Expand Down Expand Up @@ -1593,9 +1595,9 @@ def cli(
if list_databases or ping_database:
database = "postgres"

cfg = load_config(pgclirc, config_full_path)
if dsn != "":
try:
cfg = load_config(pgclirc, config_full_path)
dsn_config = cfg["alias_dsn"][dsn]
except KeyError:
click.secho(
Expand Down Expand Up @@ -1624,6 +1626,55 @@ def cli(
else:
pgcli.connect(database, host, user, port)

if "use_local_timezone" not in cfg["main"] or cfg["main"].as_bool(
"use_local_timezone"
):
server_tz = pgcli.pgexecute.get_timezone()

def echo_error(msg: str):
click.secho(
"Failed to determine the local time zone",
err=True,
fg="yellow",
)
click.secho(
msg,
err=True,
fg="yellow",
)
click.secho(
f"Continuing with the default time zone as preset by the server ({server_tz})",
err=True,
fg="yellow",
)
click.secho(
"Set `use_local_timezone = False` in the config to avoid trying to override the server time zone\n",
err=True,
dim=True,
)

local_tz = None
try:
local_tz = tzlocal.get_localzone_name()

if local_tz is None:
echo_error("No local time zone configuration found\n")
else:
click.secho(
f"Using local time zone {local_tz} (server uses {server_tz})",
fg="green",
)
click.secho(
"Use `set time zone <TZ>` to override, or set `use_local_timezone = False` in the config",
dim=True,
)

pgcli.pgexecute.set_timezone(local_tz)
except ZoneInfoNotFoundError as e:
# e.args[0] is the pre-formatted message which includes a list
# of conflicting sources
echo_error(e.args[0])

if list_databases:
cur, headers, status = pgcli.pgexecute.full_databases()

Expand Down
4 changes: 4 additions & 0 deletions pgcli/pgclirc
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ enable_pager = True
# Use keyring to automatically save and load password in a secure manner
keyring = True

# Automatically set the session time zone to the local time zone
# If unset, uses the server's time zone, which is the Postgres default
use_local_timezone = True

# Custom colors for the completion menu, toolbar, etc.
[colors]
completion-menu.completion.current = 'bg:#ffffff #000000'
Expand Down
13 changes: 13 additions & 0 deletions pgcli/pgexecute.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,3 +881,16 @@ def casing(self):

def explain_prefix(self):
return "EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) "

def get_timezone(self) -> str:
query = psycopg.sql.SQL("show time zone")
with self.conn.cursor() as cur:
cur.execute(query)
return cur.fetchone()[0]

def set_timezone(self, timezone: str):
query = psycopg.sql.SQL("set time zone {}").format(
psycopg.sql.Identifier(timezone)
)
with self.conn.cursor() as cur:
cur.execute(query)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies = [
# task manager. Also setproctitle is a hard dependency to install in Windows,
# so we'll only install it if we're not in Windows.
"setproctitle >= 1.1.9; sys_platform != 'win32' and 'CYGWIN' not in sys_platform",
"tzlocal >= 5.2",
]
dynamic = ["version"]

Expand Down
Loading