Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions stdnum/gs1_128.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,15 @@ def _encode_date(fmt: str, value: object) -> str:
# Format date in different formats
if fmt in ('N6', 'N6..12', 'N6[+N6]'):
return value.strftime('%y%m%d')
elif fmt == 'N8':
# Date with a four-digit year (YYYYMMDD), e.g. AI 7250 (DOB).
return value.strftime('%Y%m%d')
elif fmt == 'N10':
return value.strftime('%y%m%d%H%M')
elif fmt == 'N12':
# Date and time with a four-digit year (YYYYMMDDhhmm), e.g. AI 7251
# (DOB TIME).
return value.strftime('%Y%m%d%H%M')
elif fmt in ('N6+N..4', 'N6[+N..4]', 'N6[+N4]'):
value = value.strftime('%y%m%d%H%M')
if value.endswith('00'):
Expand Down Expand Up @@ -185,7 +192,14 @@ def _decode_decimal(ai: str, fmt: str, value: str) -> decimal.Decimal | tuple[st

def _decode_date(fmt: str, value: str) -> datetime.date | datetime.datetime | tuple[datetime.date, datetime.date]:
"""Decode the specified date value given the fmt."""
if len(value) == 6:
if fmt == 'N8':
# Date with a four-digit year (YYYYMMDD), e.g. AI 7250 (DOB).
return datetime.datetime.strptime(value, '%Y%m%d').date()
elif fmt == 'N12':
# Date and time with a four-digit year (YYYYMMDDhhmm), e.g. AI 7251
# (DOB TIME). This is a single datetime, not two YYMMDD dates.
return datetime.datetime.strptime(value, '%Y%m%d%H%M')
elif len(value) == 6:
if value[4:] == '00':
# When day == '00', it must be interpreted as last day of month
date = datetime.datetime.strptime(value[:4], '%y%m')
Expand All @@ -196,7 +210,7 @@ def _decode_date(fmt: str, value: str) -> datetime.date | datetime.datetime | tu
return date.date()
else:
return datetime.datetime.strptime(value, '%y%m%d').date()
elif len(value) == 12 and fmt in ('N12', 'N6..12', 'N6[+N6]'):
elif len(value) == 12 and fmt in ('N6..12', 'N6[+N6]'):
return (_decode_date('N6', value[:6]), _decode_date('N6', value[6:])) # type: ignore[return-value]
else:
# Other lengths are interpreted as variable-length datetime values
Expand Down
8 changes: 8 additions & 0 deletions tests/test_gs1_128.doctest
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ We generate dates in various formats, depending on the AI.
'(7011)181119'
>>> gs1_128.encode({'7011': datetime.datetime(2018, 11, 19, 12, 45)}, parentheses=True)
'(7011)1811191245'
>>> gs1_128.encode({'7250': datetime.date(1980, 7, 15)}, parentheses=True) # four-digit year
'(7250)19800715'
>>> gs1_128.encode({'7251': datetime.datetime(1980, 7, 15, 14, 30)}, parentheses=True)
'(7251)198007151430'

If we try to encode an invalid EAN we will get an error.

Expand Down Expand Up @@ -154,6 +158,10 @@ We an decode date files from various formats.
{'7011': datetime.date(2018, 11, 19)}
>>> pprint.pprint(gs1_128.info('(7011)1811191245'))
{'7011': datetime.datetime(2018, 11, 19, 12, 45)}
>>> pprint.pprint(gs1_128.info('(7250)19800715'))
{'7250': datetime.date(1980, 7, 15)}
>>> pprint.pprint(gs1_128.info('(7251)198007151430'))
{'7251': datetime.datetime(1980, 7, 15, 14, 30)}


While the compact() function can clean up the number somewhat the validate()
Expand Down
Loading