1# Copyright (c) 2012-2016 Seafile Ltd. 2import logging 3import pytz 4import datetime 5from django.conf import settings 6from django.utils import six 7from django.utils import timezone 8from django.utils.timezone import get_current_timezone 9 10logger = logging.getLogger(__name__) 11 12# https://docs.djangoproject.com/en/1.11/ref/utils/#django.utils.timezone.get_current_timezone 13current_timezone = get_current_timezone() 14 15 16def dt(value): 17 """Convert 32/64 bits timestamp to datetime object. 18 """ 19 try: 20 return datetime.datetime.utcfromtimestamp(value) 21 except ValueError: 22 # TODO: need a better way to handle 64 bits timestamp. 23 return datetime.datetime.utcfromtimestamp(value/1000000) 24 25 26def value_to_db_datetime(value): 27 if value is None: 28 return None 29 30 # MySQL doesn't support tz-aware datetimes 31 if timezone.is_aware(value): 32 if settings.USE_TZ: 33 value = value.astimezone(timezone.utc).replace(tzinfo=None) 34 else: 35 raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.") 36 37 # MySQL doesn't support microseconds 38 return six.text_type(value.replace(microsecond=0)) 39 40 41def utc_to_local(dt): 42 # change from UTC timezone to current seahub timezone 43 tz = timezone.get_default_timezone() 44 utc = dt.replace(tzinfo=timezone.utc) 45 local = timezone.make_naive(utc, tz) 46 return local 47 48 49def timestamp_to_isoformat_timestr(timestamp): 50 try: 51 min_ts = -(1 << 31) 52 max_ts = (1 << 31) - 1 53 if min_ts <= timestamp <= max_ts: 54 dt_obj = datetime.datetime.fromtimestamp(timestamp) 55 else: 56 dt_obj = datetime.datetime.fromtimestamp(timestamp/1000000) 57 58 dt_obj = dt_obj.replace(microsecond=0) 59 isoformat_timestr = current_timezone.localize(dt_obj).isoformat() 60 return isoformat_timestr 61 except Exception as e: 62 logger.error(e) 63 return '' 64 65 66# https://pypi.org/project/pytz/ 67def datetime_to_isoformat_timestr(datetime): 68 69 if not datetime: 70 return '' 71 72 from django.utils.timezone import make_naive, is_aware 73 if is_aware(datetime): 74 datetime = make_naive(datetime) 75 76 try: 77 # This library only supports two ways of building a localized time. 78 # The first is to use the localize() method provided by the pytz library. 79 # This is used to localize a naive datetime (datetime with no timezone information): 80 datetime = datetime.replace(microsecond=0) 81 isoformat_timestr = current_timezone.localize(datetime).isoformat() 82 return isoformat_timestr 83 except Exception as e: 84 logger.error(e) 85 return '' 86 87 88def utc_datetime_to_isoformat_timestr(utc_datetime): 89 try: 90 # The second way of building a localized time is by converting an existing 91 # localized time using the standard astimezone() method: 92 utc_datetime = utc_datetime.replace(microsecond=0) 93 utc_datetime = pytz.utc.localize(utc_datetime) 94 isoformat_timestr = utc_datetime.astimezone(current_timezone).isoformat() 95 return isoformat_timestr 96 except Exception as e: 97 logger.error(e) 98 return '' 99 100 101def datetime_to_timestamp(datetime_obj): 102 epoch = datetime.datetime(1970, 1, 1) 103 local = utc_to_local(datetime_obj) 104 time_diff = local - epoch 105 return time_diff.seconds + (time_diff.days * 24 * 3600) 106