def test_parse_datetime(self): # Valid inputs self.assertEqual(parse_datetime('2012-04-23T09:15:00'), datetime(2012, 4, 23, 9, 15)) self.assertEqual(parse_datetime('2012-4-9 4:8:16'), datetime(2012, 4, 9, 4, 8, 16)) self.assertEqual( parse_datetime('2012-04-23T09:15:00Z'), datetime(2012, 4, 23, 9, 15, 0, 0, get_fixed_timezone(0))) self.assertEqual( parse_datetime('2012-4-9 4:8:16-0320'), datetime(2012, 4, 9, 4, 8, 16, 0, get_fixed_timezone(-200))) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400+02:30'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(150))) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400+02'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(120))) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400-02'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(-120))) # Invalid inputs self.assertEqual(parse_datetime('20120423091500'), None) self.assertRaises(ValueError, parse_datetime, '2012-04-56T09:15:90')
def test_parse_datetime(self): # Valid inputs self.assertEqual( parse_datetime('2012-04-23T09:15:00'), datetime(2012, 4, 23, 9, 15) ) self.assertEqual( parse_datetime('2012-4-9 4:8:16'), datetime(2012, 4, 9, 4, 8, 16) ) self.assertEqual( parse_datetime('2012-04-23T09:15:00Z'), datetime(2012, 4, 23, 9, 15, 0, 0, get_fixed_timezone(0)) ) self.assertEqual( parse_datetime('2012-4-9 4:8:16-0320'), datetime(2012, 4, 9, 4, 8, 16, 0, get_fixed_timezone(-200)) ) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400+02:30'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(150)) ) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400+02'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(120)) ) self.assertEqual( parse_datetime('2012-04-23T10:20:30.400-02'), datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(-120)) ) # Invalid inputs self.assertIsNone(parse_datetime('20120423091500')) with self.assertRaises(ValueError): parse_datetime('2012-04-56T09:15:90')
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) with override_current_timezone(utc_plus_6): # Timezone-naive datetime assumed to be Django current_timezone self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], "2022-10-11 06:13:14") # 12:13 UTC+6 == 06:13 UTC # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], "2016-03-04 13:06:07") # 05:06 UTC-8 == 13:06 UTC # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], "2022-10-21 18:00:00") # 00:00 UTC+6 == 18:00-1d UTC # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], "2022-05-06 07:08:09") # String passed unchanged (this is *not* portable between ESPs) self.message.send_at = "2013-11-12 01:02:03" self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], "2013-11-12 01:02:03")
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() smtpapi = self.get_smtpapi() self.assertEqual(smtpapi['send_at'], timegm((2016, 3, 4, 13, 6, 7))) # 05:06 UTC-8 == 13:06 UTC # Timezone-naive datetime assumed to be Django current_timezone self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) # microseconds should get stripped self.message.send() smtpapi = self.get_smtpapi() self.assertEqual(smtpapi['send_at'], timegm((2022, 10, 11, 6, 13, 14))) # 12:13 UTC+6 == 06:13 UTC # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() smtpapi = self.get_smtpapi() self.assertEqual(smtpapi['send_at'], timegm((2022, 10, 21, 18, 0, 0))) # 00:00 UTC+6 == 18:00-1d UTC # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() smtpapi = self.get_smtpapi() self.assertEqual(smtpapi['send_at'], 1651820889)
def test_very_large_timezone(self): """ Timezone displacements must not be greater than 14 hours Or PostgreSQL won't accept them. """ datestrings = [ ("Wed, 1 Nov 2006 23:50:26 +1800", datetime.datetime(2006, 11, 1, 23, 50, 26, tzinfo=get_fixed_timezone(18 * 60))), ("Wed, 1 Nov 2006 23:50:26 -1800", datetime.datetime(2006, 11, 1, 23, 50, 26, tzinfo=get_fixed_timezone(-18 * 60))), ] for datestring, expected in datestrings: parsed = utils.parsedate(datestring) self.assertEqual(parsed, expected) self.assertTrue( parsed.utcoffset() <= datetime.timedelta(hours=13), "UTC offset %s for datetime %s is too large" % (parsed.utcoffset(), parsed))
def get_timezones(): shanghai = dict(tz=timezone.get_fixed_timezone(8 * 60), time_zone="Asia/Shanghai") landon = dict(tz=timezone.get_fixed_timezone(0), time_zone="Europe/London") return (shanghai, landon)
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() data = self.get_api_call_data() self.assertEqual(data['o:deliverytime'], "Fri, 04 Mar 2016 13:06:07 GMT") # 05:06 UTC-8 == 13:06 UTC # Timezone-naive datetime assumed to be Django current_timezone self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) self.message.send() data = self.get_api_call_data() self.assertEqual(data['o:deliverytime'], "Tue, 11 Oct 2022 06:13:14 GMT") # 12:13 UTC+6 == 06:13 UTC # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() data = self.get_api_call_data() self.assertEqual(data['o:deliverytime'], "Fri, 21 Oct 2022 18:00:00 GMT") # 00:00 UTC+6 == 18:00-1d UTC # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() data = self.get_api_call_data() self.assertEqual(data['o:deliverytime'], "Fri, 06 May 2022 07:08:09 GMT") # String passed unchanged (this is *not* portable between ESPs) self.message.send_at = "Thu, 13 Oct 2022 18:02:00 GMT" self.message.send() data = self.get_api_call_data() self.assertEqual(data['o:deliverytime'], "Thu, 13 Oct 2022 18:02:00 GMT")
def test_timezones(self): # Saving an updating with timezone-aware datetime Python objects. # Regression test for #10443. # The idea is that all these creations and saving should work without # crashing. It's not rocket science. dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=get_fixed_timezone(600)) dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=get_fixed_timezone(600)) obj = Article.objects.create(headline="A headline", pub_date=dt1, article_text="foo") obj.pub_date = dt2 obj.save() self.assertEqual( Article.objects.filter(headline="A headline").update(pub_date=dt1), 1)
def test_parse_datetime(self): valid_inputs = ( ('2012-04-23T09:15:00', datetime(2012, 4, 23, 9, 15)), ('2012-4-9 4:8:16', datetime(2012, 4, 9, 4, 8, 16)), ('2012-04-23T09:15:00Z', datetime(2012, 4, 23, 9, 15, 0, 0, get_fixed_timezone(0))), ('2012-4-9 4:8:16-0320', datetime(2012, 4, 9, 4, 8, 16, 0, get_fixed_timezone(-200))), ('2012-04-23T10:20:30.400+02:30', datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(150))), ('2012-04-23T10:20:30.400+02', datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(120))), ('2012-04-23T10:20:30.400-02', datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(-120))), ) for source, expected in valid_inputs: with self.subTest(source=source): self.assertEqual(parse_datetime(source), expected) # Invalid inputs self.assertIsNone(parse_datetime('20120423091500')) with self.assertRaises(ValueError): parse_datetime('2012-04-56T09:15:90')
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], timegm((2016, 3, 4, 13, 6, 7))) # 05:06 UTC-8 == 13:06 UTC # Timezone-naive datetime assumed to be Django current_timezone self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) # microseconds should get stripped self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], timegm((2022, 10, 11, 6, 13, 14))) # 12:13 UTC+6 == 06:13 UTC # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], timegm((2022, 10, 21, 18, 0, 0))) # 00:00 UTC+6 == 18:00-1d UTC # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() data = self.get_api_call_json() self.assertEqual(data['send_at'], 1651820889)
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) # SparkPost expects ISO-8601 YYYY-MM-DDTHH:MM:SS+-HH:MM with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2016-03-04T05:06:07-08:00") # Explicit UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc) self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2016-03-04T05:06:07+00:00") # Timezone-naive datetime assumed to be Django current_timezone # (also checks stripping microseconds) self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2022-10-11T12:13:14+06:00") # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2022-10-22T00:00:00+06:00") # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2022-05-06T07:08:09+00:00") # String passed unchanged (this is *not* portable between ESPs) self.message.send_at = "2022-10-13T18:02:00-11:30" self.message.send() data = self.get_api_call_json() self.assertEqual(data["options"]["start_time"], "2022-10-13T18:02:00-11:30")
def test_naturalday_tz(self): today = datetime.date.today() tz_one = get_fixed_timezone(-720) tz_two = get_fixed_timezone(720) # Can be today or yesterday date_one = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_one) naturalday_one = humanize.naturalday(date_one) # Can be today or tomorrow date_two = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_two) naturalday_two = humanize.naturalday(date_two) # As 24h of difference they will never be the same self.assertNotEqual(naturalday_one, naturalday_two)
def to_python(self, value): """ Validates that the input can be converted to a datetime. Returns a Python datetime.datetime object. """ if value in self.empty_values: return None try: unicode_value = force_text(value, strings_only=True) date = unicode_value[:-6] offset = unicode_value[-6:] local_date = self.strptime(value) if offset and offset[0] in ('-', '+'): tz_offset = timedelta(hours=int(offset[1:3]), minutes=int(offset[4:6])) tz_offset = tz_offset.seconds // 60 if offset[0] == '-': tz_offset *= -1 else: tz_offset = 0 tz_correction = timezone.get_fixed_timezone(tz_offset) return timezone.make_aware(local_date, tz_correction) except (IndexError, TypeError, ValueError) as e: raise ValidationError( self.error_messages['invalid'], code='invalid')
def to_python(self, value): """ Validates that the input can be converted to a datetime. Returns a Python datetime.datetime object. """ if value in self.empty_values: return None try: unicode_value = force_text(value, strings_only=True) date = unicode_value[:-6] offset = unicode_value[-6:] local_date = self.strptime(value) if offset and offset[0] in ('-', '+'): tz_offset = timedelta(hours=int(offset[1:3]), minutes=int(offset[4:6])) tz_offset = tz_offset.seconds // 60 if offset[0] == '-': tz_offset *= -1 else: tz_offset = 0 tz_correction = timezone.get_fixed_timezone(tz_offset) return timezone.make_aware(local_date, tz_correction) except (IndexError, TypeError, ValueError) as e: raise ValidationError(self.error_messages['invalid'], code='invalid')
def datetime_from_ldap(value): """Convert a LDAP-style datetime to a Python aware object. See https://tools.ietf.org/html/rfc4517#section-3.3.13 for details. Args: value (str): the datetime to parse """ if not value: return None match = LDAP_DATETIME_RE.match(value) if not match: return None groups = match.groupdict() if groups['microsecond']: groups['microsecond'] = groups['microsecond'].ljust(6, '0')[:6] tzinfo = groups.pop('tzinfo') if tzinfo == 'Z': tzinfo = timezone.utc else: offset_mins = int(tzinfo[-2:]) if len(tzinfo) == 5 else 0 offset = 60 * int(tzinfo[1:3]) + offset_mins if tzinfo[0] == '-': offset = - offset tzinfo = timezone.get_fixed_timezone(offset) kwargs = {k: int(v) for k, v in groups.items() if v is not None} kwargs['tzinfo'] = tzinfo return datetime.datetime(**kwargs)
def test_make_aware_no_tz(self): self.assertEqual( timezone.make_aware(datetime.datetime(2011, 9, 1, 13, 20, 30)), datetime.datetime( 2011, 9, 1, 13, 20, 30, tzinfo=timezone.get_fixed_timezone(-300) ), )
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) with self.assertRaises(AnymailUnsupportedFeature): self.message.send()
def process_contents(self): for post in self.contents: post_id = post["id"] identification = re.split("_", post_id) account_id = identification[0] post_id = identification[1] published_at = post["created_time"] published_at = datetime.strptime(published_at[0:10]+' '+published_at[11:19], '%Y-%m-%d %H:%M:%S') published_at = timezone.make_aware(published_at, timezone.get_fixed_timezone(0)) if "link" in post.keys(): original_url = post["link"] else: original_url = "https://www.facebook.com/"+account_id+"/posts/"+post_id def search(parameter): try: return post[parameter] except KeyError: return "" def amount(parameter): try: return self.graph.get(post['id']+'/'+parameter, summary='1')['summary']['total_count'] except KeyError: return 0 text = search("message") video_url = search("source") image_url = search("picture") image_id = search("object_id") post_type = search("type") number_of_likes = amount("likes") number_of_comments = amount("comments") if image_url and image_id: feed = self.graph.get(image_id) try: if post_type == 'video': image_url = sorted(feed['format'], key=lambda k: k['width'], reverse=True)[0]['picture'] else: image_url = sorted(feed['images'], key=lambda k: k['width'], reverse=True)[0]['source'] except KeyError: #Error finding image_url pass new_content = FacebookContent(identifier=post_id, text=text, published_at=published_at, image_url=image_url, original_url=original_url, number_of_comments=number_of_comments, number_of_likes=number_of_likes, video_url=video_url) try: if (text or video_url or image_url) and post_type != 'link': self.update_content(new_content) except Exception as err: print 'Could not save content %s: %s' % (new_content, err)
def process_contents(self): for tweet in self.contents: tweet_id = tweet["id_str"] text = tweet["text"] created_at = tweet["created_at"] published_at = datetime.strptime(created_at[4:19]+' '+created_at[26:30], '%b %d %H:%M:%S %Y') published_at = timezone.make_aware(published_at, timezone.get_fixed_timezone(0)) retweet_count = tweet["retweet_count"] favourite_count = tweet["favorite_count"] original_url = "https://twitter.com/"+tweet["user"]["screen_name"]+"/status/"+tweet_id try: image = tweet["entities"]["media"][0]["media_url_https"] except KeyError: image = None videos_or_urls = [] for video_or_url in tweet["entities"]["urls"]: videos_or_urls.append(video_or_url["expanded_url"]) new_content = TwitterContent(number_of_retweets=retweet_count, number_of_favourites=favourite_count, original_url=original_url, image_url=image, published_at=published_at, text=text, identifier=tweet_id) if len(videos_or_urls) > 0: new_content.video_url = videos_or_urls[0] self.update_content(new_content)
def get_queryset(self): user = self.request.user if user.is_anonymous or not user.is_staff: logger.warning('Permission required to get api usage') return [] tz = timezone.get_fixed_timezone(60) now = datetime.now().replace(tzinfo=tz) year = int(self.request.GET.get('year', now.year)) month = int(self.request.GET.get('month', now.month)) day = int(self.request.GET.get('day', now.day)) hour = int(self.request.GET.get('hour', now.hour)) minutes = int(self.request.GET.get('min', now.minute)) seconds = int(self.request.GET.get('sec', now.second)) start_date = datetime(year=year, month=month, day=day, hour=hour, minute=minutes, second=seconds).replace(tzinfo=tz) logger.info('%s requesting api usage after %d-%d-%d %d:%d:%d' % (user.username, year, month, day, hour, minutes, seconds)) cursor = connection.cursor() raw_sql = '''SELECT * FROM stats_apiusage where time >= '%s-%s-%s %s:%s:%s+02' ''' usage = ApiUsage.objects.raw( raw_sql, params=[year, month, day, hour, minutes, seconds]) logger.info('%d api usage found' % len(usage)) return usage
def parseAsn1Generalizedtime(value): """ Parses an ASN1 GENERALIZEDTIME timestamp as used by pyOpenSSL. @type value: string @param value: ASN1 GENERALIZEDTIME timestamp @return: datetime in UTC """ value = value.decode('utf-8') m = _ASN1_TIME_REGEX.match(value) if m: # We have an offset asn1time = m.group(1) sign = m.group(2) hours = int(m.group(3)) minutes = int(m.group(4)) utcoffset = 60 * hours + minutes if sign == '-': utcoffset = -utcoffset else: if not value.endswith("Z"): raise ValueError("Missing timezone") asn1time = value[:-1] utcoffset = 0 parsed = time.strptime(asn1time, "%Y%m%d%H%M%S") return datetime.datetime(*(parsed[:7]), tzinfo=get_fixed_timezone(utcoffset))
def as_message(self, escape_addresses=True): # http://wordeology.com/computer/how-to-send-good-unicode-email-with-python.html # http://stackoverflow.com/questions/31714221/how-to-send-an-email-with-quoted # http://stackoverflow.com/questions/9403265/how-do-i-use-python/9509718#9509718 charset = Charset('utf-8') charset.header_encoding = QP charset.body_encoding = QP msg = MIMEMultipart() # Headers unixfrom = "From %s %s" % ( self.sender.address, self.archived_date.strftime("%c")) header_from = self.sender.address if self.sender.name and self.sender.name != self.sender.address: header_from = "%s <%s>" % (self.sender.name, header_from) header_to = self.mailinglist.name if escape_addresses: header_from = header_from.replace("@", " at ") header_to = header_to.replace("@", " at ") unixfrom = unixfrom.replace("@", " at ") msg.set_unixfrom(unixfrom) headers = ( ("From", header_from), ("To", header_to), ("Subject", self.subject), ) for header_name, header_value in headers: if not header_value: continue try: msg[header_name] = header_value.encode('ascii') except UnicodeEncodeError: msg[header_name] = Header( header_value.encode('utf-8'), charset).encode() tz = get_fixed_timezone(self.timezone) header_date = self.date.astimezone(tz).replace(microsecond=0) # Date format: http://tools.ietf.org/html/rfc5322#section-3.3 msg["Date"] = header_date.strftime("%a, %d %b %Y %H:%M:%S %z") msg["Message-ID"] = "<%s>" % self.message_id if self.in_reply_to: msg["In-Reply-To"] = self.in_reply_to # Body content = self.ADDRESS_REPLACE_RE.sub(r"\1(a)\2", self.content) # Don't use MIMEText, it won't encode to quoted-printable textpart = MIMENonMultipart("text", "plain", charset='utf-8') textpart.set_payload(content, charset=charset) msg.attach(textpart) # Attachments for attachment in self.attachments.order_by("counter"): mimetype = attachment.content_type.split('/', 1) part = MIMEBase(mimetype[0], mimetype[1]) part.set_payload(attachment.content) encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=attachment.name) msg.attach(part) return msg
def datetime_from_ldap(value): """Convert a LDAP-style datetime to a Python aware object. See https://tools.ietf.org/html/rfc4517#section-3.3.13 for details. Args: value (str): the datetime to parse """ if not value: return None match = LDAP_DATETIME_RE.match(value) if not match: return None groups = match.groupdict() if groups['microsecond']: groups['microsecond'] = groups['microsecond'].ljust(6, '0')[:6] tzinfo = groups.pop('tzinfo') if tzinfo == 'Z': tzinfo = timezone.utc else: offset_mins = int(tzinfo[-2:]) if len(tzinfo) == 5 else 0 offset = 60 * int(tzinfo[1:3]) + offset_mins if tzinfo[0] == '-': offset = -offset tzinfo = timezone.get_fixed_timezone(offset) kwargs = {k: int(v) for k, v in groups.items() if v is not None} kwargs['tzinfo'] = tzinfo return datetime.datetime(**kwargs)
def _format_time_ago(dt, now=None, full=False, ago_in=False, two_days=False): if not isinstance(dt, timedelta): if now is None: now = timezone.localtime( timezone=timezone.get_fixed_timezone(-int(t.timezone / 60))) original_dt = dt dt = _parse(dt) now = _parse(now) if dt is None: raise ValueError( 'The parameter `dt` should be datetime timedelta, or datetime formatted string.' ) if now is None: raise ValueError( 'the parameter `now` should be datetime, or datetime formatted string.' ) result = relativedelta.relativedelta(dt, now) flag, result = _format_relativedelta(result, full, two_days, original_dt) if ago_in and flag is not None: result = 'in {}'.format(result) if flag else '{} ago'.format( result) return result
def get_range_time(self): tz = 'Asia/Shanghai' # realtime_between前端之前给时间范围 dsl_period = self.dsl['period'] if dsl_period['type'] == 'today': now = datetime.datetime.now(tz=tz) else: now = datetime.datetime.now(tz=tz) - datetime.timedelta(days=1) start_time = self.datetime_add_tz(now, tz=now.tzinfo) end_day = now + datetime.timedelta(days=1) end_time = self.datetime_add_tz(end_day, end_day.tzinfo) if dsl_period['type'] == 'today': end_time = datetime.datetime.now(tz=tz) tz = 'Asia/Shanghai' tz = timezone.get_fixed_timezone(8 * 60) now = datetime.datetime.now(tz=tz) print(now) print(type(datetime_add_tz(now, now.tzinfo))) end_time = datetime.datetime.now(tz=tz) + datetime.timedelta(days=1) print(datetime_add_tz(end_time, end_time.tzinfo)) return start_time, end_time
def parse_iso8601_string(value): """turns ISO 8601 string into datetime object""" value = force_text(value, strings_only=True).rstrip('Z') for format in ISO8601_FORMATS: try: parsed_value = datetime.strptime(value, format) break except ValueError: try: parsed_value = datetime.strptime(value[:-6], format) break except ValueError: pass else: raise ValueError('failed to hydrate the %s timestamp' % value) offset_str = value[-6:] if offset_str and offset_str[0] in ('-', '+'): tz_offset = timedelta(hours=int(offset_str[1:3]), minutes=int(offset_str[4:6])) tz_offset = tz_offset.seconds // 60 if offset_str[0] == '-': tz_offset *= -1 else: tz_offset = 0 tz_correction = timezone.get_fixed_timezone(tz_offset) return timezone.make_aware(parsed_value, tz_correction)
def _test_file_time_getter_tz_handling_off(self, getter): # Django's TZ (and hence the system TZ) is set to Africa/Algiers which # is UTC+1 and has no DST change. We can set the Django TZ to something # else so that UTC, Django's TIME_ZONE, and the system timezone are all # different. now_in_algiers = timezone.make_aware(datetime.now()) with timezone.override(timezone.get_fixed_timezone(-300)): # At this point the system TZ is +1 and the Django TZ # is -5. self.assertFalse(self.storage.exists('test.file.tz.off')) f = ContentFile('custom contents') f_name = self.storage.save('test.file.tz.off', f) self.addCleanup(self.storage.delete, f_name) dt = getter(f_name) # dt should be naive, in system (+1) TZ self.assertTrue(timezone.is_naive(dt)) # The three timezones are indeed distinct. naive_now = datetime.now() algiers_offset = now_in_algiers.tzinfo.utcoffset(naive_now) django_offset = timezone.get_current_timezone().utcoffset(naive_now) utc_offset = timezone.utc.utcoffset(naive_now) self.assertGreater(algiers_offset, utc_offset) self.assertLess(django_offset, utc_offset) # dt and naive_now should be the same effective time. self.assertLess(abs(dt - naive_now), timedelta(seconds=2)) # If we convert dt to an aware object using the Algiers # timezone then it should be the same effective time to # now_in_algiers. _dt = timezone.make_aware(dt, now_in_algiers.tzinfo) self.assertLess(abs(_dt - now_in_algiers), timedelta(seconds=2))
def get_tweet_date(tweet): """ Return the django date of the given tweet's created time. """ dt = to_datetime(tweet['created_at']) return timezone.localtime(timezone.make_aware(dt, timezone=timezone.get_fixed_timezone(0)))
def clean_value(self, qualifier, v): # Match value match = self.time_re.match(v) if not match: raise ValidationError( 'Invalid HH:MM:SS(.mmm) value {{{}}} for {}.'.format( v, self.field_description())) # Get values hour, minute, second, microsecond, tzinfo = match.groups() hour = int(hour) minute = int(minute) second = int(second) microsecond = int((microsecond or '').ljust(6, '0')) if tzinfo == 'Z': tzinfo = timezone.utc else: tzinfo = tzinfo.ljust(5, '0') offset = int(tzinfo[1:3]) * 60 + int(tzinfo[3:5]) if tzinfo.startswith('-'): offset = -offset tzinfo = timezone.get_fixed_timezone(offset) # Create time object return time( hour=hour, minute=minute, second=second, microsecond=microsecond, tzinfo=tzinfo, )
def do_import(annotations, gallery, commenter): sys.stderr.write("Importing {} images to gallery '{}'\n" .format(len(annotations), gallery.title)) ndigits = len(str(len(annotations)-1)) comment_timestamp = timezone.make_aware(datetime(2015, 10, 4, 20, 0), timezone.get_fixed_timezone(-240)) for seq, ann in enumerate(annotations): sys.stderr.write(ann.fname + "\n") img = GalleryImage(gallery = gallery, sort_order = seq, date = ann.date, notes = ann.desc) img.save() if ann.photog: img.photographer.set(ann.photog) if ann.loc: img.location.set(ann.loc) if ann.people: img.people.set(*ann.people) if ann.tags: img.tags.set(*ann.tags) ifile = ImageFile(open(ann.fname, 'rb')) img.image.save("I{1:0{0}}.jpg".format(ndigits, seq), ifile) img.save() if ann.comment: comment = GalleryComment(image = img, user = commenter, date = comment_timestamp, comment = ann.comment) comment.save()
def add_bookmark(request): if request.user.is_authenticated(): user = request.user url = request.POST['url'] title = request.POST['title'] timestamp = request.POST['datetime'] # get timezone offset from request and turn it into tzinfo object timezone = get_fixed_timezone(int(request.POST['timezone'])) date = datetime.datetime.fromtimestamp(float(timestamp), timezone) date_created, date_updated = date, date ext = tldextract.extract(url) domain = '.'.join(ext[:2]) bookmark = Bookmark( url = url, title = title, owner = user, date_created = date_created, date_updated = date_updated, domain = domain) bookmark.save() else: redirect('/accounts/login/', permanent=True) return HttpResponse(request)
def clean(self): cleaned_data = super().clean() if "quizz_sending" not in cleaned_data: raise forms.ValidationError( "Ce quizz n'existe pas. Vérifiez la date.") if "email" not in cleaned_data: raise forms.ValidationError("Cet email est inconnu.") quizz_sending = QuizzSending.objects.get( pk=cleaned_data["quizz_sending"]) if not quizz_sending.group.persons.filter(email=cleaned_data["email"]): raise forms.ValidationError("Ce quizz n'est pas fait pour vous.") if not any(( self.cleaned_data["answer0"], self.cleaned_data["answer1"], self.cleaned_data["answer2"], self.cleaned_data["answer3"], self.cleaned_data["answer4"], self.cleaned_data["answer5"], self.cleaned_data["answer6"], self.cleaned_data["answer7"], self.cleaned_data["answer8"], self.cleaned_data["answer9"], )): raise forms.ValidationError("Aucune réponse n'a été fournie.") already_given_answers = (Answer.objects.filter( quizz_sending=quizz_sending).filter(person=Person.objects.get( email=self.cleaned_data["email"])).filter( question=Question.objects.get( pk=self.cleaned_data["question"]))) if already_given_answers: raise forms.ValidationError( "Une réponse a déjà été fournie à la question précédente.") if datetime.now(tz=get_fixed_timezone(1)) > quizz_sending.end_date: raise forms.ValidationError("Ce quiz est maintenant terminé")
def _test_file_time_getter_tz_handling_on(self, getter): # Django's TZ (and hence the system TZ) is set to Africa/Algiers which # is UTC+1 and has no DST change. We can set the Django TZ to something # else so that UTC, Django's TIME_ZONE, and the system timezone are all # different. now_in_algiers = timezone.make_aware(datetime.now()) # Use a fixed offset timezone so we don't need pytz. with timezone.override(timezone.get_fixed_timezone(-300)): # At this point the system TZ is +1 and the Django TZ # is -5. The following will be aware in UTC. now = timezone.now() self.assertFalse(self.storage.exists('test.file.tz.on')) f = ContentFile('custom contents') f_name = self.storage.save('test.file.tz.on', f) self.addCleanup(self.storage.delete, f_name) dt = getter(f_name) # dt should be aware, in UTC self.assertTrue(timezone.is_aware(dt)) self.assertEqual(now.tzname(), dt.tzname()) # Check that the three timezones are indeed distinct. naive_now = datetime.now() algiers_offset = now_in_algiers.tzinfo.utcoffset(naive_now) django_offset = timezone.get_current_timezone().utcoffset(naive_now) utc_offset = timezone.utc.utcoffset(naive_now) self.assertGreater(algiers_offset, utc_offset) self.assertLess(django_offset, utc_offset) # dt and now should be the same effective time. self.assertLess(abs(dt - now), timedelta(seconds=2))
def iso_8601_to_datetime(iso): """Parse an iso 8601 string into a timezone aware datetime, ignoring and fractional seconds.""" if not iso: return None dt = datetime.datetime.strptime(iso[:19], '%Y-%m-%dT%H:%M:%S') # strptime doesn't seem to handle timezones, parse them here if len(iso) == 19: return timezone.make_aware(dt, timezone.get_current_timezone()) else: # Make the datetime UTC if Z is the timezone, ignoring fractional seconds in between if (len(iso) == 20 or iso[19] == '.') and iso[-1] == 'Z': return timezone.make_aware(dt, timezone.UTC()) # Parse a complete timezone e.g. +00:00, checking for the correct length or ignored fractional seconds if (len(iso) == 25 or iso[19] == '.') and iso[-6] in ('+', '-') and iso[-3] == ':': try: hours = int(iso[-5:-3]) minutes = int(iso[-2:]) minutes += hours * 60 if iso[-6] == '-': minutes = -minutes return timezone.make_aware( dt, timezone.get_fixed_timezone(minutes)) except: # drop through and raise the exception pass raise ValueError('Invalid timezone %s.' % iso[19:])
def test_open_event(self): raw_event = { "FirstOpen": True, "Client": {"Name": "Gmail", "Company": "Google", "Family": "Gmail"}, "OS": {"Name": "unknown", "Company": "unknown", "Family": "unknown"}, "Platform": "Unknown", "UserAgent": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0", "ReadSeconds": 0, "Geo": {}, "MessageID": "f4830d10-9c35-4f0c-bca3-3d9b459821f8", "ReceivedAt": "2016-04-27T16:21:41.2493688-04:00", "Recipient": "*****@*****.**" } webhook = reverse('postmark_tracking_webhook') response = self.client.post(webhook, content_type='application/json', data=json.dumps(raw_event)) self.assertEqual(response.status_code, 200) kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView, event=ANY, esp_name='Postmark') event = kwargs['event'] self.assertIsInstance(event, AnymailTrackingEvent) self.assertEqual(event.event_type, "opened") self.assertEqual(event.esp_event, raw_event) self.assertEqual(event.timestamp, datetime(2016, 4, 27, 16, 21, 41, microsecond=249368, tzinfo=get_fixed_timezone(-4*60))) self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8") self.assertEqual(event.recipient, "*****@*****.**") self.assertEqual(event.user_agent, "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0")
def parse_iso8601_string(value): value = force_text(value, strings_only=True).rstrip('Z') for format in ISO8601_FORMATS: try: parsed_value = datetime.strptime(value, format) break except ValueError: try: parsed_value = datetime.strptime(value[:-6], format) break except ValueError: pass else: raise ValueError('failed to hydrate the %s timestamp' % value) offset_str = value[-6:] if offset_str and offset_str[0] in ('-', '+'): tz_offset = timedelta(hours=int(offset_str[1:3]), minutes=int(offset_str[4:6])) tz_offset = tz_offset.seconds // 60 if offset_str[0] == '-': tz_offset *= -1 else: tz_offset = 0 tz_correction = timezone.get_fixed_timezone(tz_offset) return timezone.make_aware(parsed_value, tz_correction)
def test_serialize_datetime(self): self.assertSerializedEqual(datetime.datetime.utcnow()) self.assertSerializedEqual(datetime.datetime.utcnow) self.assertSerializedEqual(datetime.datetime.today()) self.assertSerializedEqual(datetime.datetime.today) self.assertSerializedEqual(datetime.date.today()) self.assertSerializedEqual(datetime.date.today) self.assertSerializedEqual(datetime.datetime.now().time()) self.assertSerializedEqual( datetime.datetime(2014, 1, 1, 1, 1, tzinfo=get_default_timezone())) self.assertSerializedEqual( datetime.datetime(2013, 12, 31, 22, 1, tzinfo=get_fixed_timezone(180))) self.assertSerializedResultEqual( datetime.datetime(2014, 1, 1, 1, 1), ("datetime.datetime(2014, 1, 1, 1, 1)", {'import datetime'})) self.assertSerializedResultEqual( datetime.datetime(2012, 1, 1, 1, 1, tzinfo=utc), ( "datetime.datetime(2012, 1, 1, 1, 1, tzinfo=utc)", {'import datetime', 'from django.utils.timezone import utc'}, ))
def test_time_range(self): # type: () -> None HOUR = timedelta(hours=1) DAY = timedelta(days=1) TZINFO = get_fixed_timezone(-100) # 100 minutes west of UTC # Using 22:59 so that converting to UTC and applying floor_to_{hour,day} do not commute a_time = datetime(2016, 3, 14, 22, 59).replace(tzinfo=TZINFO) floor_hour = datetime(2016, 3, 14, 22).replace(tzinfo=TZINFO) floor_day = datetime(2016, 3, 14).replace(tzinfo=TZINFO) # test start == end self.assertEqual(time_range(a_time, a_time, CountStat.HOUR, None), []) self.assertEqual(time_range(a_time, a_time, CountStat.DAY, None), []) # test start == end == boundary, and min_length == 0 self.assertEqual(time_range(floor_hour, floor_hour, CountStat.HOUR, 0), [floor_hour]) self.assertEqual(time_range(floor_day, floor_day, CountStat.DAY, 0), [floor_day]) # test start and end on different boundaries self.assertEqual(time_range(floor_hour, floor_hour+HOUR, CountStat.HOUR, None), [floor_hour, floor_hour+HOUR]) self.assertEqual(time_range(floor_day, floor_day+DAY, CountStat.DAY, None), [floor_day, floor_day+DAY]) # test min_length self.assertEqual(time_range(floor_hour, floor_hour+HOUR, CountStat.HOUR, 4), [floor_hour-2*HOUR, floor_hour-HOUR, floor_hour, floor_hour+HOUR]) self.assertEqual(time_range(floor_day, floor_day+DAY, CountStat.DAY, 4), [floor_day-2*DAY, floor_day-DAY, floor_day, floor_day+DAY])
def parse_datetime(value): """Parse a string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, the output uses a timezone with a fixed offset from UTC. Raise ValueError if the input is well formatted but not a valid datetime. Return None if the input isn't well formatted. """ match = datetime_re.match(value) if match: kw = match.groupdict() kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust( 6, '0') tzinfo = kw.pop('tzinfo') if tzinfo == 'Z': tzinfo = utc elif tzinfo is not None: offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0 offset = 60 * int(tzinfo[1:3]) + offset_mins if tzinfo[0] == '-': offset = -offset tzinfo = get_fixed_timezone(offset) kw = {k: int(v) for k, v in kw.items() if v is not None} kw['tzinfo'] = tzinfo return datetime.datetime(**kw)
def parse_datetime(value): """Parse a string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, the output uses a timezone with a fixed offset from UTC. Raise ValueError if the input is well formatted but not a valid datetime. Return None if the input isn't well formatted. """ try: return datetime.datetime.fromisoformat(value) except ValueError: if match := datetime_re.match(value): kw = match.groupdict() kw["microsecond"] = kw["microsecond"] and kw["microsecond"].ljust( 6, "0") tzinfo = kw.pop("tzinfo") if tzinfo == "Z": tzinfo = utc elif tzinfo is not None: offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0 offset = 60 * int(tzinfo[1:3]) + offset_mins if tzinfo[0] == "-": offset = -offset tzinfo = get_fixed_timezone(offset) kw = {k: int(v) for k, v in kw.items() if v is not None} return datetime.datetime(**kw, tzinfo=tzinfo)
def test_timezones(self): # Saving an updating with timezone-aware datetime Python objects. # Regression test for #10443. # The idea is that all these creations and saving should work without # crashing. It's not rocket science. dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=get_fixed_timezone(600)) dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=get_fixed_timezone(600)) obj = Article.objects.create( headline="A headline", pub_date=dt1, article_text="foo" ) obj.pub_date = dt2 obj.save() self.assertEqual( Article.objects.filter(headline="A headline").update(pub_date=dt1), 1 )
def parse_datetime(value): """Parses a string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, the output uses a timezone with a fixed offset from UTC. Raises ValueError if the input is well formatted but not a valid datetime. Returns None if the input isn't well formatted. """ match = datetime_re.match(value) if match: kw = match.groupdict() if kw['microsecond']: kw['microsecond'] = kw['microsecond'].ljust(6, '0') tzinfo = kw.pop('tzinfo') if tzinfo == 'Z': tzinfo = utc elif tzinfo is not None: offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0 offset = 60 * int(tzinfo[1:3]) + offset_mins if tzinfo[0] == '-': offset = -offset tzinfo = get_fixed_timezone(offset) kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} kw['tzinfo'] = tzinfo return datetime.datetime(**kw)
def test_time_range(self): # type: () -> None HOUR = timedelta(hours=1) DAY = timedelta(days=1) TZINFO = get_fixed_timezone(-100) # 100 minutes west of UTC # Using 22:59 so that converting to UTC and applying floor_to_{hour,day} do not commute a_time = datetime(2016, 3, 14, 22, 59).replace(tzinfo=TZINFO) floor_hour = datetime(2016, 3, 14, 22).replace(tzinfo=TZINFO) floor_day = datetime(2016, 3, 14).replace(tzinfo=TZINFO) # test start == end self.assertEqual(time_range(a_time, a_time, CountStat.HOUR, None), []) self.assertEqual(time_range(a_time, a_time, CountStat.DAY, None), []) # test start == end == boundary, and min_length == 0 self.assertEqual(time_range(floor_hour, floor_hour, CountStat.HOUR, 0), [floor_hour]) self.assertEqual(time_range(floor_day, floor_day, CountStat.DAY, 0), [floor_day]) # test start and end on different boundaries self.assertEqual( time_range(floor_hour, floor_hour + HOUR, CountStat.HOUR, None), [floor_hour, floor_hour + HOUR]) self.assertEqual( time_range(floor_day, floor_day + DAY, CountStat.DAY, None), [floor_day, floor_day + DAY]) # test min_length self.assertEqual( time_range(floor_hour, floor_hour + HOUR, CountStat.HOUR, 4), [ floor_hour - 2 * HOUR, floor_hour - HOUR, floor_hour, floor_hour + HOUR ]) self.assertEqual( time_range(floor_day, floor_day + DAY, CountStat.DAY, 4), [floor_day - 2 * DAY, floor_day - DAY, floor_day, floor_day + DAY])
def _test_file_time_getter_tz_handling_on(self, getter): # Django's TZ (and hence the system TZ) is set to Africa/Algiers which # is UTC+1 and has no DST change. We can set the Django TZ to something # else so that UTC, Django's TIME_ZONE, and the system timezone are all # different. now_in_algiers = timezone.make_aware(datetime.now()) # Use a fixed offset timezone so we don't need pytz. with timezone.override(timezone.get_fixed_timezone(-300)): # At this point the system TZ is +1 and the Django TZ # is -5. The following will be aware in UTC. now = timezone.now() self.assertFalse(self.storage.exists('test.file.tz.on')) f = ContentFile('custom contents') f_name = self.storage.save('test.file.tz.on', f) self.addCleanup(self.storage.delete, f_name) dt = getter(f_name) # dt should be aware, in UTC self.assertTrue(timezone.is_aware(dt)) self.assertEqual(now.tzname(), dt.tzname()) # Check that the three timezones are indeed distinct. naive_now = datetime.now() algiers_offset = now_in_algiers.tzinfo.utcoffset(naive_now) django_offset = timezone.get_current_timezone().utcoffset( naive_now) utc_offset = timezone.utc.utcoffset(naive_now) self.assertGreater(algiers_offset, utc_offset) self.assertLess(django_offset, utc_offset) # dt and now should be the same effective time. self.assertLess(abs(dt - now), timedelta(seconds=2))
def test_timezones(self): my_birthday = datetime(1979, 7, 8, 22, 00) summertime = datetime(2005, 10, 30, 1, 00) wintertime = datetime(2005, 10, 30, 4, 00) timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456) # 3h30m to the west of UTC tz = get_fixed_timezone(-210) aware_dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) if TZ_SUPPORT: self.assertEqual(dateformat.format(my_birthday, 'O'), '+0100') self.assertEqual(dateformat.format(my_birthday, 'r'), 'Sun, 8 Jul 1979 22:00:00 +0100') self.assertEqual(dateformat.format(my_birthday, 'T'), 'CET') self.assertEqual(dateformat.format(my_birthday, 'e'), '') self.assertEqual(dateformat.format(aware_dt, 'e'), '-0330') self.assertEqual(dateformat.format(my_birthday, 'U'), '300315600') self.assertEqual(dateformat.format(timestamp, 'u'), '123456') self.assertEqual(dateformat.format(my_birthday, 'Z'), '3600') self.assertEqual(dateformat.format(summertime, 'I'), '1') self.assertEqual(dateformat.format(summertime, 'O'), '+0200') self.assertEqual(dateformat.format(wintertime, 'I'), '0') self.assertEqual(dateformat.format(wintertime, 'O'), '+0100') # Ticket #16924 -- We don't need timezone support to test this self.assertEqual(dateformat.format(aware_dt, 'O'), '-0330')
def test_timezones(self): my_birthday = datetime(1979, 7, 8, 22, 00) summertime = datetime(2005, 10, 30, 1, 00) wintertime = datetime(2005, 10, 30, 4, 00) timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456) # 3h30m to the west of UTC tz = get_fixed_timezone(-210) aware_dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) if TZ_SUPPORT: self.assertEqual(dateformat.format(my_birthday, 'O'), '+0100') self.assertEqual(dateformat.format(my_birthday, 'r'), 'Sun, 08 Jul 1979 22:00:00 +0100') self.assertEqual(dateformat.format(my_birthday, 'T'), 'CET') self.assertEqual(dateformat.format(my_birthday, 'e'), '') self.assertEqual(dateformat.format(aware_dt, 'e'), '-0330') self.assertEqual(dateformat.format(my_birthday, 'U'), '300315600') self.assertEqual(dateformat.format(timestamp, 'u'), '123456') self.assertEqual(dateformat.format(my_birthday, 'Z'), '3600') self.assertEqual(dateformat.format(summertime, 'I'), '1') self.assertEqual(dateformat.format(summertime, 'O'), '+0200') self.assertEqual(dateformat.format(wintertime, 'I'), '0') self.assertEqual(dateformat.format(wintertime, 'O'), '+0100') # Ticket #16924 -- We don't need timezone support to test this self.assertEqual(dateformat.format(aware_dt, 'O'), '-0330')
def test_datetime_with_tzinfo(self): tz = get_fixed_timezone(-510) ltz = get_default_timezone() dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz), dt) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.astimezone(ltz).replace(tzinfo=None)) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple(), dt.utctimetuple()) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple(), dt.utctimetuple())
def test_different_timezones(self): """ When using two different timezones. """ now = datetime.datetime.now() now_tz = timezone.make_aware(now, timezone.get_default_timezone()) now_tz_i = timezone.localtime(now_tz, timezone.get_fixed_timezone(195)) self.assertEqual(timesince(now), "0\xa0minutes") self.assertEqual(timesince(now_tz), "0\xa0minutes") self.assertEqual(timeuntil(now_tz, now_tz_i), "0\xa0minutes")
def test_very_large_timezone(self): """ Timezone displacements must not be greater than 14 hours Or PostgreSQL won't accept them. """ datestrings = [ ("Wed, 1 Nov 2006 23:50:26 +1800", datetime.datetime(2006, 11, 1, 23, 50, 26, tzinfo=get_fixed_timezone(18*60))), ("Wed, 1 Nov 2006 23:50:26 -1800", datetime.datetime(2006, 11, 1, 23, 50, 26, tzinfo=get_fixed_timezone(-18*60))), ] for datestring, expected in datestrings: parsed = utils.parsedate(datestring) self.assertEqual(parsed, expected) self.assertTrue(parsed.utcoffset() <= datetime.timedelta(hours=13), "UTC offset %s for datetime %s is too large" % (parsed.utcoffset(), parsed))
def test_datetime_with_tzinfo(self): tz = get_fixed_timezone(-510) ltz = get_default_timezone() dt = make_aware(datetime(2009, 5, 16, 5, 30, 30), ltz) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz), dt) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) # astimezone() is safe here because the target timezone doesn't have DST self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.astimezone(ltz).replace(tzinfo=None)) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple(), dt.utctimetuple()) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple(), dt.utctimetuple())
def test_send_at(self): utc_plus_6 = get_fixed_timezone(6 * 60) utc_minus_8 = get_fixed_timezone(-8 * 60) # SparkPost expects ISO-8601 YYYY-MM-DDTHH:MM:SS+-HH:MM with override_current_timezone(utc_plus_6): # Timezone-aware datetime converted to UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc_minus_8) self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2016-03-04T05:06:07-08:00") # Explicit UTC: self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc) self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2016-03-04T05:06:07+00:00") # Timezone-naive datetime assumed to be Django current_timezone # (also checks stripping microseconds) self.message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567) self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2022-10-11T12:13:14+06:00") # Date-only treated as midnight in current timezone self.message.send_at = date(2022, 10, 22) self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2022-10-22T00:00:00+06:00") # POSIX timestamp self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2022-05-06T07:08:09+00:00") # String passed unchanged (this is *not* portable between ESPs) self.message.send_at = "2022-10-13T18:02:00-11:30" self.message.send() params = self.get_send_params() self.assertEqual(params['start_time'], "2022-10-13T18:02:00-11:30")
def test_serialise_with_aware_datetime(self): """ This tests that aware datetimes are converted to as UTC """ # make an aware datetime, consisting of WAGTAIL_05_RELEASE_DATETIME # in a timezone 1hr west of UTC one_hour_west = timezone.get_fixed_timezone(-60) local_time = timezone.make_aware(self.WAGTAIL_05_RELEASE_DATETIME, one_hour_west) log = Log(time=local_time, data="Wagtail 0.5 released") log_json = json.loads(log.to_json()) # Now check that the time is stored correctly with the timezone information at the end self.assertEqual(log_json['time'], '2014-08-01T12:01:42Z')
def _format_time_ago(dt, now=None, full=False, ago_in=False): if not isinstance(dt, timedelta): if now is None: now = timezone.localtime(timezone=timezone.get_fixed_timezone(-int(t.timezone / 60))) dt = _parse(dt) now = _parse(now) if dt is None: raise ValueError('The parameter `dt` should be datetime timedelta, or datetime formatted string.') if now is None: raise ValueError('the parameter `now` should be datetime, or datetime formatted string.') result = relativedelta.relativedelta(dt, now) flag, result = _format_relativedelta(result, full) if ago_in and flag is not None: result = 'in {}'.format(result) if flag else '{} ago'.format(result) return result