Skip to content

Commit

Permalink
fix: add support for negative timestamps (close #38) (#48)
Browse files Browse the repository at this point in the history
* fix: negative timestamp in note_formatter_util (close #38)

* fix: convert negative timestamp

* fix: zeropad year for linux strftime

---------

Co-authored-by: vzhd1701 <vzhd1701@gmail.com>
  • Loading branch information
favoyang and vzhd1701 committed Oct 18, 2023
1 parent c2bd9b9 commit 244440d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 17 deletions.
41 changes: 27 additions & 14 deletions evernote_backup/note_formatter_util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import base64
import sys
from datetime import datetime
from datetime import datetime, timedelta
from typing import Optional


Expand All @@ -10,12 +10,15 @@ def fmt_time(timestamp: Optional[int]) -> Optional[str]:

timestamp //= 1000

if timestamp < _get_max_timestamp():
date = datetime.utcfromtimestamp(timestamp)
else:
# https://dev.evernote.com/doc/reference/Types.html#Typedef_Timestamp
if timestamp < 0:
date = _date_from_past(timestamp)
elif timestamp >= _get_max_timestamp():
date = _date_from_future(timestamp)
else:
date = datetime.utcfromtimestamp(timestamp)

return date.strftime("%Y%m%dT%H%M%SZ")
return date.strftime(f"{date.year:04}%m%dT%H%M%SZ")


def fmt_binary(binary_data: bytes) -> str:
Expand Down Expand Up @@ -80,13 +83,23 @@ def _date_from_future(timestamp: int) -> datetime: # noqa: WPS210
m = mp + (3 if mp < 10 else -9)
y += m <= 2

day_time = datetime.utcfromtimestamp(timestamp % 86400)
try:
day_time = datetime.utcfromtimestamp(timestamp % 86400)

return datetime(
year=y,
month=m,
day=d,
hour=day_time.hour,
minute=day_time.minute,
second=day_time.second,
)
except (OverflowError, ValueError, OSError):
return datetime.max

return datetime(
year=y,
month=m,
day=d,
hour=day_time.hour,
minute=day_time.minute,
second=day_time.second,
)

def _date_from_past(timestamp: int) -> datetime:
try:
return datetime.utcfromtimestamp(0) - timedelta(seconds=abs(timestamp))
except (OverflowError, ValueError, OSError):
return datetime.min
25 changes: 22 additions & 3 deletions tests/test_note_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ def test_note_from_future(mocker):
formatter = NoteFormatter()

# 9999-12-31 23:59:59
end_of_times = 253402300799999
end_of_times_bad = 999999999999999
end_of_times = 243402300799999

# Emulate windows limit
mock_timestamp = mocker.patch(
Expand All @@ -178,11 +179,29 @@ def test_note_from_future(mocker):

note_from_future = Note(
title="test",
created=end_of_times,
created=end_of_times_bad,
updated=end_of_times,
)

formatted_note = formatter.format_note(note_from_future)

assert "<created>99991231T235959Z</created>" in formatted_note
assert "<updated>99991231T235959Z</updated>" in formatted_note
assert "<updated>96830210T061319Z</updated>" in formatted_note


def test_note_from_past(mocker):
formatter = NoteFormatter()

before_times_bad = -999999999999999
before_times = -50000000000000

note_from_future = Note(
title="test",
created=before_times_bad,
updated=before_times,
)

formatted_note = formatter.format_note(note_from_future)

assert "<created>00010101T000000Z</created>" in formatted_note
assert "<updated>03850725T070640Z</updated>" in formatted_note

0 comments on commit 244440d

Please sign in to comment.