dcicutils 8.8.3.1b14__py3-none-any.whl → 8.8.3.1b15__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.
- dcicutils/datetime_utils.py +110 -25
- {dcicutils-8.8.3.1b14.dist-info → dcicutils-8.8.3.1b15.dist-info}/METADATA +1 -1
- {dcicutils-8.8.3.1b14.dist-info → dcicutils-8.8.3.1b15.dist-info}/RECORD +6 -6
- {dcicutils-8.8.3.1b14.dist-info → dcicutils-8.8.3.1b15.dist-info}/LICENSE.txt +0 -0
- {dcicutils-8.8.3.1b14.dist-info → dcicutils-8.8.3.1b15.dist-info}/WHEEL +0 -0
- {dcicutils-8.8.3.1b14.dist-info → dcicutils-8.8.3.1b15.dist-info}/entry_points.txt +0 -0
    
        dcicutils/datetime_utils.py
    CHANGED
    
    | @@ -3,6 +3,22 @@ from datetime import datetime, timedelta, timezone | |
| 3 3 | 
             
            from dateutil import parser as datetime_parser
         | 
| 4 4 | 
             
            from typing import Optional, Tuple, Union
         | 
| 5 5 |  | 
| 6 | 
            +
            TIMEZONE_LOCAL = datetime.now().astimezone().tzinfo  # type: datetime.timezone
         | 
| 7 | 
            +
            TIMEZONE_LOCAL_NAME = TIMEZONE_LOCAL.tzname(None)  # type: str
         | 
| 8 | 
            +
            TIMEZONE_LOCAL_OFFSET = TIMEZONE_LOCAL.utcoffset(None)  # type: datetime.timedelta
         | 
| 9 | 
            +
            TIMEZONE_LOCAL_OFFSET_TOTAL_MINUTES = int(TIMEZONE_LOCAL_OFFSET.total_seconds()) // 60  # type: int
         | 
| 10 | 
            +
            TIMEZONE_LOCAL_OFFSET_HOURS = TIMEZONE_LOCAL_OFFSET_TOTAL_MINUTES // 60  # type: int
         | 
| 11 | 
            +
            TIMEZONE_LOCAL_OFFSET_MINUTES = TIMEZONE_LOCAL_OFFSET_TOTAL_MINUTES % 60  # type: int
         | 
| 12 | 
            +
            TIMEZONE_LOCAL_SUFFIX = f"{TIMEZONE_LOCAL_OFFSET_HOURS:+03d}:{TIMEZONE_LOCAL_OFFSET_MINUTES:02d}"  # type: str
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            TIMEZONE_UTC = timezone.utc  # type: datetime.timezone
         | 
| 15 | 
            +
            TIMEZONE_UTC_NAME = TIMEZONE_UTC.tzname(None)  # type: str
         | 
| 16 | 
            +
            TIMEZONE_UTC_OFFSET = timedelta(0)  # type: datetime.timedelta
         | 
| 17 | 
            +
            TIMEZONE_UTC_OFFSET_TOTAL_MINUTES = 0  # type: int
         | 
| 18 | 
            +
            TIMEZONE_UTC_OFFSET_HOURS = 0  # type: int
         | 
| 19 | 
            +
            TIMEZONE_UTC_OFFSET_MINUTES = 0  # type: int
         | 
| 20 | 
            +
            TIMEZONE_UTC_SUFFIX = "Z"  # type: str
         | 
| 21 | 
            +
             | 
| 6 22 |  | 
| 7 23 | 
             
            def parse_datetime_string(value: str) -> Optional[datetime]:
         | 
