ComplexDateTimeField handles microseconds exactly instead of rounding like DateTimeField does. Derives from a StringField so you can do `gte` and `lte` filtering by using lexicographical comparison when filtering / sorting strings. The stored string has the following format:
| 613 | |
| 614 | |
| 615 | class ComplexDateTimeField(StringField): |
| 616 | """ |
| 617 | ComplexDateTimeField handles microseconds exactly instead of rounding |
| 618 | like DateTimeField does. |
| 619 | |
| 620 | Derives from a StringField so you can do `gte` and `lte` filtering by |
| 621 | using lexicographical comparison when filtering / sorting strings. |
| 622 | |
| 623 | The stored string has the following format: |
| 624 | |
| 625 | YYYY,MM,DD,HH,MM,SS,NNNNNN |
| 626 | |
| 627 | Where NNNNNN is the number of microseconds of the represented `datetime`. |
| 628 | The `,` as the separator can be easily modified by passing the `separator` |
| 629 | keyword when initializing the field. |
| 630 | |
| 631 | Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow) |
| 632 | """ |
| 633 | |
| 634 | def __init__(self, separator=",", **kwargs): |
| 635 | """ |
| 636 | :param separator: Allows to customize the separator used for storage (default ``,``) |
| 637 | :param kwargs: Keyword arguments passed into the parent :class:`~mongoengine.StringField` |
| 638 | """ |
| 639 | self.separator = separator |
| 640 | self.format = separator.join(["%Y", "%m", "%d", "%H", "%M", "%S", "%f"]) |
| 641 | super().__init__(**kwargs) |
| 642 | |
| 643 | def _convert_from_datetime(self, val): |
| 644 | """ |
| 645 | Convert a `datetime` object to a string representation (which will be |
| 646 | stored in MongoDB). This is the reverse function of |
| 647 | `_convert_from_string`. |
| 648 | |
| 649 | >>> a = datetime(2011, 6, 8, 20, 26, 24, 92284) |
| 650 | >>> ComplexDateTimeField()._convert_from_datetime(a) |
| 651 | '2011,06,08,20,26,24,092284' |
| 652 | """ |
| 653 | return val.strftime(self.format) |
| 654 | |
| 655 | def _convert_from_string(self, data): |
| 656 | """ |
| 657 | Convert a string representation to a `datetime` object (the object you |
| 658 | will manipulate). This is the reverse function of |
| 659 | `_convert_from_datetime`. |
| 660 | |
| 661 | >>> a = '2011,06,08,20,26,24,092284' |
| 662 | >>> ComplexDateTimeField()._convert_from_string(a) |
| 663 | datetime.datetime(2011, 6, 8, 20, 26, 24, 92284) |
| 664 | """ |
| 665 | values = [int(d) for d in data.split(self.separator)] |
| 666 | return datetime.datetime(*values) |
| 667 | |
| 668 | def __get__(self, instance, owner): |
| 669 | if instance is None: |
| 670 | return self |
| 671 | |
| 672 | data = super().__get__(instance, owner) |