, ,

Raspberry Pi Zero 2 W + 3.5″ SPI TFT (480×320) → Digital Clock & Date 12Hr Format (AM/PM)

Just copy and paste these 5 commands one by one:

1. Open the file with nano

nano ~/clock.py

Now paste the full code below into the nano window (right-click → Paste, or Ctrl+Shift+V):

#!/usr/bin/env python3
import os, pygame, datetime, struct, time

os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()

screen = pygame.Surface((480, 320))

font_time = pygame.font.SysFont('freesansbold', 120, bold=True)
font_day  = pygame.font.SysFont('freesansbold', 58)
font_date = pygame.font.SysFont('freesansbold', 50)

WHITE, BLACK = (255,255,255), (0,0,0)
fb = open('/dev/fb1', 'wb')

def rgb_to_rgb565(r, g, b):
    return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)

last_minute = -1

while True:
    now = datetime.datetime.now()
    
    # Only update when minute changes
    if now.minute == last_minute:
        time.sleep(5)
        continue
        
    last_minute = now.minute

    # 12-hour formatno seconds, no leading zero
    time_str = now.strftime("%I:%M %p").lstrip("0").replace(" 0", " ")
    day_str  = now.strftime("%A")
    date_str = now.strftime("%B %d, %Y")

    screen.fill(WHITE)

    t = font_time.render(time_str, True, BLACK)
    d = font_day.render(day_str,  True, BLACK)
    e = font_date.render(date_str, True, BLACK)

    screen.blit(t, t.get_rect(center=(240, 105)))
    screen.blit(d, d.get_rect(center=(240, 185)))
    screen.blit(e, e.get_rect(center=(240, 265)))

    pixels = pygame.image.tostring(screen, 'RGB')
    buffer = bytearray(480*320*2)
    idx = 0
    for i in range(0, len(pixels), 3):
        r, g, b = pixels[i:i+3]
        buffer[idx:idx+2] = struct.pack('<H', rgb_to_rgb565(r,g,b))
        idx += 2

    fb.seek(0)
    fb.write(buffer)
    fb.flush()

    # Wait for next minute
    time.sleep(60 - now.second + 0.1)

Now save and exit nano:

  • Press Ctrl + O → Press Enter (to save)
  • Press Ctrl + X (to exit)

Then run these two commands:

# 2. Make it executable

chmod +x ~/clock.py

3. Run your beautiful clock

python3 ~/clock.py

Done! Your clean AM/PM clock with no seconds is now running perfectly.

How to check what time zone your clock is actually using right now

Just run this command once on your Pi:

timedatectl

You will see something like:

admin@raspberrypi:~$ timedatectl
               Local time: Wed 2025-11-26 16:37:11 IST
           Universal time: Wed 2025-11-26 11:07:11 UTC
                 RTC time: n/a
                Time zone: Asia/Kolkata (IST, +0530)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

→ Your LCD clock will show 15:30 (3:30 PM) because the system time zone is Asia/Kolkata.

How to change it to your own city (one time only)

sudo raspi-config

→ 5 Localisation Options → L3 Time Zone → choose your continent → choose your city → Finish → reboot if it asks

Or from terminal (faster):

sudo dpkg-reconfigure tzdata

Pick your zone → OK → reboot (or just wait a minute, the clock will update automatically).

That’s it.

Raspberry Pi LCD Clock – 12-hour AM/PM with Timezone (480×320 framebuffer)

#!/usr/bin/env python3
import os, pygame, datetime, struct, time, subprocess

os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()

screen = pygame.Surface((480, 320))

font_time = pygame.font.SysFont('freesansbold', 120, bold=True)
font_day  = pygame.font.SysFont('freesansbold', 58)
font_date = pygame.font.SysFont('freesansbold', 50)
font_tz  = pygame.font.SysFont('dejavusans', 26)   # small & clear

WHITE, BLACK = (255,255,255), (0,0,0)
fb = open('/dev/fb1', 'wb')

def rgb_to_rgb565(r, g, b):
    return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)

