Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local time and offsets the wrong way round when parsing/construction from string #54

Open
anowacki opened this issue Aug 16, 2024 · 2 comments

Comments

@anowacki
Copy link
Collaborator

anowacki commented Aug 16, 2024

As far as I understand from Wikipedia, offsets in ISO timestamps represent the offset from UTC of a ISO 8601 string in the local (offset) time zone. That is, the time given before the Z or ±hh:mm is the local time, and the offset gives the difference between the local time and UTC.

Assuming this is correct, then this means that the following should all be equivalent:

2000-01-01T06:00:00Z
2000-01-01T06:00:00+00:00
2000-01-01T00:00:00-06:00
2000-01-01T12:00:00+06:00

All this given, I understand that the relationship between the local time local_time, UTC time utc_time and local time zone offset offset should be utc_time = local_time - offset. (Note the subtraction of the offset, not addition!)

Perhaps you might be able to explain whether this is correct? Some other people agree. Likewise the datetime standard library in Python agrees (note tm_hour=1 on the last line):

# datetime at 2000-01-01T00:00:00-01:00
dt = datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone(datetime.timedelta(hours=-1)))

print(dt)
2000-01-01 00:00:00-01:00

# UTC date: 2000-01-01T01:00:00:00
print(dt.utctimetuple())
time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

If the above is all correct, then I think that NanoDates has offsets implemented the wrong way round. One of the tests:

@test NanoDate(
    "2022-06-18T12:15:30.123456789-04:00",
    dateformat"yyyy-mm-ddTHH:MM:SS.sssssssss+hh:mm";
    localtime=true
) == NanoDate(2022, 06, 18, 8, 15, 30, 123, 456, 789)

As far as I can see, when localtime is true, then the offset should be ignored entirely, and this should give back NanoDate(2022, 06, 18, 12, 15, 30, 123, 456, 789) (hour is 12).

When localtime is false, on the other hand, it should give NanoDate(2022, 06, 18, 16, 15, 30, 123, 456, 789) (hour is 12 – (–4) = 16).

As far as I can see, to fix this, the behaviour of localtime in the NanoDate constructor should be switched, and the offset should be subtracted, not added, in getting the UTC time.

Am I right, or have I got horribly confused?

@anowacki
Copy link
Collaborator Author

I should add that when asking for a time with ndnow, the behaviour appears the right way round (given I am in British Summer Time, UTC+01:00):

julia> ndnow(LOCAL)
2024-08-20T20:57:25.694112083

julia> ndnow(UTC)
2024-08-20T19:57:25.695622333

and likewise timestamp looks to also agree:

julia> timestamp(ndnow(LOCAL), localtime=true)
"2024-08-20T20:58:00.141808500+01:00"

So I think the issue is just with parsing dates with offsets.

(Just to note my preference—I think that parsing dates with offsets should give you back UTC by default, with the option to ignore the offset and return the local time. At present, it's the other way round (even if it appears to have a bug!), so it would be a breaking change.)

@anowacki anowacki changed the title Local time and offsets the wrong way round? Local time and offsets the wrong way round when parsing/construction from string Aug 20, 2024
@JeffreySarnoff
Copy link
Member

Looking into this -- thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants