Conditions | 20 |
Total Lines | 62 |
Code Lines | 45 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like jrnl.time.parse() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | from datetime import datetime |
||
21 | def parse( |
||
22 | date_str, inclusive=False, default_hour=None, default_minute=None, bracketed=False |
||
23 | ): |
||
24 | """Parses a string containing a fuzzy date and returns a datetime.datetime object""" |
||
25 | if not date_str: |
||
26 | return None |
||
27 | elif isinstance(date_str, datetime): |
||
28 | return date_str |
||
29 | |||
30 | # Don't try to parse anything with 6 or less characters and was parsed from the existing journal. |
||
31 | # It's probably a markdown footnote |
||
32 | if len(date_str) <= 6 and bracketed: |
||
33 | return None |
||
34 | |||
35 | default_date = DEFAULT_FUTURE if inclusive else DEFAULT_PAST |
||
36 | date = None |
||
37 | year_present = False |
||
38 | while not date: |
||
39 | try: |
||
40 | from dateutil.parser import parse as dateparse |
||
41 | |||
42 | date = dateparse(date_str, default=default_date) |
||
43 | if date.year == FAKE_YEAR: |
||
44 | date = datetime(datetime.now().year, date.timetuple()[1:6]) |
||
45 | else: |
||
46 | year_present = True |
||
47 | flag = 1 if date.hour == date.minute == 0 else 2 |
||
48 | date = date.timetuple() |
||
49 | except Exception as e: |
||
50 | if e.args[0] == "day is out of range for month": |
||
51 | y, m, d, H, M, S = default_date.timetuple()[:6] |
||
52 | default_date = datetime(y, m, d - 1, H, M, S) |
||
53 | else: |
||
54 | calendar = __get_pdt_calendar() |
||
55 | date, flag = calendar.parse(date_str) |
||
56 | |||
57 | if not flag: # Oops, unparsable. |
||
|
|||
58 | try: # Try and parse this as a single year |
||
59 | year = int(date_str) |
||
60 | return datetime(year, 1, 1) |
||
61 | except ValueError: |
||
62 | return None |
||
63 | except TypeError: |
||
64 | return None |
||
65 | |||
66 | if flag == 1: # Date found, but no time. Use the default time. |
||
67 | date = datetime( |
||
68 | *date[:3], |
||
69 | hour=23 if inclusive else default_hour or 0, |
||
70 | minute=59 if inclusive else default_minute or 0, |
||
71 | second=59 if inclusive else 0 |
||
72 | ) |
||
73 | else: |
||
74 | date = datetime(*date[:6]) |
||
75 | |||
76 | # Ugly heuristic: if the date is more than 4 weeks in the future, we got the year wrong. |
||
77 | # Rather then this, we would like to see parsedatetime patched so we can tell it to prefer |
||
78 | # past dates |
||
79 | dt = datetime.now() - date |
||
80 | if dt.days < -28 and not year_present: |
||
81 | date = date.replace(date.year - 1) |
||
82 | return date |
||
83 |