| 8 24 | 
             
                """
         | 
| @@ -83,46 +99,60 @@ def normalize_date_string(value: str) -> Optional[str]: | |
| 83 99 | 
             
                return d.strftime("%Y-%m-%d") if d else None
         | 
| 84 100 |  | 
| 85 101 |  | 
| 86 | 
            -
            def get_timezone( | 
| 102 | 
            +
            def get_timezone(hours_or_timedelta: Union[int, timedelta], minutes: Optional[int] = None) -> timezone:
         | 
| 103 | 
            +
                try:
         | 
| 104 | 
            +
                    if isinstance(hours_or_timedelta, timedelta):
         | 
| 105 | 
            +
                        return timezone(hours_or_timedelta)
         | 
| 106 | 
            +
                    return timezone(timedelta(hours=hours_or_timedelta, minutes=minutes or 0))
         | 
| 107 | 
            +
                except Exception:
         | 
| 108 | 
            +
                    return TIMEZONE_LOCAL
         | 
| 109 | 
            +
             | 
| 110 | 
            +
             | 
| 111 | 
            +
            def get_timezone_offset(tz: timezone) -> timedelta:
         | 
| 87 112 | 
             
                try:
         | 
| 88 | 
            -
                    return  | 
| 113 | 
            +
                    return tz.utcoffset(None)
         | 
| 89 114 | 
             
                except Exception:
         | 
| 90 | 
            -
                    return  | 
| 115 | 
            +
                    return TIMEZONE_LOCAL_OFFSET
         | 
| 91 116 |  | 
| 92 117 |  | 
| 93 118 | 
             
            def get_timezone_hours_minutes(tz: timezone) -> Tuple[int, int]:
         | 
| 94 119 | 
             
                """
         | 
| 95 120 | 
             
                Returns a tuple with the integer hours and minutes offset for the given timezone.
         | 
| 121 | 
            +
                If negative then only the hours is negative; the mintutes is always positive;
         | 
| 122 | 
            +
                this is okay because there are no timezones less than one hour from UTC.
         | 
| 96 123 | 
             
                """
         | 
| 97 | 
            -
                 | 
| 98 | 
            -
                 | 
| 124 | 
            +
                tz_offset = get_timezone_offset(tz)
         | 
| 125 | 
            +
                tz_offset_total_minutes = int(tz_offset.total_seconds()) // 60
         | 
| 126 | 
            +
                tz_offset_hours = tz_offset_total_minutes // 60
         | 
| 127 | 
            +
                tz_offset_minutes = abs(tz_offset_total_minutes % 60)
         | 
| 128 | 
            +
                return tz_offset_hours, tz_offset_minutes
         | 
| 99 129 |  | 
| 100 130 |  | 
| 101 131 | 
             
            def get_utc_timezone() -> timezone:
         | 
| 102 | 
            -
                return  | 
| 132 | 
            +
                return TIMEZONE_UTC
         | 
| 103 133 |  | 
| 104 134 |  | 
| 105 135 | 
             
            def get_local_timezone() -> timezone:
         | 
| 106 136 | 
             
                """
         | 
| 107 137 | 
             
                Returns current/local timezone as a datetime.timezone object.
         | 
| 108 138 | 
             
                """
         | 
| 109 | 
            -
                return  | 
| 139 | 
            +
                return TIMEZONE_LOCAL
         | 
| 110 140 |  | 
| 111 141 |  | 
| 112 142 | 
             
            def get_local_timezone_string() -> str:
         | 
| 113 143 | 
             
                """
         | 
| 114 144 | 
             
                Returns current/local timezone in format like: "-05:00".
         | 
| 115 145 | 
             
                """
         | 
| 116 | 
            -
                 | 
| 117 | 
            -
                return f"{tz_hours:+03d}:{tz_minutes:02d}"
         | 
| 146 | 
            +
                return TIMEZONE_LOCAL_SUFFIX
         | 
| 118 147 |  | 
| 119 148 |  | 
| 120 149 | 
             
            def get_local_timezone_hours_minutes() -> Tuple[int, int]:
         | 
| 121 150 | 
             
                """
         | 
| 122 151 | 
             
                Returns a tuple with the integer hours and minutes offset for the current/local timezone.
         | 
| 152 | 
            +
                If negative then only the hours is negative; the mintutes is always positive;
         | 
| 153 | 
            +
                this is okay because there are no timezones less than one hour from UTC.
         | 
