fedecalendino / alfred-world-clock Goto Github PK
View Code? Open in Web Editor NEWAlfred Workflow to check time in multiple timezones ๐๏ธ
Home Page: https://alfred.app/workflows/fedecalendino/world-clock/
License: MIT License
Alfred Workflow to check time in multiple timezones ๐๏ธ
Home Page: https://alfred.app/workflows/fedecalendino/world-clock/
License: MIT License
i want show time use this format:
2024/1/6 15:00:01
It would be great if one could add the Anywhere on Earth timezone!
The current way of sharing the workflow is atypical. It ships with a Python distribution which is ARM-only and significantly increases the size of the workflow. Plus itโs unsigned, so userโs canโt inspect the code and will get a warning from macOS that it is from an unidentified developer.
This means fewer users will have access to it or try it.
You can use /usr/bin/python3
directly, which is a shim on macOS but will install Python 3 when first called. A macOS GUI dialog guides users through the process.
Also, note that due to not having a Title in the Script Filter, it wonโt show up in the list of results as users type part of the name.
I like your Alfred Word Clock and added some functionality.
import sys
from datetime import timedelta, datetime
from uuid import uuid4
import pytz as tz
from pyflow import Workflow
import data
import formatters
#added function to be able to type:
#now 1 (add 1 hour)
#now -1 (subtract 1 hour)
# and more options...
def add_time(arg):
if arg[0] == '-':
is_negative = True
arg = arg[1:]
else:
is_negative = False
if len(arg) == 0 or (len(arg.strip()) == 1 and arg.startswith('+')):
return 0
if arg.endswith(':'):
arg = arg[:-1]
arg = arg.split(':')
if len(arg) == 3:
hr, minute, sec = arg
total_seconds = int(hr) * 3600 + int(minute) * 60 + int(sec)
elif len(arg) == 2:
hr, minute = arg
total_seconds = int(hr) * 3600 + int(minute) * 60
elif len(arg) == 1:
hr = arg[0]
total_seconds = int(hr) * 3600
if is_negative:
total_seconds = -total_seconds
return total_seconds
def get_home(workflow):
home_tz = workflow.env["HOME"][3:].replace("__", "/")
home_now = (
datetime.utcnow()
.replace(tzinfo=tz.utc)
.astimezone(
tz=tz.timezone(home_tz),
)
)
return home_tz, home_now
def get_timezones(workflow, home_tz):
timezones = set(
map(
lambda item: item[0][3:].replace("__", "/"),
filter(
lambda item: item[0].startswith("TZ_") and item[1] == "1",
workflow.env.items(),
),
)
)
timezones.add(home_tz)
return {
timezone: datetime.utcnow()
.replace(tzinfo=tz.utc)
.astimezone(tz=tz.timezone(timezone))
for timezone in timezones
}
def get_formatter(workflow):
timestamp_format = workflow.env.get("TIMESTAMP_FORMAT", "FORMAT_DEFAULT")
return formatters.FORMATTERS[timestamp_format]
def get_icon(timezone, now, home_tz):
if timezone == home_tz:
return "img/icons/home.png"
if timezone == "UTC":
return "img/icons/utc.png"
utc_offset = now.utcoffset()
utc_offset_hours = round(utc_offset.days * 24 + utc_offset.seconds / 60 / 60)
return f"img/icons/{utc_offset_hours}.png"
#I also wanted the UTC +/- added to the output:
def get_utc(timezone, now, home_tz):
# if timezone == home_tz:
# return "img/icons/home.png"
# if timezone == "UTC":
# return "img/icons/utc.png"
utc_offset = now.utcoffset()
utc_offset_hours = round(utc_offset.days * 24 + utc_offset.seconds / 60 / 60)
if utc_offset_hours == 0:
return ""
if utc_offset_hours > 0:
return f" - UTC +{utc_offset_hours}"
return f" - UTC {utc_offset_hours}"
def get_home_offset_str(timezone, home_tz, now, home_now) -> str:
if timezone == home_tz:
return ""
now_tmp = now.replace(tzinfo=None)
home_now_tmp = home_now.replace(tzinfo=None)
if home_now_tmp > now_tmp:
home_offset = home_now_tmp - now_tmp
seconds = home_offset.seconds + 1
text = "behind"
else:
home_offset = home_now_tmp - now_tmp
seconds = 24 * 60 * 60 - home_offset.seconds + 1
text = "ahead of"
return "ยท [{hours:02}:{minutes:02} hs {text} home ๐ ]".format(
hours=seconds // 3600,
minutes=(seconds % 3600) // 60,
text=text,
)
def get_name_replacements(workflow):
sep = "//"
name_replacements = {}
for line in workflow.env.get("NAME_REPLACEMENTS", "").split("\n"):
if not line:
continue
if sep not in line:
raise ValueError(
f"name replacement '{line}' is missing the '{sep}' separator."
)
parts = line.split(sep)
if len(parts) != 2:
raise ValueError(
f"name replacement '{line}' should have the format `old {sep} new`."
)
if "" in parts:
raise ValueError(
f"name replacement '{line}' should have the format `old {sep} new`."
)
old, new = parts
name_replacements[old.strip()] = new.strip()
return name_replacements
def main(workflow):
total_seconds = 0
input = ''
if len(sys.argv) > 1:
arg = sys.argv[1]
input = ' ' + sys.argv[1]
total_seconds = add_time(arg)
home_tz, home_now = get_home(workflow)
timezones = get_timezones(workflow, home_tz)
formatter = get_formatter(workflow)
name_replacements = get_name_replacements(workflow)
sorter = lambda pair: pair[1].isoformat()
for timezone, now in sorted(timezones.items(), key=sorter):
location = timezone.split("/")[-1].replace("_", " ")
location = name_replacements.get(location, location)
home_offset_str = get_home_offset_str(timezone, home_tz, now, home_now) + get_utc(timezone, now, home_tz)
#here the arg is added to the now...
now += timedelta(seconds=total_seconds)
workflow.new_item(
title=formatter(now) + input,
subtitle="{flag} {location} {home_offset}".format(
flag=data.flags.get(timezone, "๐"),
location=location,
home_offset=home_offset_str,
),
arg=formatter(now) + get_utc(timezone, now, home_tz),
copytext=formatter(now),
valid=True,
uid=str(uuid4()),
).set_icon_file(
path=get_icon(timezone, now, home_tz),
).set_alt_mod(
subtitle="Copy ISO format (with microseconds)",
arg=formatters.iso8601(now),
).set_cmd_mod(
subtitle="Copy ISO format (without microseconds)",
arg=formatters.iso8601_without_microseconds(now),
)
if __name__ == "__main__":
wf = Workflow()
wf.run(main)
wf.send_feedback()
sys.exit()
Hi,
Would it be possible to use the computer's preferred date/time format option for the date/time display. Right now I have my computer set to use AM/PM and not 24-hour time, but the display is always in 24 hour time.
Thanks,
Allan
What am I missing? I found no TZ for China or India. I was expecting Beijing and Delhi as a minimum.
It would be helpful to have some build instructions.
As a very experienced python user, but a newbie to poetry and a newbie to Alfred, I wasn't able to figure out how to get the build working.
As-is, cloning the repo and running ./build.sh
fails because it is looking for a .venv
(which doesn't exist on my machine). Maybe there is some poetry
magic that needs to be run first to set up the virtual environment, but I haven't used poetry before (and I usually use conda instead of venv, so I don't know my way around venv very well either).
Thanks!
Hello @fedecalendino
I have installed and configured alfred-world-clock per instructions, but when I launch via the keyword in Alfred 5 it briefly shows World Clock - Calculating times... at the top of the results list but then quickly disappears without producing any results. Any idea how I can fix this?
I haven't modified anything and downloaded directly into Alfred via the Gallery.
A great workflow and I'm keen to see it in action!
Thanks
Id like to have the am/pm lowercase
i tried to change it to %P to make it lowercase in the formatters but it seems to not work.
Is this possible?
I think maybe you are missing Denmark?
Thanks!
I was looking through the code a bit, and was wondering if there would be an easy way to add a space in the config for setting a "Friendly name" for home. I find when i type "now" it always takes me a second to remember that my home and the city i have as home in this tool are different.
If you have any suggestions where to start implementing this I could shape up a PR. I've been looking for a reason to get reacquainted with Alfred workflows now that all the cool config features have been added.
I work for different timezones one feature I find useful is to know how much ahead or behind I am.
It would be great if we can set a "Home" timezone so, on top of the information you already provide you can give the offset (i.e. 5h behind, 2h ahead, etc.).
Thanks, great workflow.
Release 1.8.2 does not include the packaged workflow for download.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.