Offline timezone lookup + local time formatting + optional weather & calendar conversions
Project description
libtime
What time is it right now, and how do I format it?
libtime gives you the answer – offline, fast, and without API keys.
A Python library that finds the timezone of any city worldwide (offline, using an embedded database), provides local time formatting (12h/24h, custom strftime), supports optional calendar conversions (Hijri, Jalali, Hebrew), and can fetch the current weather via a free API.
Features
- Timezone for any city – offline, no internet required
- Three database sizes – from "lite" (~2000 cities) to "full" (~150,000 cities)
- Local time formatting – 12h/24h, with/without seconds, or any custom pattern
- Optional calendar conversions – Islamic (Hijri), Persian (Jalali), Hebrew
- Current weather – async, uses Open-Meteo (free, no API key)
- Minimal dependencies – only
aiohttpfor weather; calendars are optional extras - Async API – works well with Discord bots (Nextcord, discord.py) and other async apps
Installation
Basic installation (timezone + weather):
pip install libtime
For optional calendar conversions (Hijri, Jalali, Hebrew):
pip install libtime[calendar]
pip install tzdata
Quickstart Examples
1. Timezone of a city
from libtime import timezone_for_city
print(timezone_for_city("Berlin")) # Europe/Berlin
print(timezone_for_city("Tokyo")) # Asia/Tokyo
print(timezone_for_city("New York")) # America/New_York
2. Get all city data (coordinates, country, timezone)
from libtime import resolve_city
data = resolve_city("Cairo")
print(data)
# {
# 'tz': 'Africa/Cairo',
# 'lat': 30.0444,
# 'lng': 31.2357,
# 'country': 'EG'
# }
3. Local time formatting
from libtime import local_time
print(local_time("Berlin")) # 14:05:30 (24h with seconds)
print(local_time("London", format="12h")) # 02:05:30 PM
print(local_time("New York", format="12h_no_sec")) # 02:05 PM
print(local_time("Tokyo", format="%I:%M %p")) # custom strftime -> 02:05 PM
4. Current weather (async)
import asyncio
from libtime import get_current_weather, format_weather
async def main():
weather = await get_current_weather("Paris")
if weather:
print(format_weather(weather)) # "Rain, 12.3°C"
else:
print("City not found or API error")
asyncio.run(main())
5. Optional calendar conversions (requires libtime[calendar])
from libtime import local_datetime
from libtime.calendar import to_hijri, to_jalali, to_hebrew
dt = local_datetime("Cairo")
if dt:
print(to_hijri(dt)) # {'year': 1446, 'month': 9, 'month_name': 'Ramadan', 'day': 12}
print(to_jalali(dt)) # {'year': 1404, 'month': 2, 'month_name': 'Ordibehesht', 'day': 22}
print(to_hebrew(dt)) # {'year': 5784, 'month': 8, 'month_name': 'Iyar', 'day': 15}
6. Discord bot example (Nextcord)
import nextcord
from nextcord.ext import commands
from libtime import preload_database, timezone_for_city, local_time, get_current_weather
bot = commands.Bot(command_prefix="!")
@bot.event
async def on_ready():
preload_database("city")
print(f"Bot {bot.user} is ready")
@bot.command()
async def time(ctx, *, city: str):
tz = timezone_for_city(city)
if not tz:
await ctx.send(f"City `{city}` not found.")
return
local = local_time(city, format="12h")
await ctx.send(f"**{city}**\nTimezone: `{tz}`\nLocal time: `{local}`")
@bot.command()
async def weather(ctx, *, city: str):
w = await get_current_weather(city)
if w:
await ctx.send(f"**{city}**: {w['temperature']:.1f}°C")
else:
await ctx.send(f"No weather data for `{city}`.")
bot.run("YOUR_TOKEN")
Database Variants
libtime includes three pre‑built databases. Choose one with preload_database():
| Variant | Size | Contains |
|---|---|---|
lite |
0.5 MB | ~2,000 major cities (capitals + large cities), primary names only |
city |
2 MB | ~135,000 cities, primary names only – no translations |
full |
2.2 MB | ~1.3 million entries – all cities + all translations + native names + state + capital |
Preload a specific variant:
from libtime import preload_database
preload_database("full") # or "city", "lite"
If you do not preload, the library automatically uses the largest available database (full > city > lite).
Weather Notes
- Requires an active internet connection.
- No API key required – Open‑Meteo is completely free.
- Asynchronous – use
await get_current_weather("city"). - Weather codes are mapped to readable texts (see
libtime.WEATHER_CODES).
Credits
- City database: dr5hn/countries-states-cities-database (ODbL 1.0)
- Weather API: Open-Meteo (free, no API key)
- HTTP client: aiohttp (Apache License 2.0)
- Timezone data: tzdata (Apache License 2.0) – provides IANA timezone database, especially for Windows
- Optional calendars: hijri-converter, jdatetime, convertdate
License
MIT License – see LICENSE file.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file libtime-1.1.5.tar.gz.
File metadata
- Download URL: libtime-1.1.5.tar.gz
- Upload date:
- Size: 24.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fec8872dc829ced260410ecef2ae8be6d078d6ec61c5db1e8ef3aa81ef445356
|
|
| MD5 |
096cad0db7d2770d0d48abf2d97e4b43
|
|
| BLAKE2b-256 |
4cc9dc79add8bcbe29f2b05bfef2af2c2168f6b9f1091a89beecb679d2d2b983
|
Provenance
The following attestation bundles were made for libtime-1.1.5.tar.gz:
Publisher:
python-publish.yml on LibS0n/libtime
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libtime-1.1.5.tar.gz -
Subject digest:
fec8872dc829ced260410ecef2ae8be6d078d6ec61c5db1e8ef3aa81ef445356 - Sigstore transparency entry: 1573673524
- Sigstore integration time:
-
Permalink:
LibS0n/libtime@2e78ce1e91a544e30282c3129e87624732aae302 -
Branch / Tag:
refs/tags/1.1.5 - Owner: https://github.com/LibS0n
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@2e78ce1e91a544e30282c3129e87624732aae302 -
Trigger Event:
release
-
Statement type:
File details
Details for the file libtime-1.1.5-py3-none-any.whl.
File metadata
- Download URL: libtime-1.1.5-py3-none-any.whl
- Upload date:
- Size: 24.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fd1620d92708882b2795fb77026bab8e1457bcf80c5267950bf78da92240265
|
|
| MD5 |
6a1b2a1138827998e637421e2bfa5c9d
|
|
| BLAKE2b-256 |
80e3aeb3a4d350f2c43de5677bb9125d73e285b370d11d4a8206af7bc4799be7
|
Provenance
The following attestation bundles were made for libtime-1.1.5-py3-none-any.whl:
Publisher:
python-publish.yml on LibS0n/libtime
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libtime-1.1.5-py3-none-any.whl -
Subject digest:
0fd1620d92708882b2795fb77026bab8e1457bcf80c5267950bf78da92240265 - Sigstore transparency entry: 1573673533
- Sigstore integration time:
-
Permalink:
LibS0n/libtime@2e78ce1e91a544e30282c3129e87624732aae302 -
Branch / Tag:
refs/tags/1.1.5 - Owner: https://github.com/LibS0n
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@2e78ce1e91a544e30282c3129e87624732aae302 -
Trigger Event:
release
-
Statement type: