clox 1.1__py3-none-any.whl → 1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of clox might be problematic. Click here for more details.

clox/functions.py CHANGED
@@ -14,7 +14,7 @@ from art import tprint
14
14
  from .jcalendar import TextCalendar as JalaliCalendar
15
15
  from .params import HORIZONTAL_TIME_24H_FORMATS, VERTICAL_TIME_24H_FORMATS
16
16
  from .params import HORIZONTAL_TIME_12H_FORMATS, VERTICAL_TIME_12H_FORMATS
17
- from .params import TIMEZONE_DIFFERENCE_FORMAT
17
+ from .params import TIMEZONE_DIFFERENCE_FORMAT, OFFSET_FORMAT
18
18
  from .params import CLOX_VERSION
19
19
  from .params import TIMEZONES_LIST, COUNTRIES_LIST, WEEKDAYS_LIST
20
20
  from .params import ADDITIONAL_INFO, EXIT_MESSAGE
@@ -24,8 +24,8 @@ from .params import CLOX_OVERVIEW, CLOX_REPO
24
24
  from .params import DATE_FORMATS_MAP, DATE_FORMATS_LIST
25
25
 
26
26
 
27
- def clox_info() -> None:
28
- """Print clox details."""
27
+ def print_clox_info() -> None:
28
+ """Print clox info."""
29
29
  tprint("Clox")
30
30
  tprint("V:" + CLOX_VERSION)
31
31
  print(CLOX_OVERVIEW)
@@ -51,16 +51,18 @@ def get_face(index: int) -> str:
51
51
  return FACES_MAP[index]
52
52
 
53
53
 
54
- def get_timezone_difference(timezone: str) -> str:
54
+ def get_timezone_difference(timezone: str, offset_local: float, offset_timezone: float) -> str:
55
55
  """
56
56
  Return timezone difference.
57
57
 
58
58
  :param timezone: timezone
59
+ :param offset_local: manual offset for the local time
60
+ :param offset_timezone: manual offset for the timezone
59
61
  """
60
62
  direction = "ahead"
61
63
  tz = pytz.timezone(timezone)
62
- datetime_timezone = datetime.datetime.now(tz=tz)
63
- datetime_local = datetime.datetime.now()
64
+ datetime_timezone = datetime.datetime.now(tz=tz) + datetime.timedelta(hours=offset_timezone)
65
+ datetime_local = datetime.datetime.now() + datetime.timedelta(hours=offset_local)
64
66
  difference = datetime_timezone - tz.localize(datetime_local)
65
67
  total_minutes = difference.total_seconds() // 60
66
68
  if total_minutes < 0:
@@ -144,7 +146,7 @@ def show_date_formats_list(date_system: str = "GREGORIAN") -> None:
144
146
  date_format_code=date_format, date_format_example=example_date.strftime(DATE_FORMATS_MAP[date_format])))
145
147
 
146
148
 
147
- def _get_weekday_id(first_weekday: str, date_system: str = "GREGORIAN") -> int:
149
+ def get_weekday_id(first_weekday: str, date_system: str = "GREGORIAN") -> int:
148
150
  """
149
151
  Get weekday id.
150
152
 
@@ -168,7 +170,9 @@ def print_calendar(
168
170
  h_shift: int = 0,
169
171
  date_system: str = "GREGORIAN",
170
172
  date_format: str = "FULL",
171
- first_weekday: str = "MONDAY") -> None:
173
+ first_weekday: str = "MONDAY",
174
+ offset_local: float = 0,
175
+ offset_timezone: float = 0) -> None:
172
176
  """
173
177
  Print calendar.
174
178
 
