mirror of
https://github.com/powerline/powerline.git
synced 2025-07-25 14:54:54 +02:00
Add timezone argument to date and fuzzy_time segments (#2097)
* add basic timezone support
This commit is contained in:
parent
da3ed7e720
commit
59a5425597
@ -4,22 +4,33 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
def date(pl, format='%Y-%m-%d', istime=False):
|
def date(pl, format='%Y-%m-%d', istime=False, timezone=None):
|
||||||
'''Return the current date.
|
'''Return the current date.
|
||||||
|
|
||||||
:param str format:
|
:param str format:
|
||||||
strftime-style date format string
|
strftime-style date format string
|
||||||
:param bool istime:
|
:param bool istime:
|
||||||
If true then segment uses ``time`` highlight group.
|
If true then segment uses ``time`` highlight group.
|
||||||
|
:param string timezone:
|
||||||
|
Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
|
||||||
|
(Defaults to system defaults.)
|
||||||
|
|
||||||
Divider highlight group used: ``time:divider``.
|
Divider highlight group used: ``time:divider``.
|
||||||
|
|
||||||
Highlight groups used: ``time`` or ``date``.
|
Highlight groups used: ``time`` or ``date``.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
contents = datetime.now().strftime(format)
|
tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
|
||||||
|
except ValueError:
|
||||||
|
tz = None
|
||||||
|
|
||||||
|
nw = datetime.now(tz)
|
||||||
|
|
||||||
|
try:
|
||||||
|
contents = nw.strftime(format)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
contents = datetime.now().strftime(format.encode('utf-8')).decode('utf-8')
|
contents = nw.strftime(format.encode('utf-8')).decode('utf-8')
|
||||||
|
|
||||||
return [{
|
return [{
|
||||||
'contents': contents,
|
'contents': contents,
|
||||||
@ -34,59 +45,77 @@ UNICODE_TEXT_TRANSLATION = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def fuzzy_time(pl, unicode_text=False):
|
def fuzzy_time(pl, format='{minute_str} {hour_str}', unicode_text=False, timezone=None, hour_str=['twelve', 'one', 'two', 'three', 'four',
|
||||||
|
'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'], minute_str = {
|
||||||
|
'0': 'o\'clock', '5': 'five past', '10': 'ten past','15': 'quarter past',
|
||||||
|
'20': 'twenty past', '25': 'twenty-five past', '30': 'half past', '35': 'twenty-five to',
|
||||||
|
'40': 'twenty to', '45': 'quarter to', '50': 'ten to', '55': 'five to'
|
||||||
|
}, special_case_str = {
|
||||||
|
'(23, 58)': 'round about midnight',
|
||||||
|
'(23, 59)': 'round about midnight',
|
||||||
|
'(0, 0)': 'midnight',
|
||||||
|
'(0, 1)': 'round about midnight',
|
||||||
|
'(0, 2)': 'round about midnight',
|
||||||
|
'(12, 0)': 'noon',
|
||||||
|
}):
|
||||||
|
|
||||||
'''Display the current time as fuzzy time, e.g. "quarter past six".
|
'''Display the current time as fuzzy time, e.g. "quarter past six".
|
||||||
|
|
||||||
|
:param string format:
|
||||||
|
Format used to display the fuzzy time. (Ignored when a special time
|
||||||
|
is displayed.)
|
||||||
:param bool unicode_text:
|
:param bool unicode_text:
|
||||||
If true then hyphenminuses (regular ASCII ``-``) and single quotes are
|
If true then hyphenminuses (regular ASCII ``-``) and single quotes are
|
||||||
replaced with unicode dashes and apostrophes.
|
replaced with unicode dashes and apostrophes.
|
||||||
'''
|
:param string timezone:
|
||||||
hour_str = ['twelve', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']
|
Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
|
||||||
minute_str = {
|
(Defaults to system defaults.)
|
||||||
5: 'five past',
|
:param string list hour_str:
|
||||||
10: 'ten past',
|
Strings to be used to display the hour, starting with midnight.
|
||||||
15: 'quarter past',
|
(This list may contain 12 or 24 entries.)
|
||||||
20: 'twenty past',
|
:param dict minute_str:
|
||||||
25: 'twenty-five past',
|
Dictionary mapping minutes to strings to be used to display them.
|
||||||
30: 'half past',
|
:param dict special_case_str:
|
||||||
35: 'twenty-five to',
|
Special strings for special times.
|
||||||
40: 'twenty to',
|
|
||||||
45: 'quarter to',
|
|
||||||
50: 'ten to',
|
|
||||||
55: 'five to',
|
|
||||||
}
|
|
||||||
special_case_str = {
|
|
||||||
(23, 58): 'round about midnight',
|
|
||||||
(23, 59): 'round about midnight',
|
|
||||||
(0, 0): 'midnight',
|
|
||||||
(0, 1): 'round about midnight',
|
|
||||||
(0, 2): 'round about midnight',
|
|
||||||
(12, 0): 'noon',
|
|
||||||
}
|
|
||||||
|
|
||||||
now = datetime.now()
|
Highlight groups used: ``fuzzy_time``.
|
||||||
|
'''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return special_case_str[(now.hour, now.minute)]
|
tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
|
||||||
|
except ValueError:
|
||||||
|
tz = None
|
||||||
|
|
||||||
|
now = datetime.now(tz)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# We don't want to enforce a special type of spaces/ alignment in the input
|
||||||
|
from ast import literal_eval
|
||||||
|
special_case_str = {literal_eval(x):special_case_str[x] for x in special_case_str}
|
||||||
|
result = special_case_str[(now.hour, now.minute)]
|
||||||
|
if unicode_text:
|
||||||
|
result = result.translate(UNICODE_TEXT_TRANSLATION)
|
||||||
|
return result
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
hour = now.hour
|
hour = now.hour
|
||||||
if now.minute > 32:
|
if now.minute >= 30:
|
||||||
if hour == 23:
|
hour = hour + 1
|
||||||
hour = 0
|
hour = hour % len(hour_str)
|
||||||
else:
|
|
||||||
hour += 1
|
|
||||||
if hour > 11:
|
|
||||||
hour = hour - 12
|
|
||||||
hour = hour_str[hour]
|
|
||||||
|
|
||||||
minute = int(round(now.minute / 5.0) * 5)
|
min_dis = 100
|
||||||
if minute == 60 or minute == 0:
|
min_pos = 0
|
||||||
result = ' '.join([hour, 'o\'clock'])
|
|
||||||
else:
|
for mn in minute_str:
|
||||||
minute = minute_str[minute]
|
mn = int(mn)
|
||||||
result = ' '.join([minute, hour])
|
if now.minute >= mn and now.minute - mn < min_dis:
|
||||||
|
min_dis = now.minute - mn
|
||||||
|
min_pos = mn
|
||||||
|
elif now.minute < mn and mn - now.minute < min_dis:
|
||||||
|
min_dis = mn - now.minute
|
||||||
|
min_pos = mn
|
||||||
|
result = format.format(minute_str=minute_str[str(min_pos)], hour_str=hour_str[hour])
|
||||||
|
|
||||||
if unicode_text:
|
if unicode_text:
|
||||||
result = result.translate(UNICODE_TEXT_TRANSLATION)
|
result = result.translate(UNICODE_TEXT_TRANSLATION)
|
||||||
|
@ -819,9 +819,11 @@ class TestTime(TestCommon):
|
|||||||
|
|
||||||
def test_date(self):
|
def test_date(self):
|
||||||
pl = Pl()
|
pl = Pl()
|
||||||
with replace_attr(self.module, 'datetime', Args(now=lambda: Args(strftime=lambda fmt: fmt))):
|
with replace_attr(self.module, 'datetime', Args(strptime=lambda timezone, fmt: Args(tzinfo=timezone), now=lambda tz:Args(strftime=lambda fmt: fmt + (tz if tz else '')))):
|
||||||
self.assertEqual(self.module.date(pl=pl), [{'contents': '%Y-%m-%d', 'highlight_groups': ['date'], 'divider_highlight_group': None}])
|
self.assertEqual(self.module.date(pl=pl), [{'contents': '%Y-%m-%d', 'highlight_groups': ['date'], 'divider_highlight_group': None}])
|
||||||
|
self.assertEqual(self.module.date(pl=pl, timezone='+0900'), [{'contents': '%Y-%m-%d+0900', 'highlight_groups': ['date'], 'divider_highlight_group': None}])
|
||||||
self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
|
self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
|
||||||
|
self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True, timezone='-0900'), [{'contents': '%H:%M-0900', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
|
||||||
unicode_date = self.module.date(pl=pl, format='\u231a', istime=True)
|
unicode_date = self.module.date(pl=pl, format='\u231a', istime=True)
|
||||||
expected_unicode_date = [{'contents': '\u231a', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}]
|
expected_unicode_date = [{'contents': '\u231a', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}]
|
||||||
if python_implementation() == 'PyPy' and sys.version_info >= (3,):
|
if python_implementation() == 'PyPy' and sys.version_info >= (3,):
|
||||||
@ -832,23 +834,49 @@ class TestTime(TestCommon):
|
|||||||
def test_fuzzy_time(self):
|
def test_fuzzy_time(self):
|
||||||
time = Args(hour=0, minute=45)
|
time = Args(hour=0, minute=45)
|
||||||
pl = Pl()
|
pl = Pl()
|
||||||
with replace_attr(self.module, 'datetime', Args(now=lambda: time)):
|
hour_str = ['12', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']
|
||||||
|
minute_str = {'0': 'o\'clock', '5': 'five past', '10': 'ten past','15':
|
||||||
|
'quarter past','20': 'twenty past', '25': 'twenty-five past',
|
||||||
|
'30': 'half past', '35': 'twenty-five to','40': 'twenty to', '45':
|
||||||
|
'quarter to', '50': 'ten to', '55': 'five to'}
|
||||||
|
special_case_str = {
|
||||||
|
'(23, 58)': '~ midnight',
|
||||||
|
'(23, 59)': '~ midnight',
|
||||||
|
'(0, 0)': 'midnight',
|
||||||
|
'(0, 1)': '~ midnight',
|
||||||
|
'(0, 2)': '~ midnight',
|
||||||
|
'(12, 0)': 'twelve o\'clock'}
|
||||||
|
with replace_attr(self.module, 'datetime', Args(strptime=lambda timezone, fmt: Args(tzinfo=timezone), now=lambda tz: time)):
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'quarter to one')
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'quarter to one')
|
self.assertEqual(self.module.fuzzy_time(pl=pl), 'quarter to one')
|
||||||
time.hour = 23
|
time.hour = 23
|
||||||
time.minute = 59
|
time.minute = 59
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), '~ midnight')
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'round about midnight')
|
self.assertEqual(self.module.fuzzy_time(pl=pl), 'round about midnight')
|
||||||
|
time.hour = 11
|
||||||
time.minute = 33
|
time.minute = 33
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str),'twenty-five to 12')
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'twenty-five to twelve')
|
self.assertEqual(self.module.fuzzy_time(pl=pl), 'twenty-five to twelve')
|
||||||
time.minute = 60
|
time.hour = 12
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'twelve o\'clock')
|
time.minute = 0
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o\'clock')
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl), 'noon')
|
||||||
|
time.hour = 11
|
||||||
time.minute = 33
|
time.minute = 33
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twenty-five to 12')
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve')
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve')
|
||||||
time.minute = 60
|
time.hour = 12
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twelve o\'clock')
|
time.minute = 0
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o\'clock')
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'noon')
|
||||||
|
time.hour = 11
|
||||||
time.minute = 33
|
time.minute = 33
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twenty‐five to 12')
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twenty‐five to twelve')
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twenty‐five to twelve')
|
||||||
time.minute = 60
|
time.hour = 12
|
||||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twelve o’clock')
|
time.minute = 0
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o’clock')
|
||||||
|
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True),'noon')
|
||||||
|
|
||||||
|
|
||||||
class TestSys(TestCommon):
|
class TestSys(TestCommon):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user