Skip to content

Commit 1a4329c

Browse files
Merge pull request #307 from brondsem/fix_date_order_preference
Fix date parsing for .rs .kz .kg
2 parents f089435 + 403e726 commit 1a4329c

8 files changed

Lines changed: 134 additions & 6 deletions

File tree

test/samples/expected/abc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"domain_name": "abc.rs", "expiration_date": "2026-03-26 16:18:03+00:00", "updated_date": "2025-02-11 08:24:15+00:00", "registrar": "Mainstream Public Cloud Services d.o.o.", "registrar_url": null, "creation_date": "2008-03-26 16:18:03+00:00", "status": "Active https://www.rnids.rs/en/domain-name-status-codes#Active"}

test/samples/expected/google.kg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"domain_name": "GOOGLE.KG", "expiration_date": "2026-03-28 23:59:00+00:00", "updated_date": "2025-03-05 00:13:49+00:00", "registrar": null, "registrar_url": null, "creation_date": "2004-02-10 09:42:42+00:00", "status": null}

test/samples/expected/yandex.kz

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"domain_name": "yandex.kz", "expiration_date": null, "updated_date": "2022-08-04 10:20:10+00:00", "registrar": "HOSTER.KZ", "registrar_url": null, "creation_date": "2009-07-01 12:44:02+00:00", "status": ["status : clientTransferProhibited", "clientDeleteProhibited", "clientRenewProhibited"]}

test/samples/whois/abc.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
% The data in the Whois database are provided by RNIDS
2+
% for information purposes only and to assist persons in obtaining
3+
% information about or related to a domain name registration record.
4+
% Data in the database are created by registrants and we do not guarantee
5+
% their accuracy. We reserve the right to remove access
6+
% for entities abusing the data, without notice.
7+
% All timestamps are given in Serbian local time.
8+
%
9+
Domain name: abc.rs
10+
Domain status: Active https://www.rnids.rs/en/domain-name-status-codes#Active
11+
Registration date: 26.03.2008 16:18:03
12+
Modification date: 11.02.2025 08:24:15
13+
Expiration date: 26.03.2026 16:18:03
14+
Confirmed: 26.03.2008 16:18:03
15+
Registrar: Mainstream Public Cloud Services d.o.o.
16+
17+
18+
Registrant: Roda grupa doo
19+
Address: Bulevar Oslobodjenja 129, Beograd, Serbia
20+
Postal Code: 11000
21+
ID Number: 20886374
22+
Tax ID: 107867472
23+
24+
Administrative contact: Individual
25+
26+
Technical contact: SERBIA BROADBAND - SRPSKE KABLOVSKE MREZE D.O.O.
27+
Address: Bulevar Peka Dapcevica 19, Beograd, Serbia
28+
Postal Code: 11000
29+
ID Number: 17280554
30+
Tax ID: 101038731
31+
32+
33+
DNS: ns1.providus.rs - 164.132.48.70
34+
DNS: ns2.providus.rs - 104.199.179.254
35+
DNS: ns3.providus.rs - 52.5.196.189
36+
37+
38+
DNSSEC signed: no
39+
40+
Whois Timestamp: 07.11.2025 20:57:08

test/samples/whois/google.kg

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
% This is the .kg ccTLD Whois server
2+
% Register your own domain at https://www.cctld.kg
3+
% Whois web service - https://www.cctld.kg/whois
4+
5+
Domain GOOGLE.KG (ACTIVE)
6+
7+
Administrative Contact:
8+
PID: AI-44973-KG
9+
Name:
10+
Address: United States Mountain View 1600 Amphitheatre Parkway N/A
11+
Email: dns-admin@google.com
12+
phone: 16502530000
13+
fax: +1.6502530001
14+
15+
Technical Contact:
16+
PID: AI-44973-KG
17+
Name:
18+
Address: United States Mountain View 1600 Amphitheatre Parkway N/A
19+
Email: dns-admin@google.com
20+
phone: 16502530000
21+
fax: +1.6502530001
22+
23+
Billing Contact:
24+
PID: 5935-KG
25+
Name:
26+
Address: United States Meridian 1120 S. Rackham Way Suite 300
27+
Email: ccops@markmonitor.com
28+
phone: +12083895740
29+
fax: +12083895771
30+
31+
32+
Record created: Tue Feb 10 09:42:42 2004
33+
Record last updated on: Wed Mar 5 00:13:49 2025
34+
Record expires on: Sat Mar 28 23:59:00 2026
35+
36+
Name servers in the listed order:
37+
38+
NS1.GOOGLE.COM
39+
NS2.GOOGLE.COM
40+
NS4.GOOGLE.COM

