1# vim:fileencoding=utf-8:noet
2from __future__ import (unicode_literals, division, absolute_import, print_function)
3
4from datetime import datetime
5
6
7def date(pl, format='%Y-%m-%d', istime=False, timezone=None):
8	'''Return the current date.
9
10	:param str format:
11		strftime-style date format string
12	:param bool istime:
13		If true then segment uses ``time`` highlight group.
14	:param string timezone:
15		Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
16		(Defaults to system defaults.)
17
18	Divider highlight group used: ``time:divider``.
19
20	Highlight groups used: ``time`` or ``date``.
21	'''
22
23	try:
24		tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
25	except ValueError:
26		tz = None
27
28	nw = datetime.now(tz)
29
30	try:
31		contents = nw.strftime(format)
32	except UnicodeEncodeError:
33		contents = nw.strftime(format.encode('utf-8')).decode('utf-8')
34
35	return [{
36		'contents': contents,
37		'highlight_groups': (['time'] if istime else []) + ['date'],
38		'divider_highlight_group': 'time:divider' if istime else None,
39	}]
40
41
42UNICODE_TEXT_TRANSLATION = {
43	ord('\''): '’',
44	ord('-'): '‐',
45}
46
47
48def fuzzy_time(pl, format='{minute_str} {hour_str}', unicode_text=False, timezone=None, hour_str=['twelve', 'one', 'two', 'three', 'four',
49    'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'], minute_str = {
50	'0':  'o\'clock', '5':  'five past', '10': 'ten past','15': 'quarter past',
51	'20': 'twenty past', '25': 'twenty-five past', '30': 'half past', '35': 'twenty-five to',
52	'40': 'twenty to', '45': 'quarter to', '50': 'ten to', '55': 'five to'
53	}, special_case_str = {
54	    '(23, 58)': 'round about midnight',
55	    '(23, 59)': 'round about midnight',
56	    '(0, 0)': 'midnight',
57	    '(0, 1)': 'round about midnight',
58	    '(0, 2)': 'round about midnight',
59	    '(12, 0)': 'noon',
60	}):
61
62	'''Display the current time as fuzzy time, e.g. "quarter past six".
63
64	:param string format:
65		Format used to display the fuzzy time. (Ignored when a special time
66		is displayed.)
67	:param bool unicode_text:
68		If true then hyphenminuses (regular ASCII ``-``) and single quotes are
69		replaced with unicode dashes and apostrophes.
70	:param string timezone:
71		Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
72		(Defaults to system defaults.)
73	:param string list hour_str:
74		Strings to be used to display the hour, starting with midnight.
75		(This list may contain 12 or 24 entries.)
76	:param dict minute_str:
77		Dictionary mapping minutes to strings to be used to display them.
78	:param dict special_case_str:
79		Special strings for special times.
80
81	Highlight groups used: ``fuzzy_time``.
82	'''
83
84	try:
85		tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
86	except ValueError:
87		tz = None
88
89	now = datetime.now(tz)
90
91	try:
92		# We don't want to enforce a special type of spaces/ alignment in the input
93		from ast import literal_eval
94		special_case_str = {literal_eval(x):special_case_str[x] for x in special_case_str}
95		result = special_case_str[(now.hour, now.minute)]
96		if unicode_text:
97			result = result.translate(UNICODE_TEXT_TRANSLATION)
98		return result
99	except KeyError:
100		pass
101
102	hour = now.hour
103	if now.minute >= 30:
104		hour = hour + 1
105	hour = hour % len(hour_str)
106
107	min_dis = 100
108	min_pos = 0
109
110	for mn in minute_str:
111		mn = int(mn)
112		if now.minute >= mn and now.minute - mn < min_dis:
113			min_dis = now.minute - mn
114			min_pos = mn
115		elif now.minute < mn and mn - now.minute < min_dis:
116			min_dis = mn - now.minute
117			min_pos = mn
118	result = format.format(minute_str=minute_str[str(min_pos)], hour_str=hour_str[hour])
119
120	if unicode_text:
121		result = result.translate(UNICODE_TEXT_TRANSLATION)
122
123	return result
124