Example #1
0
 def _decompress_historic_datetime(
         historic_datetime: HistoricDateTime) -> List:
     year = historic_datetime.year
     season, month, day, time = None, None, None, None
     hour, minute, second = (
         historic_datetime.hour,
         historic_datetime.minute,
         historic_datetime.second,
     )
     if historic_datetime.use_ybp:
         year, year_system = historic_datetime.year_bp, YBP
     elif historic_datetime.year_bce:
         year, year_system = historic_datetime.year_bce, BCE
     else:
         year_system = CE
     if historic_datetime.season_is_known:
         season = get_season_from_month(historic_datetime.month)
         if historic_datetime.month_is_known:
             month = historic_datetime.month
             if historic_datetime.day_is_known:
                 day = historic_datetime.day
     if 0 in {hour, minute, second} or 1 in {hour, minute, second}:
         time = None
     else:
         time = historic_datetime.strftime('%H:%M:%S.%f')
     return [year, year_system, season, month, day, time]
Example #2
0
    def to_python(
        self, historic_datetime: Optional[Union[DateTime, str]]
    ) -> Optional[HistoricDateTime]:
        """
        Convert the value into the correct Python object.

        This method acts as the reverse of value_to_string(), and is also called in clean().
        """
        if not historic_datetime:
            return None
        elif isinstance(historic_datetime, HistoricDateTime):
            return historic_datetime
        elif isinstance(historic_datetime, datetime):
            # TODO: consider effect of timezones
            if settings.USE_TZ and is_naive(historic_datetime):
                historic_datetime = make_aware(historic_datetime)
            return HistoricDateTime(
                historic_datetime.year,
                historic_datetime.month,
                historic_datetime.day,
                historic_datetime.hour,
                historic_datetime.minute,
                historic_datetime.second,
                historic_datetime.microsecond,
            )
        elif isinstance(historic_datetime, str):
            raise TypeError
Example #3
0
    def decompress(self, datetime_value: Union[date, str, Any]):
        """
        "Decompresses" a Python value into a list of values to populate the widget.

        The input value can be assumed valid, but not necessarily non-empty.

        https://docs.djangoproject.com/en/3.1/ref/forms/widgets/#django.forms.MultiWidget.decompress
        """
        nones = (None, None, None, None, None, None)
        hour = minute = second = ms = 0
        if not isinstance(datetime_value, HistoricDateTime):
            if isinstance(datetime_value, str):
                year, month, day, hour, minute, second, ms = self._parse_string(
                    datetime_value)
            elif isinstance(datetime_value, (datetime, date)):
                year, month, day = (
                    datetime_value.year,
                    datetime_value.month,
                    datetime_value.day,
                )
                if isinstance(datetime_value, datetime):
                    hour, minute, second, ms = (
                        datetime_value.hour,
                        datetime_value.minute,
                        datetime_value.second,
                        datetime_value.microsecond,
                    )
            else:
                return nones
            # Convert value to HistoricDateTime
            datetime_value = HistoricDateTime(year, month, day, hour, minute,
                                              second, ms)
        return self._decompress_historic_datetime(datetime_value)
Example #4
0
def date_sorter(
        model_instance: Union[SearchableDatedModel, Dict]) -> HistoricDateTime:
    """Return the value used to sort the model instance by date."""
    get_date = getattr(model_instance, 'get_date', None)
    if get_date is not None:
        date = get_date()
    elif isinstance(model_instance, dict):
        date = model_instance.get('date')
    else:
        date = getattr(model_instance, 'date', None)
    if not date:
        date = HistoricDateTime(1, 1, 1, 0, 0, 0)
    # Display precise dates before ranges, e.g., "1500" before "1500 – 2000"
    if getattr(model_instance, 'end_date', None):
        microsecond = date.microsecond + 1
        date = date.replace(microsecond=microsecond)
    return date
Example #5
0
 def value_from_datadict(self, datadict, files, name) -> Optional[str]:
     """Compress the input value into a format that can be saved to the db."""
     decompressed_values = super().value_from_datadict(
         datadict, files, name)
     if len(decompressed_values) != 2:
         raise ValueError(
             f'Wrong number of values: {len(decompressed_values)}')
     year, year_system = decompressed_values
     if not year:
         return None
     year, second, microsecond = get_year(year, year_system)
     # Build datetime obj
     dt = HistoricDateTime(year,
                           1,
                           1,
                           1,
                           1,
                           second,
                           microsecond=microsecond)
     # Return date-parsable string for db
     return dt.strftime('%Y-%m-%d %H:%M:%S.%f')
Example #6
0
    def from_db_value(self, datetime_value: Optional[DateTime], expression,
                      connection) -> Optional[HistoricDateTime]:
        """
        Convert a value as returned by the database to a Python object.

        This method is the reverse of get_prep_value().

        https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.Field.from_db_value
        """
        if datetime_value is None:
            return datetime_value
        # TODO: consider effect of timezones
        if settings.USE_TZ and is_naive(datetime_value):
            datetime_value = make_aware(datetime_value)
        return HistoricDateTime(
            datetime_value.year,
            datetime_value.month,
            datetime_value.day,
            datetime_value.hour,
            datetime_value.minute,
            datetime_value.second,
            datetime_value.microsecond,
        )
Example #7
0
def _datetime_from_datadict_values(year, year_system, season, month, day):
    # Figure out year
    year, second, microsecond = get_year(year, year_system)
    # Figure out date precision
    hour, minute = 0, 0
    if not season and not month:
        hour, minute, second = 1, 1, second or 1
    elif season and not month:
        month = get_month_from_season(season)
        hour, minute, second = 0, 1, second or 1
    elif month and not day:
        hour, minute, second = 0, 0, second or 1
    month, day = (month or 1), (day or 1)
    # Return datetime object
    return HistoricDateTime(
        int(year),
        int(month),
        int(day),
        int(hour),
        int(minute),
        int(second),
        microsecond=int(microsecond),
    )