Skip to content

Commit 3e3745a

Browse files
JTrembdluc
authored andcommitted
python: Porting TimeSkill (microsoft#209)
### Motivation and Context Port of the core TimeSkill ### Description This PR adds the core TimeSkill with unit tests. ``` kernel = sk.create_kernel() kernel.import_skill(TimeSkill(), "time") ``` ``` sk_prompt = """ {{time.now}} """ ```
1 parent 0ce2acb commit 3e3745a

3 files changed

Lines changed: 332 additions & 1 deletion

File tree

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Copyright (c) Microsoft. All rights reserved.
22

33
from semantic_kernel.core_skills.text_memory_skill import TextMemorySkill
4+
from semantic_kernel.core_skills.file_io_skill import FileIOSkill
5+
from semantic_kernel.core_skills.time_skill import TimeSkill
6+
from semantic_kernel.core_skills.text_skill import TextSkill
47

5-
__all__ = ["TextMemorySkill"]
8+
__all__ = ["TextMemorySkill", "TextSkill", "FileIOSkill", "TimeSkill"]
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import datetime
2+
3+
from semantic_kernel.skill_definition import sk_function
4+
5+
6+
class TimeSkill:
7+
"""
8+
Description: TimeSkill provides a set of functions
9+
to get the current time and date.
10+
11+
Usage:
12+
kernel.import_skill("time", TimeSkill())
13+
14+
Examples:
15+
{{time.date}} => Sunday, 12 January, 2031
16+
{{time.today}} => Sunday, 12 January, 2031
17+
{{time.now}} => Sunday, January 12, 2031 9:15 PM
18+
{{time.utcNow}} => Sunday, January 13, 2031 5:15 AM
19+
{{time.time}} => 09:15:07 PM
20+
{{time.year}} => 2031
21+
{{time.month}} => January
22+
{{time.monthNumber}} => 01
23+
{{time.day}} => 12
24+
{{time.dayOfWeek}} => Sunday
25+
{{time.hour}} => 9 PM
26+
{{time.hourNumber}} => 21
27+
{{time.minute}} => 15
28+
{{time.minutes}} => 15
29+
{{time.second}} => 7
30+
{{time.seconds}} => 7
31+
{{time.timeZoneOffset}} => -0800
32+
{{time.timeZoneName}} => PST
33+
"""
34+
35+
@sk_function(description="Get the current time.")
36+
def date(self) -> str:
37+
"""
38+
Get the current date
39+
40+
Example:
41+
{{time.date}} => Sunday, 12 January, 2031
42+
"""
43+
now = datetime.datetime.now()
44+
return now.strftime("%A, %d %B, %Y")
45+
46+
@sk_function(description="Get the current date and time in the local time zone")
47+
def now(self) -> str:
48+
"""
49+
Get the current date and time in the local time zone"
50+
51+
Example:
52+
{{time.now}} => Sunday, January 12, 2031 9:15 PM
53+
"""
54+
now = datetime.datetime.now()
55+
return now.strftime("%A, %B %d, %Y %I:%M %p")
56+
57+
@sk_function(description="Get the current date and time in UTC", name="utcNow")
58+
def utc_now(self) -> str:
59+
"""
60+
Get the current date and time in UTC
61+
62+
Example:
63+
{{time.utcNow}} => Sunday, January 13, 2031 5:15 AM
64+
"""
65+
now = datetime.datetime.utcnow()
66+
return now.strftime("%A, %B %d, %Y %I:%M %p")
67+
68+
@sk_function(description="Get the current time in the local time zone")
69+
def time(self) -> str:
70+
"""
71+
Get the current time in the local time zone
72+
73+
Example:
74+
{{time.time}} => 09:15:07 PM
75+
"""
76+
now = datetime.datetime.now()
77+
return now.strftime("%I:%M:%S %p")
78+
79+
@sk_function(description="Get the current year")
80+
def year(self) -> str:
81+
"""
82+
Get the current year
83+
84+
Example:
85+
{{time.year}} => 2031
86+
"""
87+
now = datetime.datetime.now()
88+
return now.strftime("%Y")
89+
90+
@sk_function(description="Get the current month")
91+
def month(self) -> str:
92+
"""
93+
Get the current month
94+
95+
Example:
96+
{{time.month}} => January
97+
"""
98+
now = datetime.datetime.now()
99+
return now.strftime("%B")
100+
101+
@sk_function(description="Get the current month number")
102+
def month_number(self) -> str:
103+
"""
104+
Get the current month number
105+
106+
Example:
107+
{{time.monthNumber}} => 01
108+
"""
109+
now = datetime.datetime.now()
110+
return now.strftime("%m")
111+
112+
@sk_function(description="Get the current day")
113+
def day(self) -> str:
114+
"""
115+
Get the current day of the month
116+
117+
Example:
118+
{{time.day}} => 12
119+
"""
120+
now = datetime.datetime.now()
121+
return now.strftime("%d")
122+
123+
@sk_function(description="Get the current day of the week", name="dayOfWeek")
124+
def day_of_week(self) -> str:
125+
"""
126+
Get the current day of the week
127+
128+
Example:
129+
{{time.dayOfWeek}} => Sunday
130+
"""
131+
now = datetime.datetime.now()
132+
return now.strftime("%A")
133+
134+
@sk_function(description="Get the current hour")
135+
def hour(self) -> str:
136+
"""
137+
Get the current hour
138+
139+
Example:
140+
{{time.hour}} => 9 PM
141+
"""
142+
now = datetime.datetime.now()
143+
return now.strftime("%I %p")
144+
145+
@sk_function(description="Get the current hour number", name="hourNumber")
146+
def hour_number(self) -> str:
147+
"""
148+
Get the current hour number
149+
150+
Example:
151+
{{time.hourNumber}} => 21
152+
"""
153+
now = datetime.datetime.now()
154+
return now.strftime("%H")
155+
156+
@sk_function(description="Get the current minute")
157+
def minute(self) -> str:
158+
"""
159+
Get the current minute
160+
161+
Example:
162+
{{time.minute}} => 15
163+
"""
164+
now = datetime.datetime.now()
165+
return now.strftime("%M")
166+
167+
@sk_function(description="Get the seconds on the current minute")
168+
def second(self) -> str:
169+
"""
170+
Get the seconds on the current minute
171+
172+
Example:
173+
{{time.second}} => 7
174+
"""
175+
now = datetime.datetime.now()
176+
return now.strftime("%S")
177+
178+
@sk_function(description="Get the current time zone offset", name="timeZoneOffset")
179+
def time_zone_offset(self) -> str:
180+
"""
181+
Get the current time zone offset
182+
183+
Example:
184+
{{time.timeZoneOffset}} => -08:00
185+
"""
186+
now = datetime.datetime.now()
187+
return now.strftime("%z")
188+
189+
@sk_function(description="Get the current time zone name", name="timeZoneName")
190+
def time_zone_name(self) -> str:
191+
"""
192+
Get the current time zone name
193+
194+
Example:
195+
{{time.timeZoneName}} => PST
196+
"""
197+
now = datetime.datetime.now()
198+
return now.strftime("%Z")

python/tests/test_time_skill.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import datetime
2+
import semantic_kernel as sk
3+
4+
from unittest import mock
5+
6+
from semantic_kernel.core_skills.time_skill import TimeSkill
7+
8+
test_mock_now = datetime.datetime(2031, 1, 12, 12, 24, 56, tzinfo=datetime.timezone.utc)
9+
10+
11+
def test_can_be_instantiated():
12+
assert TimeSkill()
13+
14+
15+
def test_can_be_imported():
16+
kernel = sk.create_kernel()
17+
assert kernel.import_skill(TimeSkill(), "time")
18+
assert kernel.skills.has_native_function("time", "now")
19+
20+
21+
def test_date():
22+
skill = TimeSkill()
23+
24+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
25+
dt.now.return_value = test_mock_now
26+
assert skill.date() == "Sunday, 12 January, 2031"
27+
28+
29+
def test_now():
30+
skill = TimeSkill()
31+
32+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
33+
dt.now.return_value = test_mock_now
34+
assert skill.now() == "Sunday, January 12, 2031 12:24 PM"
35+
36+
37+
def test_utc_now():
38+
skill = TimeSkill()
39+
40+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
41+
dt.utcnow.return_value = test_mock_now
42+
assert skill.utc_now() == "Sunday, January 12, 2031 12:24 PM"
43+
44+
45+
def test_time():
46+
skill = TimeSkill()
47+
48+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
49+
dt.now.return_value = test_mock_now
50+
assert skill.time() == "12:24:56 PM"
51+
52+
53+
def test_year():
54+
skill = TimeSkill()
55+
56+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
57+
dt.now.return_value = test_mock_now
58+
assert skill.year() == "2031"
59+
60+
61+
def test_month():
62+
skill = TimeSkill()
63+
64+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
65+
dt.now.return_value = test_mock_now
66+
assert skill.month() == "January"
67+
68+
69+
def test_month_number():
70+
skill = TimeSkill()
71+
72+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
73+
dt.now.return_value = test_mock_now
74+
assert skill.month_number() == "01"
75+
76+
77+
def test_day():
78+
skill = TimeSkill()
79+
80+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
81+
dt.now.return_value = test_mock_now
82+
assert skill.day() == "12"
83+
84+
85+
def test_day_of_week():
86+
skill = TimeSkill()
87+
88+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
89+
dt.now.return_value = test_mock_now
90+
assert skill.day_of_week() == "Sunday"
91+
92+
93+
def test_hour():
94+
skill = TimeSkill()
95+
96+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
97+
dt.now.return_value = test_mock_now
98+
assert skill.hour() == "12 PM"
99+
100+
101+
def test_minute():
102+
skill = TimeSkill()
103+
104+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
105+
dt.now.return_value = test_mock_now
106+
assert skill.minute() == "24"
107+
108+
109+
def test_second():
110+
skill = TimeSkill()
111+
112+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
113+
dt.now.return_value = test_mock_now
114+
assert skill.second() == "56"
115+
116+
117+
def test_time_zone_offset():
118+
skill = TimeSkill()
119+
120+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
121+
dt.now.return_value = test_mock_now
122+
assert skill.time_zone_offset() == "+0000"
123+
124+
125+
def test_time_zone_name():
126+
skill = TimeSkill()
127+
128+
with mock.patch("datetime.datetime", wraps=datetime.datetime) as dt:
129+
dt.now.return_value = test_mock_now
130+
assert skill.time_zone_name() == "UTC"

0 commit comments

Comments
 (0)