Skip to content

Commit

Permalink
Simplifies text writing of timestamps with Decimal fractional seconds.
Browse files Browse the repository at this point in the history
  • Loading branch information
tgregg committed Oct 11, 2019
1 parent 57c864c commit aab21c0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 29 deletions.
37 changes: 8 additions & 29 deletions amazon/ion/writer_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,6 @@
]


def _scientific_notation_to_decimal_string(value):
"""Converts the Decimal ```value```, which must be expressed in scientific notation, to a string version of the full
precision decimal with the zero that precedes the decimal point omitted.
Input example: Decimal('1.2E-14')
Output example: '.000000000000012'
Args:
value (Decimal): The numerical value, which must be expressed in scientific notation
Returns:
string: A string version of the full precision decimal with the zero that precedes the decimal point omitted.
"""
value_string = str(value).replace('.', '').lower()
pos = value_string.find('e')
number_value = value_string[:pos]
exponent_value = value_string[pos + 1:]
total_num_of_zeroes = (int(exponent_value) * -1) - 1
decimal_string = '.' + ('0' * total_num_of_zeroes) + number_value
return decimal_string


def _serialize_bool(ion_event):
if ion_event.value:
return b'true'
Expand Down Expand Up @@ -193,9 +172,9 @@ def _bytes_datetime(dt):
else:
return tz_string + _bytes_utc_offset(dt)

fractional_precision = getattr(original_dt, TIMESTAMP_FRACTION_PRECISION_FIELD, MICROSECOND_PRECISION)
fractional_seconds = getattr(original_dt, TIMESTAMP_FRACTIONAL_SECONDS_FIELD, None)
if fractional_seconds is None:
fractional_precision = getattr(original_dt, TIMESTAMP_FRACTION_PRECISION_FIELD, MICROSECOND_PRECISION)
fractional = dt.strftime('%f')
assert len(fractional) == MICROSECOND_PRECISION

Expand All @@ -206,13 +185,13 @@ def _bytes_datetime(dt):
fractional = fractional[:fractional_precision]
tz_string += '.' + fractional

if fractional_seconds == 0:
tz_string += '.' + ('0' * fractional_precision)
elif fractional_seconds is not None:
if 'e' in str(fractional_seconds).lower():
tz_string += _scientific_notation_to_decimal_string(fractional_seconds)
else:
tz_string += str(fractional_seconds)[1:]
else:
_, digits, exponent = fractional_seconds.as_tuple()
leading_zeroes = -exponent - len(digits)
tz_string += '.'
if leading_zeroes > 0:
tz_string += '0' * leading_zeroes
tz_string += ''.join(str(x) for x in digits)
return tz_string + _bytes_utc_offset(dt)


Expand Down
20 changes: 20 additions & 0 deletions tests/writer_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ def _convert_clob_pairs(clob_pairs):
(_DT(2016, 1, 1, 12, 34, 12, tzinfo=OffsetTZInfo()), b'2016-01-01T12:34:12.000000Z'),
(_DT(2016, 1, 1, 12, 34, 12, tzinfo=OffsetTZInfo(timedelta(hours=-7))),
b'2016-01-01T12:34:12.000000-07:00'),
(
timestamp(2016, 2, 2, 0, 0, 30, precision=TimestampPrecision.SECOND,
fractional_seconds=Decimal('0.000010000')),
b'2016-02-02T00:00:30.000010000-00:00'
),
(
timestamp(2016, 2, 2, 0, 0, 30, precision=TimestampPrecision.SECOND,
fractional_seconds=Decimal('0.7e-500')),
b'2016-02-02T00:00:30.' + b'0' * 500 + b'7-00:00'
)
),
_IT.SYMBOL: (
(None, b'null.symbol'),
Expand Down Expand Up @@ -288,6 +298,16 @@ def _convert_clob_pairs(clob_pairs):
precision=TimestampPrecision.SECOND, fractional_precision=1),
b'\x6B\x43\xA4\x0F\xE0\x82\x82\x87\x80\x9E\xC1\x01'
),
(
timestamp(2016, 2, 2, 0, 0, 30, precision=TimestampPrecision.SECOND,
fractional_seconds=Decimal('0.000010000')),
b'\x6B\xC0\x0F\xE0\x82\x82\x80\x80\x9E\xC9\x27\x10'
),
(
timestamp(2016, 2, 2, 0, 0, 30, precision=TimestampPrecision.SECOND,
fractional_seconds=Decimal('0.7e-500')),
b'\x6B\xC0\x0F\xE0\x82\x82\x80\x80\x9E\x43\xF5\x07'
)
),
_IT.SYMBOL: (
(None, b'\x7F'),
Expand Down

0 comments on commit aab21c0

Please sign in to comment.