def make_utc_date(dict):
"""
Takes an attribute dictionary. If "date" present, returns "YYYY-MM-DD" in Coordinated Universal Time.
Otherwise, returns None. "date" must be a git-formatted string, e.g. 'Mon Apr 18 00:59:02 2016 -0400'.
**Parameters**:
> *dict* : `dict`
>> An attribute dictionary.
**Return** `string` or `none`
"""
if "date" in dict:
git_dt = datetime_git(dict["date"]).astimezone(dt.timezone(dt.timedelta(0)))
return git_dt.strftime("%Y-%m-%d")
else:
return None
python类timezone()的实例源码
def make_utc_datetime(dict):
"""
Takes an attribute dictionary. If "date" present, returns "YYYY-MM-DD HH:MM:SS" in
Coordinated Universal Time. Otherwise, returns None. "date" must be a git-formatted string,
e.g. 'Mon Apr 18 00:59:02 2016 -0400'.
**Parameters**:
> *dict* : `dict`
>> An attribute dictionary.
**Return** `string` or `none`
"""
if "date" in dict:
git_dt = datetime_git(dict["date"]).astimezone(dt.timezone(dt.timedelta(0)))
return git_dt.strftime("%Y-%m-%d %H:%M:%S")
else:
return None
def __str__(self):
if self.user is None or self.date is None:
error("Stringify `Tweet` without `user` or `date`.")
raise ValueError()
dt = self.date.astimezone(timezone(timedelta(hours=9)))
ds = datetime.strftime(dt, "%Y-%m-%d %H:%M:%S JST")
results = [self.user, ds]
for t in [self.ja, self.zh]:
if len(t) == 0:
continue
# Fix GBK encoding
t = t.replace('?', '·')
t = t.replace('?', '×')
t = t.replace('#???', '')
t = t.replace('#????????', '')
results.extend(['', t.strip()])
results.extend([str(m) for m in self.media])
return '\n'.join(results)
def __str__(self):
if self.user is None or self.date is None:
error("Stringify `Tweet` without `user` or `date`.")
raise ValueError()
dt = self.date.astimezone(timezone(timedelta(hours=9)))
ds = datetime.strftime(dt, "%Y-%m-%d %H:%M:%S JST")
results = [self.user, ds]
for t in [self.ja, self.zh]:
if len(t) == 0:
continue
# Fix GBK encoding
t = t.replace('?', '·')
t = t.replace('?', '×')
t = t.replace('?', '')
t = t.replace('#???', '')
t = t.replace('#????????', '')
results.extend(['', t.strip()])
results.extend([str(m) for m in self.media])
return '\n'.join(results)
def utcnow(format="ts"):
''' returns time-aware utc datetime object or timestamp of current time/date
@Param: format - defaults to timestamp, provide "dt" for datetime obj '''
dt = datetime.now(tz=pytz.utc)
if format == "dt":
return dt
else: # timestamp includes millis down to 6th decimal place
ts = str(dt.timestamp())
return ts.replace('.', '')
# DEBUG
# print(utcnow())
# print(utcnow("dt"))
# TODO add methods for converting to client local timezone dynamically
def format_date(unix_timestamp):
""" Return a standardized date format for use in the two1 library.
This function produces a localized datetime string that includes the UTC timezone offset. This offset is
computed as the difference between the local version of the timestamp (python's datatime.fromtimestamp)
and the utc representation of the input timestamp.
Args:
unix_timestamp (float): a floating point unix timestamp
Returns:
string: A string formatted with "%Y-%m-%d %H:%M:%S %Z"
"""
local_datetime = datetime.fromtimestamp(unix_timestamp)
utz_offset = local_datetime - datetime.utcfromtimestamp(unix_timestamp)
local_date = local_datetime.replace(
tzinfo=timezone(utz_offset)
).strftime("%Y-%m-%d %H:%M:%S %Z")
return local_date
def test_str2date():
# GIVEN
expected = datetime(
year=2017,
month=3,
day=21,
hour=16,
minute=9,
second=13,
tzinfo=timezone(timedelta(hours=1))
)
string = '2017-03-21 16:09:13 +0100'
# WHEN
date = datetools.str2date(string)
# THEN
assert date == expected
def test_date2str():
# GIVEN
expected = '2017-03-21 16:09:13 +0100'
dt = datetime(
year=2017,
month=3,
day=21,
hour=16,
minute=9,
second=13,
tzinfo=timezone(timedelta(hours=1))
)
# WHEN
string = datetools.date2str(dt)
# THEN
assert string == expected
def timezone_from_str(tz_str):
"""
Convert a timezone string to a timezone object.
:param tz_str: string with format 'Asia/Shanghai' or 'UTC±[hh]:[mm]'
:return: a timezone object (tzinfo)
"""
m = re.match(r'UTC([+|-]\d{1,2}):(\d{2})', tz_str)
if m:
# in format 'UTC±[hh]:[mm]'
delta_h = int(m.group(1))
delta_m = int(m.group(2)) if delta_h >= 0 else -int(m.group(2))
return timezone(timedelta(hours=delta_h, minutes=delta_m))
# in format 'Asia/Shanghai'
try:
return pytz.timezone(tz_str)
except pytz.exceptions.UnknownTimeZoneError:
return None
def __str__(self):
for url in self.media:
filename = os.path.basename(url)
dir = os.path.join(config['cq_root_dir'], config['cq_image_dir'], 'twitter')
path = os.path.join(dir, filename)
# ??twitter??????????
if not os.path.exists(dir):
os.mkdir(dir)
# ??
if not os.path.exists(path):
resp = requests.get(url, timeout=60, proxies=config.get('proxies'))
with open(path, 'wb') as f:
f.write(resp.content)
dt = self.date.astimezone(timezone(timedelta(hours=9)))
ds = datetime.strftime(dt, "%Y-%m-%d %H:%M:%S JST")
results = [ds, ]
text = self.text
text = text.replace('?', '·').replace('?', '×').replace('#????????', '').replace('?', '')
results.extend(['', text.strip()])
results.extend([str(CQImage(os.path.join('twitter', os.path.basename(m)))) for m in self.media])
return '\n'.join(results)
def test_decode_time():
assert _decode_time('03:04:05', True) == time(3, 4, 5, tzinfo=timezone(timedelta(0)))
# TODO: The standard specifies that the second fraction is limited to one
# digit, however udatetime only permits 3 or 6 digits.
assert _decode_time('03:04:05.600', True) == time(3, 4, 5, 600000, tzinfo=timezone(timedelta(0)))
assert _decode_time('03:04:05Z', True) == time(3, 4, 5, tzinfo=timezone(timedelta(0)))
assert _decode_time('03:04:05+00:00', True) == time(3, 4, 5, tzinfo=timezone(timedelta(0)))
assert _decode_time('03:04:05-00:00', True) == time(3, 4, 5, tzinfo=timezone(timedelta(0)))
assert _decode_time('03:04:05+07:08', True) == time(3, 4, 5, tzinfo=timezone(timedelta(hours=7, minutes=8)))
assert _decode_time('03:04:05-07:08', True) == time(3, 4, 5, tzinfo=timezone(timedelta(hours=-7, minutes=-8)))
assert _decode_time('03:04:05.600+07:08', True) == \
time(3, 4, 5, 600000, tzinfo=timezone(timedelta(hours=7, minutes=8)))
assert _decode_time('03:04:05', False) == time(3, 4, 5)
assert _decode_time('03:04:05.600', False) == time(3, 4, 5, 600000)
assert _decode_time('03:04:05Z', False) == time(3, 4, 5)
assert _decode_time('03:04:05+00:00', False) == time(3, 4, 5)
assert _decode_time('03:04:05-00:00', False) == time(3, 4, 5)
assert _decode_time('12:00:00+07:08', False) == time(4, 52)
assert _decode_time('12:00:00-07:08', False) == time(19, 8)
def test_sanitize_contract_data(user):
contract = Contract(
user=user,
number="9911222777 ",
regional_direction=" 10",
)
contract.customer_code = "279311"
contract.status_code = "A"
contract.start_date = "2014-05-09 00:00:00-03:00"
contract.end_date = "2018-05-16 00:00:00-03:00"
assert contract.number == 9911222777
assert contract.regional_direction.number == 10
assert contract.customer_code == 279311
assert contract.status_code == "A"
assert contract.start_date == datetime(2014, 5, 9, 0, 0, tzinfo=timezone(timedelta(hours=-3)))
assert contract.end_date == datetime(2018, 5, 16, 0, 0, tzinfo=timezone(timedelta(hours=-3)))
def test_sanitize_posting_card_data(contract):
posting_card = PostingCard(
contract=contract,
number="0056789123",
administrative_code=8888888,
)
posting_card.start_date = "2014-05-09 00:00:00-03:00"
posting_card.end_date = "2018-05-16 00:00:00-03:00"
posting_card.status = "01"
posting_card.status_code = "I"
posting_card.unit = "08 "
assert posting_card.number == "0056789123"
assert posting_card.administrative_code == "08888888"
assert posting_card.start_date == datetime(2014, 5, 9, 0, 0, tzinfo=timezone(timedelta(hours=-3)))
assert posting_card.end_date == datetime(2018, 5, 16, 0, 0, tzinfo=timezone(timedelta(hours=-3)))
assert posting_card.status == 1
assert posting_card.status_code == "I"
assert posting_card.unit == 8
def parse_timezone(matches, default_timezone=UTC):
"""Parses ISO 8601 time zone specs into tzinfo offsets
"""
if matches["timezone"] == "Z":
return UTC
# This isn't strictly correct, but it's common to encounter dates without
# timezones so I'll assume the default (which defaults to UTC).
# Addresses issue 4.
if matches["timezone"] is None:
return default_timezone
sign = matches["tz_sign"]
hours = to_int(matches, "tz_hour")
minutes = to_int(matches, "tz_minute", default_to_zero=True)
description = "%s%02d:%02d" % (sign, hours, minutes)
if sign == "-":
hours = -hours
minutes = -minutes
return FixedOffset(hours, minutes, description)
def format_datetime(dt, usegmt=False):
"""Turn a datetime into a date string as specified in RFC 2822.
If usegmt is True, dt must be an aware datetime with an offset of zero. In
this case 'GMT' will be rendered instead of the normal +0000 required by
RFC2822. This is to support HTTP headers involving date stamps.
"""
now = dt.timetuple()
if usegmt:
if dt.tzinfo is None or dt.tzinfo != datetime.timezone.utc:
raise ValueError("usegmt option requires a UTC datetime")
zone = 'GMT'
elif dt.tzinfo is None:
zone = '-0000'
else:
zone = dt.strftime("%z")
return _format_timetuple_and_zone(now, zone)
def format(self, value, property, context):
if isinstance(value, datetime.datetime):
if value.tzinfo:
# DST ? ???? ???.
value = value.replace(tzinfo=timezone.utc) - value.utcoffset()
return int(calendar.timegm(value.timetuple())) + (value.microsecond / 1000000.0)
elif isinstance(value, datetime.time):
seconds = value.hour * 3600 + value.minute * 60 + value.second
if value.tzinfo:
# DST ? ???? ???.
seconds -= value.utcoffset().total_seconds()
return seconds % 86400 + (value.microsecond / 1000000.0)
elif isinstance(value, datetime.date):
return calendar.timegm(value.timetuple())
else:
raise ValueError()
def __init__(self, *args):
"""Constructor."""
from datetime import datetime, timezone, timedelta
# figure the local timezone
#
lt = datetime.now()
ut = datetime.utcnow()
lt2 = datetime.now()
if ut.second == lt2.second:
lt = lt2
dt = ut - lt
offset_minutes = 0
if (0 == dt.days):
offset_minutes = dt.seconds // 60
else:
dt = lt - ut
offset_minutes = dt.seconds // 60
offset_minutes *= -1
dt = timedelta(minutes=offset_minutes)
self.__tz = timezone(dt)
self.__utz = timezone(timedelta(0))
super().__init__(*args)
def format_datetime(dt, usegmt=False):
"""Turn a datetime into a date string as specified in RFC 2822.
If usegmt is True, dt must be an aware datetime with an offset of zero. In
this case 'GMT' will be rendered instead of the normal +0000 required by
RFC2822. This is to support HTTP headers involving date stamps.
"""
now = dt.timetuple()
if usegmt:
if dt.tzinfo is None or dt.tzinfo != datetime.timezone.utc:
raise ValueError("usegmt option requires a UTC datetime")
zone = 'GMT'
elif dt.tzinfo is None:
zone = '-0000'
else:
zone = dt.strftime("%z")
return _format_timetuple_and_zone(now, zone)
def _get_jst_from_utime(cls, timestamp):
"""
UNIXTIME ???????????????'+09:00'??????
1471084020 -> '2016-08-13 19:27:00'
:param int timestamp: UNIXTIME???
:rtype: str
"""
return str(datetime.fromtimestamp(timestamp, timezone(timedelta(hours=+9))))[:-6]
# @classmethod
# def _get_utime(cls):
# """
# ??? UNIXTIME ????
#
# '2016-08-13 19:27:00' -> 1471084020
#
# :rtype: int
# """
# return datetime.now().timestamp()
def _get_jst_from_utime(cls, timestamp):
"""
UNIXTIME ???????????????'+09:00'??????
1471084020 -> '2016-08-13 19:27:00'
:param int timestamp: UNIXTIME???
:rtype: str
"""
return str(datetime.fromtimestamp(timestamp, timezone(timedelta(hours=+9))))[:-6]
# @classmethod
# def _get_utime(cls):
# """
# ??? UNIXTIME ????
#
# '2016-08-13 19:27:00' -> 1471084020
#
# :rtype: int
# """
# return datetime.now().timestamp()
def timezone_from_str(tz_str):
"""
Convert a timezone string to a timezone object
:param tz_str: string with format 'UTC±[hh]:[mm]'
:return: a timezone object
"""
m = re.match(r'UTC([+|-]\d{1,2}):(\d{2})', tz_str)
delta_h = int(m.group(1))
delta_m = int(m.group(2)) if delta_h >= 0 else -int(m.group(2))
return timezone(timedelta(hours=delta_h, minutes=delta_m))
def fix_datetime(dt):
"""
Fix a datetime (supposed to be)
:param dt: datetime to fix
:return: correct datetime object
"""
if isinstance(dt, date):
dt = datetime(dt.year, dt.month, dt.day)
if dt is not None and dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone_from_str(C.timezone))
return dt
def test_create_attributes():
data = FancyEvent(
string_field='123456789',
uuid_field=uuid.UUID('72d9a041-f401-42b6-8556-72b3c00e43d8'),
)
now = datetime.datetime(2016, 12, 10, 11, 15, 45, tzinfo=datetime.timezone.utc)
attributes = encoding.create_attributes(data, now=now)
assert attributes == {
'type': 'FancyEvent',
'timestamp': '2016-12-10T11:15:45.000000Z',
}
def test_create_attributes_uses_current_date_for_timestamp(get_now_with_utc_timezone):
data = FancyEvent(
string_field='123456789',
uuid_field=uuid.UUID('72d9a041-f401-42b6-8556-72b3c00e43d8'),
)
get_now_with_utc_timezone.return_value = datetime.datetime(
2016, 12, 10, 11, 15, 45, tzinfo=datetime.timezone.utc)
attributes = encoding.create_attributes(data)
assert attributes == {
'type': 'FancyEvent',
'timestamp': '2016-12-10T11:15:45.000000Z',
}
def test_integration(self):
input = datetime.datetime(2016, 12, 10, 11, 15, 45, 123456,
tzinfo=datetime.timezone.utc)
encoded = encoding.datetime_to_rfc3339_string(input)
decoded = encoding.rfc3339_string_to_datetime(encoded)
assert decoded == input
def test_encoding_datetime_in_utc(self):
input = datetime.datetime(2016, 12, 10, 11, 15, 45, 123456,
tzinfo=datetime.timezone.utc)
encoded = encoding.datetime_to_rfc3339_string(input)
assert encoded == '2016-12-10T11:15:45.123456Z'
def test_encoding_datetime_not_in_utc(self):
some_timezone = datetime.timezone(datetime.timedelta(hours=-7))
input = datetime.datetime(2016, 12, 10, 11, 15, 45, 123456,
tzinfo=some_timezone)
encoded = encoding.datetime_to_rfc3339_string(input)
assert encoded == '2016-12-10T18:15:45.123456Z'
def TimeEnd(self, timeend):
if timeend is None:
self._timeend = datetime.now(tz=pytz.utc)
elif not isinstance(timeend, datetime):
raise TypeError("req.TimeEnd must be a datetime.datetime object.")
else:
# Always use timezone-aware datetime.
if timeend.tzinfo is None:
_logger.warning('Naive HistDataReq.TimeEnd. '
'Assumeing system local time zone.')
tz_system = get_localzone()
timeend = tz_system.localize(timeend)
self._timeend = timeend
def to_timestamp(dt_str, tz_str):
temp_time = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
if re.match(r'^UTC\+([0-9]|0[0-9]|1[0-2]):00$', tz_str):
temp_timezone = timezone(timedelta(hours=int(re.match(r'^UTC\+([0-9]|0[0-9]|1[0-2]):00$', tz_str).group(1))))
elif re.match(r'^UTC\-([0-9]|0[0-9]|1[0-2]):00$', tz_str):
temp_timezone = timezone(timedelta(hours=-int(re.match(r'^UTC\-([0-9]|0[0-9]|1[0-2]):00$', tz_str).group(1))))
dt = temp_time.replace(tzinfo=temp_timezone)
dt_timestamp = dt.timestamp()
return dt_timestamp
def get_time_zone(time_zone_str: str) -> Optional[dt.tzinfo]:
"""Get time zone from string. Return None if unable to determine.
Async friendly.
"""
try:
return pytz.timezone(time_zone_str)
except pytz.exceptions.UnknownTimeZoneError:
return None