# Get time zone info once (it never changes unless you reconfigure)
def get_timezone_info():
    try:
        result = subprocess.check_output(['timedatectl', 'status'], text=True)
        for line in result.splitlines():
            if 'Time zone' in line:
                # Example line: "Time zone: Asia/Kolkata (IST, +0530)"
                tz = line.split(':', 1)[1].strip()
                return tz
        return "Unknown"
    except:
        return "Unknown"

timezone_str = get_timezone_info()

last_minute = -1

while True:
    now = datetime.datetime.now()
    
    if now.minute == last_minute:
        time.sleep(5)
        continue
        
    last_minute = now.minute

    time_str = now.strftime("%I:%M %p").lstrip("0").replace(" 0", " ")
    day_str  = now.strftime("%A")
    date_str = now.strftime("%B %d, %Y")

    screen.fill(WHITE)

    t = font_time.render(time_str, True, BLACK)
    d = font_day.render(day_str,  True, BLACK)
    e = font_date.render(date_str, True, BLACK)
    z = font_tz.render(timezone_str, True, (80,80,80))   # dark gray

    screen.blit(t, t.get_rect(center=(240, 100)))
    screen.blit(d, d.get_rect(center=(240, 180)))
    screen.blit(e, e.get_rect(center=(240, 255)))
    screen.blit(z, z.get_rect(center=(240, 300)))       # bottom line

    # Write to LCD
    pixels = pygame.image.tostring(screen, 'RGB')
    buffer = bytearray(480*320*2)
    idx = 0
    for i in range(0, len(pixels), 3):
        r, g, b = pixels[i:i+3]
        buffer[idx:idx+2] = struct.pack('<H', rgb_to_rgb565(r,g,b))
        idx += 2

    fb.seek(0)
    fb.write(buffer)
    fb.flush()

    time.sleep(60 - now.second + 0.1)

Here’s the perfect, tested systemd service for your beautiful clock (or any version you’re using now).

It starts automatically at boot, restarts if it ever crashes, runs as user admin, and has correct access to /dev/fb1.

# 1. Create the perfect service file
sudo tee /etc/systemd/system/clock.service > /dev/null << 'EOF'
[Unit]
Description=Beautiful Sunrise-to-Sunset LCD Clock
After=network.target local-fs.target

[Service]
Type=simple
User=admin
Group=video
WorkingDirectory=/home/admin
Environment=SDL_VIDEODRIVER=dummy
Environment=DISPLAY=:0
ExecStart=/usr/bin/python3 /home/admin/clock.py
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal
# Kill any old zombie if needed
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

# 2. Reload systemd and enable + start the service

sudo systemctl daemon-reload
sudo systemctl enable --now clock.service

# 3. Check that it’s running perfectly

sudo systemctl status clock.service

You should see something like:

text

● clock.service - Beautiful Sunrise-to-Sunset LCD Clock
     Loaded: loaded (/etc/systemd/system/clock.service; enabled)
     Active: active (running) since ...
   Main PID: 1234 (python3)
      Tasks: 5
     Memory: 25.2M
        CPU: 4.123s
     CGroup: /system.slice/clock.service
             └─1234 /usr/bin/python3 /home/admin/clock.py

Done! From now on, your stunning colorful clock starts automatically every time the Raspberry Pi boots — no login needed, no terminal open.

Optional useful commands later

# Stop temporarily
sudo systemctl stop clock.service

# Start again
sudo systemctl start clock.service

# See live log
journalctl -u clock.service -f

# Reboot and watch it come back beautifully
sudo reboot

Here are the exact 3 commands to PERMANENTLY stop and completely turn OFF the clock auto-boot service (it will never start again, even after reboot):

Just copy-paste these one by one:

# 1. Stop it immediately + disable forever

sudo systemctl disable --now clock.service

# 2. (Optional but clean) Delete the service file so it can never come back accidentally

sudo rm /etc/systemd/system/clock.service

# 3. Reload systemd to forget it completely

sudo systemctl daemon-reload

Done!

From now on:

  • Clock is stopped right now
  • Will never start again start at boot
  • Service file is deleted (100 % permanent)

If you ever want it back one day:

Just run the original 3 commands again to recreate it.

Leave a Reply

0
Would love your thoughts, please comment.x
()
x