| 123 154 | 
             
                """
         | 
| 124 | 
            -
                 | 
| 125 | 
            -
                return int(tz_minutes // 60), int(abs(tz_minutes % 60))
         | 
| 155 | 
            +
                return TIMEZONE_LOCAL_OFFSET_HOURS, TIMEZONE_LOCAL_OFFSET_MINUTES
         | 
| 126 156 |  | 
| 127 157 |  | 
| 128 158 | 
             
            def parse_datetime(value: str, utc: bool = False, tz: Optional[timezone] = None) -> Optional[datetime]:
         | 
| @@ -154,14 +184,16 @@ def parse_datetime(value: str, utc: bool = False, tz: Optional[timezone] = None) | |
| 154 184 |  | 
| 155 185 | 
             
            def format_datetime(value: datetime,
         | 
| 156 186 | 
             
                                utc: bool = False,
         | 
| 157 | 
            -
                                iso: bool = False,
         | 
| 158 | 
            -
                                ms: bool = False,
         | 
| 159 187 | 
             
                                tz: Optional[Union[timezone, bool]] = None,
         | 
| 188 | 
            +
                                iso: bool = False,
         | 
| 160 189 | 
             
                                notz: bool = False,
         | 
| 161 190 | 
             
                                noseconds: bool = False,
         | 
| 191 | 
            +
                                ms: bool = False,
         | 
| 162 192 | 
             
                                verbose: bool = False,
         | 
| 163 193 | 
             
                                noseparator: bool = False,
         | 
| 164 | 
            -
                                noday: bool = False | 
| 194 | 
            +
                                noday: bool = False,
         | 
| 195 | 
            +
                                nodate: bool = False,
         | 
| 196 | 
            +
                                notime: bool = False) -> str:
         | 
| 165 197 | 
             
                """
         | 
| 166 198 | 
             
                Returns the given datetime as a string in "YYYY:MM:DD hh:mm:ss tz" format, for
         | 
| 167 199 | 
             
                example "2024-04-17 15:42:26 EDT". If the given notz argument is True then omits
         | 