@@ -180,31 +184,45 @@ def print_calendar(
180
184
  :param date_system: date system
181
185
  :param date_format: date format
182
186
  :param first_weekday: first weekday
187
+ :param offset_local: manual offset for the local time
188
+ :param offset_timezone: manual offset for the timezone
183
189
  """
184
- first_weekday_id = _get_weekday_id(first_weekday, date_system)
190
+ first_weekday_id = get_weekday_id(first_weekday, date_system)
185
191
  datetime_lib = datetime
186
192
  calendar_obj = GregorianCalendar(first_weekday_id)
187
193
  if date_system == "JALALI":
188
194
  datetime_lib = jdatetime
189
195
  calendar_obj = JalaliCalendar(first_weekday_id)
196
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_local)
190
197
  tz = None
191
198
  timezone_str = "Local"
192
199
  if country is not None:
193
200
  timezone = pytz.country_timezones(country)[0].upper()
194
201
  if timezone is not None:
195
202
  timezone_str = timezone
196
- timezone_diff = get_timezone_difference(timezone=timezone)
203
+ timezone_diff = get_timezone_difference(
204
+ timezone=timezone,
205
+ offset_local=offset_local,
206
+ offset_timezone=offset_timezone)
197
207
  timezone_str += " ({timezone_diff})".format(timezone_diff=timezone_diff)
198
208
  tz = pytz.timezone(timezone)
209
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_timezone)
199
210
  v_shift = max(0, v_shift)
200
211
  h_shift = max(0, h_shift)
201
- datetime_timezone = datetime_lib.datetime.now(tz=tz)
212
+ datetime_timezone = datetime_lib.datetime.now(tz=tz) + offset_main_timedelta
202
213
  date_timezone_str = datetime_timezone.strftime(DATE_FORMATS_MAP[date_format])
203
214
  print('\n' * v_shift, end='')
204
215
  print(" " * h_shift, end='')
205
216
  print("Today: {date}".format(date=date_timezone_str))
206
217
  print(" " * h_shift, end='')
207
- print("Timezone: {timezone}\n".format(timezone=timezone_str))
218
+ print("Timezone: {timezone}".format(timezone=timezone_str))
219
+ if offset_timezone != 0:
220
+ print(" " * h_shift, end='')
221
+ print(OFFSET_FORMAT.format(offset_type="Timezone", offset_value=offset_timezone))
222
+ if offset_local != 0:
223
+ print(" " * h_shift, end='')
224
+ print(OFFSET_FORMAT.format(offset_type="Local", offset_value=offset_local))
225
+ print("")
208
226
  calendar_str = calendar_obj.formatmonth(datetime_timezone.year, datetime_timezone.month)
209
227
  if mode == "YEAR":
210
228
  calendar_str = calendar_obj.formatyear(datetime_timezone.year)
@@ -223,7 +241,9 @@ def run_clock(
223
241
  hide_timezone: bool = False,
224
242
  am_pm: bool = False,
225
243
  date_system: str = "GREGORIAN",
226
- date_format: str = "FULL") -> None:
244
+ date_format: str = "FULL",
245
+ offset_local: float = 0,
246
+ offset_timezone: float = 0) -> None:
227
247
  """
228
248
  Run clock.
229
249
 
@@ -239,6 +259,8 @@ def run_clock(
239
259
  :param am_pm: AM/PM mode flag
240
260
  :param date_system: date system
241
261
  :param date_format: date format
262
+ :param offset_local: manual offset for the local time
263
+ :param offset_timezone: manual offset for the timezone
242
264
  """
243
265
  datetime_lib = datetime
244
266
  if date_system == "JALALI":
@@ -250,13 +272,19 @@ def run_clock(
250
272
  time_formats = VERTICAL_TIME_12H_FORMATS if am_pm else VERTICAL_TIME_24H_FORMATS
251
273
  tz = None
252
274
  timezone_str = "Local"
275
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_local)
276
+ offset_local_timedelta = datetime.timedelta(hours=offset_local)
253
277
  if country is not None:
254
278
  timezone = pytz.country_timezones(country)[0].upper()
255
279
  if timezone is not None:
256
280
  timezone_str = timezone
257
- timezone_diff = get_timezone_difference(timezone=timezone)
281
+ timezone_diff = get_timezone_difference(
282
+ timezone=timezone,
283
+ offset_local=offset_local,
284
+ offset_timezone=offset_timezone)
258
285
  timezone_str += " ({timezone_diff})".format(timezone_diff=timezone_diff)
259
286
  tz = pytz.timezone(timezone)
287
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_timezone)
260
288
  v_shift = max(0, v_shift)
261
289
  h_shift = max(0, h_shift)
262
290
  face = get_face(face)
@@ -264,7 +292,7 @@ def run_clock(
264
292
  clear_screen()
265
293
  print('\n' * v_shift, end='')
266
294
  print(" " * h_shift, end='')
267
- datetime_timezone = datetime_lib.datetime.now(tz=tz)
295
+ datetime_timezone = datetime_lib.datetime.now(tz=tz) + offset_main_timedelta
268
296
  time_timezone_str = datetime_timezone.strftime(time_formats[format_index])
269
297
  date_timezone_str = datetime_timezone.strftime(DATE_FORMATS_MAP[date_format])
270
298
  tprint(time_timezone_str, font=face, sep="\n" + " " * h_shift)
@@ -274,11 +302,17 @@ def run_clock(
274
302
  if not hide_timezone:
275
303
  print(" " * h_shift, end='')
276
304
  print("Timezone: {timezone}".format(timezone=timezone_str))
305
+ if offset_timezone != 0:
306
+ print(" " * h_shift, end='')
307
+ print(OFFSET_FORMAT.format(offset_type="Timezone", offset_value=offset_timezone))
277
308
  if timezone is not None:
278
- datetime_local = datetime.datetime.now()
309
+ datetime_local = datetime.datetime.now() + offset_local_timedelta
279
310
  time_local_str = datetime_local.strftime(time_formats_local[format_index])
280
311
  print(" " * h_shift, end='')
281
312
  print("Local Time: {local_time}".format(local_time=time_local_str))
313
+ if offset_local != 0:
314
+ print(" " * h_shift, end='')
315
+ print(OFFSET_FORMAT.format(offset_type="Local", offset_value=offset_local))
282
316
  time.sleep(1)
283
317
  if not no_blink:
284
318
  format_index = int(not format_index)
@@ -314,11 +348,13 @@ def main() -> None:
314
348
  type=str.upper,
315
349
  choices=DATE_SYSTEMS_LIST,
316
350
  default="GREGORIAN")
351
+ parser.add_argument('--offset-local', help='manual offset for the local time (in hours)', type=float, default=0)
352
+ parser.add_argument('--offset-timezone', help='manual offset for the timezone (in hours)', type=float, default=0)
317
353
  args = parser.parse_args()
318
354
  if args.version:
319
355
  print(CLOX_VERSION)
320
356
  elif args.info:
321
- clox_info()
357
+ print_clox_info()
322
358
  elif args.faces_list:
323
359
  show_faces_list(vertical=args.vertical)
324
360
  elif args.timezones_list:
@@ -336,7 +372,9 @@ def main() -> None:
336
372
  v_shift=args.v_shift,
337
373
  date_system=args.date_system,
338
374
  date_format=args.date_format,
339
- first_weekday=args.first_weekday)
375
+ first_weekday=args.first_weekday,
376
+ offset_local=args.offset_local,
377
+ offset_timezone=args.offset_timezone)
340
378
  else:
341
379
  try:
342
380
  run_clock(
@@ -351,6 +389,8 @@ def main() -> None:
351
389
  hide_timezone=args.hide_timezone,
352
390
  am_pm=args.am_pm,
353
391
  date_system=args.date_system,
354
- date_format=args.date_format)
392
+ date_format=args.date_format,
393
+ offset_local=args.offset_local,
394
+ offset_timezone=args.offset_timezone)
355
395
  except (KeyboardInterrupt, EOFError):
356
396
  print(EXIT_MESSAGE)
clox/params.py CHANGED
@@ -2,7 +2,7 @@
2
2
  """clox params."""
3
3
  import pytz
4
4
 
5
- CLOX_VERSION = "1.1"
5
+ CLOX_VERSION = "1.2"
6
6
 
7
7
  CLOX_OVERVIEW = '''
8
8
  Clox is a terminal-based clock application designed for terminal enthusiasts who appreciate simplicity,
@@ -23,6 +23,7 @@ VERTICAL_TIME_24H_FORMATS = ['%H\n%M', '%H\n%M.']
23
23
  HORIZONTAL_TIME_12H_FORMATS = ['%I:%M %p', '%I:%M %p.']
24
24
  VERTICAL_TIME_12H_FORMATS = ['%I\n%M\n%p', '%I\n%M\n%p.']
25
25
  TIMEZONE_DIFFERENCE_FORMAT = "{hours:02}h{minutes:02}m {direction}"
26
+ OFFSET_FORMAT = "{offset_type} Offset: {offset_value:g}h"
26
27
 
27
28
  WEEKDAYS_LIST = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]
28
29
  TIMEZONES_LIST = list(map(lambda x: x.upper(), pytz.all_timezones))
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clox
3
- Version: 1.1
3
+ Version: 1.2
4
4
  Summary: A Geeky Clock for Terminal Enthusiasts
5
5
  Home-page: https://github.com/sepandhaghighi/clox
6
- Download-URL: https://github.com/sepandhaghighi/clox/tarball/v1.1
6
+ Download-URL: https://github.com/sepandhaghighi/clox/tarball/v1.2
7
7
  Author: Sepand Haghighi
8
8
  Author-email: me@sepand.tech
9
9
  License: MIT
@@ -96,7 +96,6 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
96
96
  <td align="center">Code Quality</td>
97
97
  <td align="center"><a href="https://www.codefactor.io/repository/github/sepandhaghighi/clox"><img src="https://www.codefactor.io/repository/github/sepandhaghighi/clox/badge" alt="CodeFactor"></a></td>
98
98
  <td align="center"><a href="https://app.codacy.com/gh/sepandhaghighi/clox/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/4cd4cd3b20b1474fb674823b1b417b76"></a></td>
99
- <td align="center"><a href="https://codebeat.co/projects/github-com-sepandhaghighi-clox-main"><img alt="codebeat badge" src="https://codebeat.co/badges/19394d3a-009b-401b-b376-24a325ef2fdf"></a></td>
100
99
  </tr>
101
100
  </table>
102
101
 
@@ -104,13 +103,13 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
104
103
  ## Installation
105
104
 
106
105
  ### Source Code
107
- - Download [Version 1.1](https://github.com/sepandhaghighi/clox/archive/v1.1.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
106
+ - Download [Version 1.2](https://github.com/sepandhaghighi/clox/archive/v1.2.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
108
107
  - `pip install .`
109
108
 
110
109
  ### PyPI
111
110
 
112
111
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
113
- - `pip install clox==1.1`
112
+ - `pip install clox==1.2`
114
113
 
115
114
 
116
115
  ## Usage
@@ -154,6 +153,16 @@ clox --timezone="Etc/GMT+7"
154
153
  * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md): `clox --timezones-list`
155
154
 
156
155
 
156
+ ### Manual Offset
157
+
158
+ ℹ️ The local and timezone offset both have default values of `0`
159
+
160
+ These arguments allow you to manually adjust the time by ±X hours. This is especially useful when daylight saving time (DST) is not correctly applied by the system or timezone database.
161
+
162
+ ```console
163
+ clox --offset-local=1 --offset-timezone=-1
164
+ ```
165
+
157
166
  ### Country
158
167
 
159
168
  The `--country` argument allows you to specify a country using its **ISO 3166** code format
@@ -303,6 +312,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
303
312
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
304
313
 
305
314
  ## [Unreleased]
315
+ ## [1.2] - 2025-09-02
316
+ ### Added
317
+ - `--offset-local` argument
318
+ - `--offset-timezone` argument
319
+ ### Changed
320
+ - `README.md` updated
321
+ - Test system modified
322
+ - `_get_weekday_id` function renamed to `get_weekday_id`
323
+ - `clox_info` function renamed to `print_clox_info`
306
324
  ## [1.1] - 2025-05-23
307
325
  ### Added
308
326
  - `--first-weekday` argument
@@ -377,7 +395,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
377
395
  - `TIMEZONES.md`
378
396
  - `FACES.md`
379
397
 
380
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.1...dev
398
+ [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.2...dev
399
+ [1.2]: https://github.com/sepandhaghighi/clox/compare/v1.1...v1.2
381
400
  [1.1]: https://github.com/sepandhaghighi/clox/compare/v1.0...v1.1
382
401
  [1.0]: https://github.com/sepandhaghighi/clox/compare/v0.9...v1.0
383
402
  [0.9]: https://github.com/sepandhaghighi/clox/compare/v0.8...v0.9
@@ -0,0 +1,12 @@
1
+ clox/__init__.py,sha256=gErclFSjUDschQpngWqOBGkBKt1jwd-Ww8B9iJmlU5s,108
2
+ clox/__main__.py,sha256=9oJYc1WXu4ZMrjKny_2-4Cgu46-VWHuE9xOqD1iJY0E,109
3
+ clox/functions.py,sha256=aSYoZdmM3TGX4nPVMnbH9RkrB0uql-MPNOaZmY4BgCo,15978
4
+ clox/jcalendar.py,sha256=RvtTikECGI4LjDSi5qbJF9grz7to2__fgR98xnnvme8,13462
5
+ clox/params.py,sha256=vBtlat47gc9C9M9RIwu8yugdCQ35ObBPdqwSTwDMp_A,2176
6
+ clox-1.2.dist-info/licenses/AUTHORS.md,sha256=lmtnd18MnfgB57jdvfJbC0JHN3iARf2Ov4pY5kPGJC8,242
7
+ clox-1.2.dist-info/licenses/LICENSE,sha256=WoAsqqZ_lNVBGdyxjwh7YnVNXKfOB-qYVrRhrn-e-_4,1072
8
+ clox-1.2.dist-info/METADATA,sha256=_zZIpzNgZkRFqdDhjSEtonDORLGkuET9xkwNx_AWneU,10916
9
+ clox-1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ clox-1.2.dist-info/entry_points.txt,sha256=sP4Rmoe-DxYGjlF_Tld6nghbt_u-fK8h9ZUQFmO8TJs,45
11
+ clox-1.2.dist-info/top_level.txt,sha256=5DxGH-4VNfYkM8vbfngObh6-jpFEoSW4M90EvDGfhSw,5
12
+ clox-1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
clox-1.1.dist-info/RECORD DELETED
@@ -1,12 +0,0 @@
1
- clox/__init__.py,sha256=gErclFSjUDschQpngWqOBGkBKt1jwd-Ww8B9iJmlU5s,108
2
- clox/__main__.py,sha256=9oJYc1WXu4ZMrjKny_2-4Cgu46-VWHuE9xOqD1iJY0E,109
3
- clox/functions.py,sha256=-tJtvWZBtYmh2qlNe_Y7KYZJXwo3nUzgVYwHe_mnbmc,13607
4
- clox/jcalendar.py,sha256=RvtTikECGI4LjDSi5qbJF9grz7to2__fgR98xnnvme8,13462
5
- clox/params.py,sha256=JH8NEjXDUoHKCLCVtfjog5DR-iqVPxUsGJPZYcNeWL4,2118
6
- clox-1.1.dist-info/licenses/AUTHORS.md,sha256=lmtnd18MnfgB57jdvfJbC0JHN3iARf2Ov4pY5kPGJC8,242
7
- clox-1.1.dist-info/licenses/LICENSE,sha256=WoAsqqZ_lNVBGdyxjwh7YnVNXKfOB-qYVrRhrn-e-_4,1072
8
- clox-1.1.dist-info/METADATA,sha256=qmV3t6v2pJmTIUppwLi-XhVJud_bHvkgmjJL2H5pdsQ,10459
9
- clox-1.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
10
- clox-1.1.dist-info/entry_points.txt,sha256=sP4Rmoe-DxYGjlF_Tld6nghbt_u-fK8h9ZUQFmO8TJs,45
11
- clox-1.1.dist-info/top_level.txt,sha256=5DxGH-4VNfYkM8vbfngObh6-jpFEoSW4M90EvDGfhSw,5
12
- clox-1.1.dist-info/RECORD,,
File without changes