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