| @@ -173,9 +205,11 @@ def format_datetime(value: datetime, | |
| 173 205 | 
             
                one; if the given utc argument is True then it will be UTC; or if the given tz
         | 
| 174 206 | 
             
                argument is a datetime.timezone it will be in that timezone.
         | 
| 175 207 | 
             
                """
         | 
| 208 | 
            +
                if nodate is True and notime is True:
         | 
| 209 | 
            +
                    return ""
         | 
| 176 210 | 
             
                if not isinstance(value, datetime):
         | 
| 177 211 | 
             
                    if not isinstance(value, str) or not (value := parse_datetime(value)):
         | 
| 178 | 
            -
                        return  | 
| 212 | 
            +
                        return ""
         | 
| 179 213 | 
             
                try:
         | 
| 180 214 | 
             
                    if utc is True:
         | 
| 181 215 | 
             
                        tz = timezone.utc
         | 
| @@ -195,19 +229,70 @@ def format_datetime(value: datetime, | |
| 195 229 | 
             
                            value = value.replace(microsecond=0)
         | 
| 196 230 | 
             
                        if noseconds is True:
         | 
| 197 231 | 
             
                            if notz is True:
         | 
| 198 | 
            -
                                 | 
| 232 | 
            +
                                if nodate is True:
         | 
| 233 | 
            +
                                    return value.strftime(f"%H:%M")
         | 
| 234 | 
            +
                                elif notime is True:
         | 
| 235 | 
            +
                                    return value.strftime(f"%Y-%m-%d")
         | 
| 236 | 
            +
                                else:
         | 
| 237 | 
            +
                                    return value.strftime(f"%Y-%m-%dT%H:%M")
         | 
| 199 238 | 
             
                            tz = value.strftime("%z")
         | 
| 200 239 | 
             
                            tz = tz[:3] + ":" + tz[3:]
         | 
| 201 | 
            -
                             | 
| 202 | 
            -
             | 
| 240 | 
            +
                            if nodate is True:
         | 
| 241 | 
            +
                                return value.strftime(f"%H:%M") + tz
         | 
| 242 | 
            +
                            elif notime is True:
         | 
| 243 | 
            +
                                return value.strftime(f"%Y-%m-%d") + tz
         | 
| 244 | 
            +
                            else:
         | 
| 245 | 
            +
                                return value.strftime(f"%Y-%m-%dT%H:%M") + tz
         | 
| 246 | 
            +
                        if nodate is True:
         | 
| 247 | 
            +
                            return value.strftime(f"%H:%M:%S{f'.%f' if ms is True else ''}")
         | 
| 248 | 
            +
                        elif notime is True:
         | 
| 249 | 
            +
                            return value.strftime(f"%Y-%m-%d")
         | 
| 250 | 
            +
                        else:
         | 
| 251 | 
            +
                            return value.isoformat()
         | 
| 203 252 | 
             
                    if verbose:
         | 
| 204 | 
            -
                         | 
| 205 | 
            -
                             | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 253 | 
            +
                        if nodate is True:
         | 
| 254 | 
            +
                            return value.strftime(
         | 
| 255 | 
            +
                                f"%-I:%M{'' if noseconds is True else ':%S'}"
         | 
| 256 | 
            +
                                f"{f'.%f' if ms is True else ''} %p{'' if notz is True else ' %Z'}")
         | 
| 257 | 
            +
                        elif notime is True:
         | 
| 258 | 
            +
                            return value.strftime(f"{'' if noday is True else '%A, '}%B %-d, %Y")
         | 
| 259 | 
            +
                        else:
         | 
| 260 | 
            +
                            return value.strftime(
         | 
| 261 | 
            +
                                f"{'' if noday is True else '%A, '}%B %-d, %Y{'' if noseparator is True else ' |'}"
         | 
| 262 | 
            +
                                f" %-I:%M{'' if noseconds is True else ':%S'}"
         | 
| 263 | 
            +
                                f"{f'.%f' if ms is True else ''} %p{'' if notz is True else ' %Z'}")
         | 
| 208 264 | 
             
                    else:
         | 
| 209 | 
            -
                         | 
| 210 | 
            -
                             | 
| 211 | 
            -
             | 
| 265 | 
            +
                        if nodate is True:
         | 
| 266 | 
            +
                            return value.strftime(
         | 
| 267 | 
            +
                                f"%H:%M{'' if noseconds is True else ':%S'}"
         | 
| 268 | 
            +
                                f"{f'.%f' if ms is True else ''}{'' if notz is True else ' %Z'}")
         | 
| 269 | 
            +
                        elif notime is True:
         | 
| 270 | 
            +
                            return value.strftime(f"%Y-%m-%d")
         | 
| 271 | 
            +
                        else:
         | 
| 272 | 
            +
                            return value.strftime(
         | 
| 273 | 
            +
                                f"%Y-%m-%d %H:%M{'' if noseconds is True else ':%S'}"
         | 
| 274 | 
            +
                                f"{f'.%f' if ms is True else ''}{'' if notz is True else ' %Z'}")
         | 
| 212 275 | 
             
                except Exception:
         | 
| 213 276 | 
             
                    return None
         | 
| 277 | 
            +
             | 
| 278 | 
            +
             | 
| 279 | 
            +
            def format_date(value: datetime,
         | 
| 280 | 
            +
                            utc: bool = False,
         | 
| 281 | 
            +
                            iso: bool = False,
         | 
| 282 | 
            +
                            tz: Optional[Union[timezone, bool]] = None,
         | 
| 283 | 
            +
                            verbose: bool = False,
         | 
| 284 | 
            +
                            noday: bool = False) -> str:
         | 
| 285 | 
            +
                return format_datetime(value, utc=utc, iso=iso, tz=tz, verbose=verbose, noday=noday, notime=True)
         | 
| 286 | 
            +
             | 
| 287 | 
            +
             | 
| 288 | 
            +
            def format_time(value: datetime,
         | 
| 289 | 
            +
                            utc: bool = False,
         | 
| 290 | 
            +
                            iso: bool = False,
         | 
| 291 | 
            +
                            ms: bool = False,
         | 
| 292 | 
            +
                            tz: Optional[Union[timezone, bool]] = None,
         | 
| 293 | 
            +
                            notz: bool = False,
         | 
| 294 | 
            +
                            noseconds: bool = False,
         | 
| 295 | 
            +
                            verbose: bool = False,
         | 
| 296 | 
            +
                            noday: bool = False) -> str:
         | 
| 297 | 
            +
                return format_datetime(value, utc=utc, iso=iso, ms=ms, tz=tz, notz=notz,
         | 
| 298 | 
            +
                                       noseconds=noseconds, verbose=verbose, nodate=True)
         | 
| @@ -12,7 +12,7 @@ dcicutils/contribution_utils.py,sha256=vYLS1JUB3sKd24BUxZ29qUBqYeQBLK9cwo8x3k64u | |
| 12 12 | 
             
            dcicutils/creds_utils.py,sha256=xrLekD49Ex0GOpL9n7LlJA4gvNcY7txTVFOSYD7LvEU,11113
         | 
| 13 13 | 
             
            dcicutils/data_readers.py,sha256=6EMrY7TjDE8H7bA_TCWtpLQP7slJ0YTL77_dNh6e7sg,7626
         | 
| 14 14 | 
             
            dcicutils/data_utils.py,sha256=k2OxOlsx7AJ6jF-YNlMyGus_JqSUBe4_n1s65Mv1gQQ,3098
         | 
| 15 | 
            -
            dcicutils/datetime_utils.py,sha256= | 
| 15 | 
            +
            dcicutils/datetime_utils.py,sha256=STFFakdCIwtuRLA1PCbieeXniTPY8Rchg5Psv1CUJ84,13342
         | 
| 16 16 | 
             
            dcicutils/deployment_utils.py,sha256=sKv8Jb-_Zw2aH3OAywRlsre-Cqm3a7fEGG3_1PT-r-s,69908
         | 
| 17 17 | 
             
            dcicutils/diff_utils.py,sha256=sQx-yz56DHAcQWOChYbAG3clXu7TbiZKlw-GggeveO0,8118
         | 
| 18 18 | 
             
            dcicutils/docker_utils.py,sha256=30gUiqz7X9rJwSPXTPn4ewjQibUgoSJqhP9o9vn5X-A,1747
         | 
| @@ -72,8 +72,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769 | |
| 72 72 | 
             
            dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
         | 
| 73 73 | 
             
            dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
         | 
| 74 74 | 
             
            dcicutils/zip_utils.py,sha256=rnjNv_k6L9jT2SjDSgVXp4BEJYLtz9XN6Cl2Fy-tqnM,2027
         | 
| 75 | 
            -
            dcicutils-8.8.3. | 
| 76 | 
            -
            dcicutils-8.8.3. | 
| 77 | 
            -
            dcicutils-8.8.3. | 
| 78 | 
            -
            dcicutils-8.8.3. | 
| 79 | 
            -
            dcicutils-8.8.3. | 
| 75 | 
            +
            dcicutils-8.8.3.1b15.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
         | 
| 76 | 
            +
            dcicutils-8.8.3.1b15.dist-info/METADATA,sha256=JY0PlcvcINCPnQ0qQ6u5flnCWSw1237wWPTfmlg43T4,3357
         | 
| 77 | 
            +
            dcicutils-8.8.3.1b15.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
         | 
| 78 | 
            +
            dcicutils-8.8.3.1b15.dist-info/entry_points.txt,sha256=51Q4F_2V10L0282W7HFjP4jdzW4K8lnWDARJQVFy_hw,270
         | 
| 79 | 
            +
            dcicutils-8.8.3.1b15.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |