| 554 | |
| 555 | @staticmethod |
| 556 | def _parse_datetime(value): |
| 557 | # Attempt to parse a datetime from a string |
| 558 | value = value.strip() |
| 559 | if not value: |
| 560 | return None |
| 561 | |
| 562 | if dateutil: |
| 563 | try: |
| 564 | return dateutil.parser.parse(value) |
| 565 | except (TypeError, ValueError, OverflowError): |
| 566 | return None |
| 567 | |
| 568 | # split usecs, because they are not recognized by strptime. |
| 569 | if "." in value: |
| 570 | try: |
| 571 | value, usecs = value.split(".") |
| 572 | usecs = int(usecs) |
| 573 | except ValueError: |
| 574 | return None |
| 575 | else: |
| 576 | usecs = 0 |
| 577 | kwargs = {"microsecond": usecs} |
| 578 | try: # Seconds are optional, so try converting seconds first. |
| 579 | return datetime.datetime( |
| 580 | *time.strptime(value, "%Y-%m-%d %H:%M:%S")[:6], **kwargs |
| 581 | ) |
| 582 | except ValueError: |
| 583 | try: # Try without seconds. |
| 584 | return datetime.datetime( |
| 585 | *time.strptime(value, "%Y-%m-%d %H:%M")[:5], **kwargs |
| 586 | ) |
| 587 | except ValueError: # Try without hour/minutes/seconds. |
| 588 | try: |
| 589 | return datetime.datetime( |
| 590 | *time.strptime(value, "%Y-%m-%d")[:3], **kwargs |
| 591 | ) |
| 592 | except ValueError: |
| 593 | return None |
| 594 | |
| 595 | def prepare_query_value(self, op, value): |
| 596 | return super().prepare_query_value(op, self.to_mongo(value)) |