test/samples/whois/yandex.kz

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Whois Server for the KZ top level domain name.
2+
This server is maintained by KazNIC Organization, a ccTLD manager for Kazakhstan Republic.
3+
4+
Domain Name............: yandex.kz
5+
6+
Organization Using Domain Name
7+
Name...................: Yandex.Kazakhstan LLP
8+
Organization Name......: Yandex.Kazakhstan LLP
9+
Street Address.........: Dostyk street 43
10+
City...................: Almaty
11+
State..................: -
12+
Postal Code............: 050051
13+
Country................: KZ
14+
15+
Administrative Contact/Agent
16+
NIC Handle.............: HOSTERKZ-280570
17+
Name...................: Domain manager
18+
Phone Number...........: +7.4957397000
19+
Fax Number.............: +7.4957397000
20+
Email Address..........: hostmaster@yandex.net
21+
22+
Nameserver in listed order
23+
24+
Primary server.........: ns1.yandex.net
25+
Primary ip address.....: 213.180.193.1
26+
27+
Secondary server.......: ns2.yandex.net
28+
Secondary ip address...: 213.180.199.34
29+
30+
31+
Domain created: 2009-07-01 12:44:02 (GMT+0:00)
32+
Last modified : 2022-08-04 10:20:10 (GMT+0:00)
33+
Domain status : clientTransferProhibited - status prohibits domain transfer without documents (статус запрещает трансфер домена без предоставления документов)
34+
clientDeleteProhibited - status prevent domain deletion from the Register (статус предотвращает удаление домена из реестра)
35+
clientRenewProhibited - status prevent domain auto renewal without payment (статус предотвращает авто продление без оплаты)
36+
37+
Registar created: KAZNIC
38+
Current Registar: HOSTER.KZ

test/test_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def test_cast_date(self):
4545

4646
def test_unknown_date_format(self):
4747
with self.assertRaises(WhoisUnknownDateFormatError):
48-
datetime_parse("UNKNOWN")
48+
cast_date("UNKNOWN")
4949

5050
def test_com_allsamples(self):
5151
"""

whois/parser.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,12 @@
6969
"before %Y-%m-%d", # before 1996-01-01
7070
"before %Y%m%d", # before 19960821
7171
"%Y-%m-%d %H:%M:%S (%Z%z)", # 2017-09-26 11:38:29 (GMT+00:00)
72+
"%Y-%m-%d %H:%M:%S (%Z+0:00)", # 2009-07-01 12:44:02 (GMT+0:00)
7273
"%Y-%b-%d.", # 2024-Apr-02.
7374
]
7475

7576

76-
def datetime_parse(s: str) -> Union[str, datetime]:
77+
def datetime_parse(s: str) -> Union[datetime, None]:
7778
for known_format in KNOWN_FORMATS:
7879
try:
7980
parsed = datetime.strptime(s, known_format)
@@ -83,21 +84,27 @@ def datetime_parse(s: str) -> Union[str, datetime]:
8384
if parsed.tzinfo is None:
8485
parsed = parsed.replace(tzinfo=timezone.utc)
8586
return parsed
86-
raise WhoisUnknownDateFormatError(f"Unknown date format: {s}")
8787

8888

8989
def cast_date(
9090
s: str, dayfirst: bool = False, yearfirst: bool = False
9191
) -> Union[str, datetime]:
9292
"""Convert any date string found in WHOIS to a datetime object."""
93+
94+
# prefer our conversion before dateutil.parser
95+
# because dateutil.parser does %m.%d.%Y and ours has %d.%m.%Y which is more logical
96+
parsed = datetime_parse(s)
97+
if parsed:
98+
return parsed
99+
93100
try:
94101
# Use datetime.timezone.utc to support < Python3.9
95102
return default_tzinfo(
96103
dp.parse(s, tzinfos=tz_data, dayfirst=dayfirst, yearfirst=yearfirst),
97104
timezone.utc,
98105
)
99106
except dp.ParserError:
100-
return datetime_parse(s)
107+
raise WhoisUnknownDateFormatError(f"Unknown date format: {s}") from None
101108

102109

103110
class WhoisEntry(dict):
@@ -1723,8 +1730,8 @@ class WhoisKg(WhoisEntry):
17231730
"name_servers": r"Name servers in the listed order: *([\d\w\.\s]+)",
17241731
# 'name_servers': r'([\w]+\.[\w]+\.[\w]{2,5}\s*\d{1,3}\.\d]{1,3}\.[\d]{1-3}\.[\d]{1-3})',
17251732
"creation_date": r"Record created: *(.+)",
1726-
"expiration_date": r"Record expires on \s*(.+)",
1727-
"updated_date": r"Record last updated on\s*(.+)",
1733+
"expiration_date": r"Record expires on:\s*(.+)",
1734+
"updated_date": r"Record last updated on:\s*(.+)",
17281735
}
17291736

17301737
def __init__(self, domain: str, text: str):

0 commit comments

Comments
 (0)