clox 1.0__tar.gz → 1.2__tar.gz

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.

@@ -5,6 +5,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ ## [1.2] - 2025-09-02
9
+ ### Added
10
+ - `--offset-local` argument
11
+ - `--offset-timezone` argument
12
+ ### Changed
13
+ - `README.md` updated
14
+ - Test system modified
15
+ - `_get_weekday_id` function renamed to `get_weekday_id`
16
+ - `clox_info` function renamed to `print_clox_info`
17
+ ## [1.1] - 2025-05-23
18
+ ### Added
19
+ - `--first-weekday` argument
20
+ - `--date-format` argument
21
+ - `--date-formats-list` argument
22
+ ### Changed
23
+ - `README.md` updated
24
+ - Test system modified
8
25
  ## [1.0] - 2025-05-06
9
26
  ### Added
10
27
  - Local time
@@ -71,7 +88,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
71
88
  - `TIMEZONES.md`
72
89
  - `FACES.md`
73
90
 
74
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.0...dev
91
+ [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.2...dev
92
+ [1.2]: https://github.com/sepandhaghighi/clox/compare/v1.1...v1.2
93
+ [1.1]: https://github.com/sepandhaghighi/clox/compare/v1.0...v1.1
75
94
  [1.0]: https://github.com/sepandhaghighi/clox/compare/v0.9...v1.0
76
95
  [0.9]: https://github.com/sepandhaghighi/clox/compare/v0.8...v0.9
77
96
  [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clox
3
- Version: 1.0
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.0
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.0](https://github.com/sepandhaghighi/clox/archive/v1.0.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.0`
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
@@ -218,22 +227,33 @@ clox --vertical
218
227
 
219
228
  In this mode, the calendar will be displayed
220
229
 
221
- ℹ️ Valid choices: [`month`, `year`]
230
+ ℹ️ Valid choices: [`MONTH`, `YEAR`]
222
231
 
223
232
  ```console
224
- clox --calendar=month
233
+ clox --calendar=month --first-weekday="SUNDAY"
225
234
  ```
226
235
 
227
236
  ### Date System
228
237
 
229
- ℹ️ Valid choices: [`gregorian`, `jalali`]
238
+ ℹ️ Valid choices: [`GREGORIAN`, `JALALI`]
230
239
 
231
- ℹ️ The default date system is `gregorian`
240
+ ℹ️ The default date system is `GREGORIAN`
232
241
 
233
242
  ```console
234
243
  clox --date-system=jalali
235
244
  ```
236
245
 
246
+ ### Date Format
247
+
248
+ ℹ️ Valid choices: [`ISO`, `US`, `US-SHORT`, `EU`, `EU-SHORT`, `DOT`, `DASH`, `YMD`, `DMY`, `MDY`, `FULL`]
249
+
250
+ ℹ️ The default date format is `FULL`
251
+
252
+ ```console
253
+ clox --date-system=jalali --date-format=EU
254
+ ```
255
+ * Date Formats List: `clox --date-formats-list`
256
+
237
257
  ## Screen Record
238
258
 
239
259
  <div align="center">
@@ -292,6 +312,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
292
312
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
293
313
 
294
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`
324
+ ## [1.1] - 2025-05-23
325
+ ### Added
326
+ - `--first-weekday` argument
327
+ - `--date-format` argument
328
+ - `--date-formats-list` argument
329
+ ### Changed
330
+ - `README.md` updated
331
+ - Test system modified
295
332
  ## [1.0] - 2025-05-06
296
333
  ### Added
297
334
  - Local time
@@ -358,7 +395,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
358
395
  - `TIMEZONES.md`
359
396
  - `FACES.md`
360
397
 
361
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.0...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
400
+ [1.1]: https://github.com/sepandhaghighi/clox/compare/v1.0...v1.1
362
401
  [1.0]: https://github.com/sepandhaghighi/clox/compare/v0.9...v1.0
363
402
  [0.9]: https://github.com/sepandhaghighi/clox/compare/v0.8...v0.9
364
403
  [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
@@ -45,7 +45,6 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
45
45
  <td align="center">Code Quality</td>
46
46
  <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>
47
47
  <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>
48
- <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>
49
48
  </tr>
50
49
  </table>
51
50
 
@@ -53,13 +52,13 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
53
52
  ## Installation
54
53
 
55
54
  ### Source Code
56
- - Download [Version 1.0](https://github.com/sepandhaghighi/clox/archive/v1.0.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
55
+ - Download [Version 1.2](https://github.com/sepandhaghighi/clox/archive/v1.2.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
57
56
  - `pip install .`
58
57
 
59
58
  ### PyPI
60
59
 
61
60
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
62
- - `pip install clox==1.0`
61
+ - `pip install clox==1.2`
63
62
 
64
63
 
65
64
  ## Usage
@@ -103,6 +102,16 @@ clox --timezone="Etc/GMT+7"
103
102
  * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md): `clox --timezones-list`
104
103
 
105
104
 
105
+ ### Manual Offset
106
+
107
+ ℹ️ The local and timezone offset both have default values of `0`
108
+
109
+ 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.
110
+
111
+ ```console
112
+ clox --offset-local=1 --offset-timezone=-1
113
+ ```
114
+
106
115
  ### Country
107
116
 
108
117
  The `--country` argument allows you to specify a country using its **ISO 3166** code format
@@ -167,22 +176,33 @@ clox --vertical
167
176
 
168
177
  In this mode, the calendar will be displayed
169
178
 
170
- ℹ️ Valid choices: [`month`, `year`]
179
+ ℹ️ Valid choices: [`MONTH`, `YEAR`]
171
180
 
172
181
  ```console
173
- clox --calendar=month
182
+ clox --calendar=month --first-weekday="SUNDAY"
174
183
  ```
175
184
 
176
185
  ### Date System
177
186
 
178
- ℹ️ Valid choices: [`gregorian`, `jalali`]
187
+ ℹ️ Valid choices: [`GREGORIAN`, `JALALI`]
179
188
 
180
- ℹ️ The default date system is `gregorian`
189
+ ℹ️ The default date system is `GREGORIAN`
181
190
 
182
191
  ```console
183
192
  clox --date-system=jalali
184
193
  ```
185
194
 
195
+ ### Date Format
196
+
197
+ ℹ️ Valid choices: [`ISO`, `US`, `US-SHORT`, `EU`, `EU-SHORT`, `DOT`, `DASH`, `YMD`, `DMY`, `MDY`, `FULL`]
198
+
199
+ ℹ️ The default date format is `FULL`
200
+
201
+ ```console
202
+ clox --date-system=jalali --date-format=EU
203
+ ```
204
+ * Date Formats List: `clox --date-formats-list`
205
+
186
206
  ## Screen Record
187
207
 
188
208
  <div align="center">
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | ------------- | ------------------ |
7
- | 1.0 | :white_check_mark: |
8
- | < 1.0 | :x: |
7
+ | 1.2 | :white_check_mark: |
8
+ | < 1.2 | :x: |
9
9
 
10
10
  ## Reporting a Vulnerability
11
11
 
@@ -14,17 +14,18 @@ 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
18
- from .params import CLOX_VERSION, DATE_FORMAT
19
- from .params import TIMEZONES_LIST, COUNTRIES_LIST
17
+ from .params import TIMEZONE_DIFFERENCE_FORMAT, OFFSET_FORMAT
18
+ from .params import CLOX_VERSION
19
+ from .params import TIMEZONES_LIST, COUNTRIES_LIST, WEEKDAYS_LIST
20
20
  from .params import ADDITIONAL_INFO, EXIT_MESSAGE
21
21
  from .params import FACES_MAP, FACES_LIST, CALENDARS_LIST, DATE_SYSTEMS_LIST
22
22
  from .params import HORIZONTAL_FACES_LIST_EXAMPLE, VERTICAL_FACES_LIST_EXAMPLE
23
23
  from .params import CLOX_OVERVIEW, CLOX_REPO
24
+ from .params import DATE_FORMATS_MAP, DATE_FORMATS_LIST
24
25
 
25
26
 
26
- def clox_info() -> None:
27
- """Print clox details."""
27
+ def print_clox_info() -> None:
28
+ """Print clox info."""
28
29
  tprint("Clox")
29
30
  tprint("V:" + CLOX_VERSION)
30
31
  print(CLOX_OVERVIEW)
@@ -50,16 +51,18 @@ def get_face(index: int) -> str:
50
51
  return FACES_MAP[index]
51
52
 
52
53
 
53
- def get_timezone_difference(timezone: str) -> str:
54
+ def get_timezone_difference(timezone: str, offset_local: float, offset_timezone: float) -> str:
54
55
  """
55
56
  Return timezone difference.
56
57
 
57
58
  :param timezone: timezone
59
+ :param offset_local: manual offset for the local time
60
+ :param offset_timezone: manual offset for the timezone
58
61
  """
59
62
  direction = "ahead"
60
63
  tz = pytz.timezone(timezone)
61
- datetime_timezone = datetime.datetime.now(tz=tz)
62
- 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)
63
66
  difference = datetime_timezone - tz.localize(datetime_local)
64
67
  total_minutes = difference.total_seconds() // 60
65
68
  if total_minutes < 0:
@@ -125,13 +128,51 @@ def show_countries_list() -> None:
125
128
  country_code=country_code, country_name=country_code))
126
129
 
127
130
 
131
+ def show_date_formats_list(date_system: str = "GREGORIAN") -> None:
132
+ """
133
+ Show date formats list.
134
+
135
+ :param date_system: date system
136
+ """
137
+ datetime_lib = datetime
138
+ example_year = 1990
139
+ if date_system == "JALALI":
140
+ datetime_lib = jdatetime
141
+ example_year = 1368
142
+ print("Date formats list:\n")
143
+ example_date = datetime_lib.datetime(year=example_year, month=7, day=23)
144
+ for index, date_format in enumerate(DATE_FORMATS_LIST, 1):
145
+ print("{index}. {date_format_code} - {date_format_example}".format(index=index,
146
+ date_format_code=date_format, date_format_example=example_date.strftime(DATE_FORMATS_MAP[date_format])))
147
+
148
+
149
+ def get_weekday_id(first_weekday: str, date_system: str = "GREGORIAN") -> int:
150
+ """
151
+ Get weekday id.
152
+
153
+ :param first_weekday: first weekday
154
+ :param date_system: date system
155
+ """
156
+ first_weekday_normalized = first_weekday.upper()
157
+ if len(first_weekday) > 2:
158
+ first_weekday_normalized = first_weekday_normalized[:2]
159
+ weekdays = [x[:2] for x in WEEKDAYS_LIST]
160
+ if date_system == "JALALI":
161
+ weekdays = weekdays[-2:] + weekdays[:-2]
162
+ return weekdays.index(first_weekday_normalized)
163
+
164
+
128
165
  def print_calendar(
129
- mode: str = "month",
166
+ mode: str = "MONTH",
130
167
  timezone: Optional[str] = None,
131
168
  country: Optional[str] = None,
132
169
  v_shift: int = 0,
133
170
  h_shift: int = 0,
134
- date_system: str = "gregorian") -> None:
171
+ date_system: str = "GREGORIAN",
172
+ date_format: str = "FULL",
173
+ first_weekday: str = "MONDAY",
174
+ offset_local: float = 0,
175
+ offset_timezone: float = 0) -> None:
135
176
  """
136
177
  Print calendar.
137
178
 
@@ -141,32 +182,49 @@ def print_calendar(
141
182
  :param v_shift: vertical shift
142
183
  :param h_shift: horizontal shift
143
184
  :param date_system: date system
185
+ :param date_format: date format
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
144
189
  """
190
+ first_weekday_id = get_weekday_id(first_weekday, date_system)
145
191
  datetime_lib = datetime
146
- calendar_obj = GregorianCalendar()
147
- if date_system == "jalali":
192
+ calendar_obj = GregorianCalendar(first_weekday_id)
193
+ if date_system == "JALALI":
148
194
  datetime_lib = jdatetime
149
- calendar_obj = JalaliCalendar()
195
+ calendar_obj = JalaliCalendar(first_weekday_id)
196
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_local)
150
197
  tz = None
151
198
  timezone_str = "Local"
152
199
  if country is not None:
153
200
  timezone = pytz.country_timezones(country)[0].upper()
154
201
  if timezone is not None:
155
202
  timezone_str = timezone
156
- 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)
157
207
  timezone_str += " ({timezone_diff})".format(timezone_diff=timezone_diff)
158
208
  tz = pytz.timezone(timezone)
209
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_timezone)
159
210
  v_shift = max(0, v_shift)
160
211
  h_shift = max(0, h_shift)
161
- datetime_timezone = datetime_lib.datetime.now(tz=tz)
162
- date_timezone_str = datetime_timezone.strftime(DATE_FORMAT)
212
+ datetime_timezone = datetime_lib.datetime.now(tz=tz) + offset_main_timedelta
213
+ date_timezone_str = datetime_timezone.strftime(DATE_FORMATS_MAP[date_format])
163
214
  print('\n' * v_shift, end='')
164
215
  print(" " * h_shift, end='')
165
216
  print("Today: {date}".format(date=date_timezone_str))
166
217
  print(" " * h_shift, end='')
167
- 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("")
168
226
  calendar_str = calendar_obj.formatmonth(datetime_timezone.year, datetime_timezone.month)
169
- if mode == "year":
227
+ if mode == "YEAR":
170
228
  calendar_str = calendar_obj.formatyear(datetime_timezone.year)
171
229
  print("\n".join([" " * h_shift + x for x in calendar_str.split("\n")]))
172
230
 
@@ -182,7 +240,10 @@ def run_clock(
182
240
  hide_date: bool = False,
183
241
  hide_timezone: bool = False,
184
242
  am_pm: bool = False,
185
- date_system: str = "gregorian") -> None:
243
+ date_system: str = "GREGORIAN",
244
+ date_format: str = "FULL",
245
+ offset_local: float = 0,
246
+ offset_timezone: float = 0) -> None:
186
247
  """
187
248
  Run clock.
188
249
 
@@ -197,9 +258,12 @@ def run_clock(
197
258
  :param hide_timezone: hide timezone flag
198
259
  :param am_pm: AM/PM mode flag
199
260
  :param date_system: date system
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
200
264
  """
201
265
  datetime_lib = datetime
202
- if date_system == "jalali":
266
+ if date_system == "JALALI":
203
267
  datetime_lib = jdatetime
204
268
  format_index = 0
205
269
  time_formats = HORIZONTAL_TIME_12H_FORMATS if am_pm else HORIZONTAL_TIME_24H_FORMATS
@@ -208,13 +272,19 @@ def run_clock(
208
272
  time_formats = VERTICAL_TIME_12H_FORMATS if am_pm else VERTICAL_TIME_24H_FORMATS
209
273
  tz = None
210
274
  timezone_str = "Local"
275
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_local)
276
+ offset_local_timedelta = datetime.timedelta(hours=offset_local)
211
277
  if country is not None:
212
278
  timezone = pytz.country_timezones(country)[0].upper()
213
279
  if timezone is not None:
214
280
  timezone_str = timezone
215
- 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)
216
285
  timezone_str += " ({timezone_diff})".format(timezone_diff=timezone_diff)
217
286
  tz = pytz.timezone(timezone)
287
+ offset_main_timedelta = datetime_lib.timedelta(hours=offset_timezone)
218
288
  v_shift = max(0, v_shift)
219
289
  h_shift = max(0, h_shift)
220
290
  face = get_face(face)
@@ -222,9 +292,9 @@ def run_clock(
222
292
  clear_screen()
223
293
  print('\n' * v_shift, end='')
224
294
  print(" " * h_shift, end='')
225
- datetime_timezone = datetime_lib.datetime.now(tz=tz)
295
+ datetime_timezone = datetime_lib.datetime.now(tz=tz) + offset_main_timedelta
226
296
  time_timezone_str = datetime_timezone.strftime(time_formats[format_index])
227
- date_timezone_str = datetime_timezone.strftime(DATE_FORMAT)
297
+ date_timezone_str = datetime_timezone.strftime(DATE_FORMATS_MAP[date_format])
228
298
  tprint(time_timezone_str, font=face, sep="\n" + " " * h_shift)
229
299
  if not hide_date:
230
300
  print(" " * h_shift, end='')
@@ -232,11 +302,17 @@ def run_clock(
232
302
  if not hide_timezone:
233
303
  print(" " * h_shift, end='')
234
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))
235
308
  if timezone is not None:
236
- datetime_local = datetime.datetime.now()
309
+ datetime_local = datetime.datetime.now() + offset_local_timedelta
237
310
  time_local_str = datetime_local.strftime(time_formats_local[format_index])
238
311
  print(" " * h_shift, end='')
239
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))
240
316
  time.sleep(1)
241
317
  if not no_blink:
242
318
  format_index = int(not format_index)
@@ -256,29 +332,37 @@ def main() -> None:
256
332
  parser.add_argument('--faces-list', help='faces list', nargs="?", const=1)
257
333
  parser.add_argument('--timezones-list', help='timezones list', nargs="?", const=1)
258
334
  parser.add_argument('--countries-list', help='countries list', nargs="?", const=1)
335
+ parser.add_argument('--date-formats-list', help='date formats list', nargs="?", const=1)
259
336
  parser.add_argument('--no-blink', help='disable blinking mode', nargs="?", const=1)
260
337
  parser.add_argument('--vertical', help='vertical mode', nargs="?", const=1)
261
338
  parser.add_argument('--hide-date', help='hide date', nargs="?", const=1)
262
339
  parser.add_argument('--hide-timezone', help='hide timezone', nargs="?", const=1)
263
340
  parser.add_argument('--am-pm', help='AM/PM mode', nargs="?", const=1)
264
- parser.add_argument('--calendar', help='calendar mode', type=str.lower, choices=CALENDARS_LIST)
341
+ parser.add_argument('--calendar', help='calendar mode', type=str.upper, choices=CALENDARS_LIST)
342
+ parser.add_argument('--first-weekday', help='first weekday', type=str.upper, default="MONDAY",
343
+ choices=WEEKDAYS_LIST + [x[:2] for x in WEEKDAYS_LIST])
344
+ parser.add_argument('--date-format', help='date format', type=str.upper, choices=DATE_FORMATS_LIST, default="FULL")
265
345
  parser.add_argument(
266
346
  '--date-system',
267
347
  help='date system',
268
- type=str.lower,
348
+ type=str.upper,
269
349
  choices=DATE_SYSTEMS_LIST,
270
- default="gregorian")
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)
271
353
  args = parser.parse_args()
272
354
  if args.version:
273
355
  print(CLOX_VERSION)
274
356
  elif args.info:
275
- clox_info()
357
+ print_clox_info()
276
358
  elif args.faces_list:
277
359
  show_faces_list(vertical=args.vertical)
278
360
  elif args.timezones_list:
279
361
  show_timezones_list(args.country)
280
362
  elif args.countries_list:
281
363
  show_countries_list()
364
+ elif args.date_formats_list:
365
+ show_date_formats_list(date_system=args.date_system)
282
366
  elif args.calendar:
283
367
  print_calendar(
284
368
  mode=args.calendar,
@@ -286,7 +370,11 @@ def main() -> None:
286
370
  country=args.country,
287
371
  h_shift=args.h_shift,
288
372
  v_shift=args.v_shift,
289
- date_system=args.date_system)
373
+ date_system=args.date_system,
374
+ date_format=args.date_format,
375
+ first_weekday=args.first_weekday,
376
+ offset_local=args.offset_local,
377
+ offset_timezone=args.offset_timezone)
290
378
  else:
291
379
  try:
292
380
  run_clock(
@@ -300,6 +388,9 @@ def main() -> None:
300
388
  hide_date=args.hide_date,
301
389
  hide_timezone=args.hide_timezone,
302
390
  am_pm=args.am_pm,
303
- date_system=args.date_system)
391
+ date_system=args.date_system,
392
+ date_format=args.date_format,
393
+ offset_local=args.offset_local,
394
+ offset_timezone=args.offset_timezone)
304
395
  except (KeyboardInterrupt, EOFError):
305
396
  print(EXIT_MESSAGE)
@@ -2,7 +2,7 @@
2
2
  """clox params."""
3
3
  import pytz
4
4
 
5
- CLOX_VERSION = "1.0"
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,
@@ -22,9 +22,10 @@ HORIZONTAL_TIME_24H_FORMATS = ['%H:%M', '%H:%M.']
22
22
  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
- DATE_FORMAT = "%A, %B %d, %Y"
26
25
  TIMEZONE_DIFFERENCE_FORMAT = "{hours:02}h{minutes:02}m {direction}"
26
+ OFFSET_FORMAT = "{offset_type} Offset: {offset_value:g}h"
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))
29
30
  COUNTRIES_LIST = list(map(lambda x: x.upper(), pytz.country_timezones.keys()))
30
31
 
@@ -57,8 +58,24 @@ FACES_MAP = {
57
58
  25: 'epic',
58
59
  }
59
60
 
61
+ DATE_FORMATS_MAP = {
62
+ 'ISO': '%Y-%m-%d',
63
+ 'US': '%m/%d/%Y',
64
+ 'US-SHORT': '%m/%d/%y',
65
+ 'EU': '%d/%m/%Y',
66
+ 'EU-SHORT': '%d/%m/%y',
67
+ 'DOT': '%d.%m.%Y',
68
+ 'DASH': '%d-%m-%Y',
69
+ 'YMD': '%Y/%m/%d',
70
+ 'DMY': '%d/%m/%Y',
71
+ 'MDY': '%m/%d/%Y',
72
+ 'FULL': '%A, %B %d, %Y',
73
+ }
74
+
60
75
  FACES_LIST = [-1] + sorted(FACES_MAP)
61
76
 
62
- CALENDARS_LIST = ["month", "year"]
77
+ CALENDARS_LIST = ["MONTH", "YEAR"]
78
+
79
+ DATE_SYSTEMS_LIST = ["GREGORIAN", "JALALI"]
63
80
 
64
- DATE_SYSTEMS_LIST = ["gregorian", "jalali"]
81
+ DATE_FORMATS_LIST = sorted(DATE_FORMATS_MAP)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clox
3
- Version: 1.0
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.0
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.0](https://github.com/sepandhaghighi/clox/archive/v1.0.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.0`
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
@@ -218,22 +227,33 @@ clox --vertical
218
227
 
219
228
  In this mode, the calendar will be displayed
220
229
 
221
- ℹ️ Valid choices: [`month`, `year`]
230
+ ℹ️ Valid choices: [`MONTH`, `YEAR`]
222
231
 
223
232
  ```console
224
- clox --calendar=month
233
+ clox --calendar=month --first-weekday="SUNDAY"
225
234
  ```
226
235
 
227
236
  ### Date System
228
237
 
229
- ℹ️ Valid choices: [`gregorian`, `jalali`]
238
+ ℹ️ Valid choices: [`GREGORIAN`, `JALALI`]
230
239
 
231
- ℹ️ The default date system is `gregorian`
240
+ ℹ️ The default date system is `GREGORIAN`
232
241
 
233
242
  ```console
234
243
  clox --date-system=jalali
235
244
  ```
236
245
 
246
+ ### Date Format
247
+
248
+ ℹ️ Valid choices: [`ISO`, `US`, `US-SHORT`, `EU`, `EU-SHORT`, `DOT`, `DASH`, `YMD`, `DMY`, `MDY`, `FULL`]
249
+
250
+ ℹ️ The default date format is `FULL`
251
+
252
+ ```console
253
+ clox --date-system=jalali --date-format=EU
254
+ ```
255
+ * Date Formats List: `clox --date-formats-list`
256
+
237
257
  ## Screen Record
238
258
 
239
259
  <div align="center">
@@ -292,6 +312,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
292
312
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
293
313
 
294
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`
324
+ ## [1.1] - 2025-05-23
325
+ ### Added
326
+ - `--first-weekday` argument
327
+ - `--date-format` argument
328
+ - `--date-formats-list` argument
329
+ ### Changed
330
+ - `README.md` updated
331
+ - Test system modified
295
332
  ## [1.0] - 2025-05-06
296
333
  ### Added
297
334
  - Local time
@@ -358,7 +395,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
358
395
  - `TIMEZONES.md`
359
396
  - `FACES.md`
360
397
 
361
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v1.0...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
400
+ [1.1]: https://github.com/sepandhaghighi/clox/compare/v1.0...v1.1
362
401
  [1.0]: https://github.com/sepandhaghighi/clox/compare/v0.9...v1.0
363
402
  [0.9]: https://github.com/sepandhaghighi/clox/compare/v0.8...v0.9
364
403
  [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
@@ -30,7 +30,7 @@ def read_description() -> str:
30
30
  setup(
31
31
  name='clox',
32
32
  packages=['clox'],
33
- version='1.0',
33
+ version='1.2',
34
34
  description='A Geeky Clock for Terminal Enthusiasts',
35
35
  long_description=read_description(),
36
36
  long_description_content_type='text/markdown',
@@ -38,7 +38,7 @@ setup(
38
38
  author='Sepand Haghighi',
39
39
  author_email='me@sepand.tech',
40
40
  url='https://github.com/sepandhaghighi/clox',
41
- download_url='https://github.com/sepandhaghighi/clox/tarball/v1.0',
41
+ download_url='https://github.com/sepandhaghighi/clox/tarball/v1.2',
42
42
  keywords="clock time timer timezone terminal cli geek clox",
43
43
  project_urls={
44
44
  'Source': 'https://github.com/sepandhaghighi/clox'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes