Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix SFTP file UTC time handling #356

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

Merged
merged 6 commits into from
Jul 18, 2020
Merged

Fix SFTP file UTC time handling #356

merged 6 commits into from
Jul 18, 2020

Conversation

menees
Copy link
Contributor

@menees menees commented Dec 13, 2017

I changed SftpFileAttributes to preserve the last access and modified times as UTC values rather than always forcing a local conversion. This primarily affected the FromBytes(SshDataStream) method, but the changes cascade out from there to make sure that SftpFileAttributes and SftpFile can be used without ever forcing a (potentially lossy) conversion to local time. In the SSH data stream the atime and mtime values are "Unix times" in seconds, so they're already in UTC. We need to preserve that fact by returning and storing DateTime values with Kind == Utc.

Previously, the code called DateTime.FromFileTime. Internally, FromFileTime calls DateTime.ToLocalTime(), which is a lossy function. For example, any local time >= 1am and < 2am during the "fall back" hour of a daylight saving time shift in the fall could have come from two different UTC times. Avoiding this ambiguity is why file systems store times in UTC, so the SFTP classes need to preserve UTC times too. Here's a simple example to see this in VS's C# interactive window:

TimeZoneInfo central = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime first = new DateTime(2017, 11, 5, 6, 0, 0, DateTimeKind.Utc);
DateTime second = new DateTime(2017, 11, 5, 7, 0, 0, DateTimeKind.Utc);
Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(first, central));
Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(second, central));
// Both UTC times convert to the same local time: 11/5/2017 1:00:00 AM

.NET also has an issue where it caches the current local time zone offset, so it can incorrectly calculate local times after a DST shift if nothing has called CultureInfo.ClearCachedData or TimeZoneInfo.ClearCachedData. This is discussed more at https://stackoverflow.com/a/297189/1882616, and it can be a big problem in long-running services if not handled correctly. By making SSH.NET internally preserve UTC times correctly, the library can be immune to problems with DST shifts for callers that only work with UTC times.

I also cleaned up some warnings in the unit tests and added an .editorconfig file so VS 2017 will know to use spaces for indentation in this solution (even though my global preference is set to tabs).

@stefer
Copy link

stefer commented Apr 4, 2018

This is not only "improve" - I would say it is "correct" UTC time handling, see #415

@menees
Copy link
Contributor Author

menees commented Mar 16, 2020

@drieseng Is there any way you could bump up the priority on merging in this pull request please? I originally said "improved", but I actually agree with @stefer that this is the correct UTC time handling. I'd really like to stop having to maintain and ship my own fork because correct UTC time support is extremely important in my app. Thanks!

@drieseng
Copy link
Member

@bmenees I first want to have an integration test to validate these changes. I hope to have time for that this weekend.

@menees
Copy link
Contributor Author

menees commented Mar 19, 2020

Thanks! I really appreciate it and all of your hard work on this project!

@menees
Copy link
Contributor Author

menees commented Jul 10, 2020

@drieseng Have you had a chance to validate these changes? I'd really like to get this pull request merged in. Thanks!

@drieseng
Copy link
Member

@menees Sorry to inform you, but our policy is to not accept PRs from developers that prefer tabs over spaces.

@drieseng drieseng closed this Jul 11, 2020
@drieseng drieseng reopened this Jul 11, 2020
@drieseng
Copy link
Member

We may reconsider :)

@drieseng
Copy link
Member

drieseng commented Jul 11, 2020

I'm really gonna try to find time tomorrow to create an integration test for this PR.
Sorry it has taken this much time. If you could swap for a week, you'd surely understand.

@menees
Copy link
Contributor Author

menees commented Jul 11, 2020

Thanks. Regarding tabs vs. spaces, all of my changes in this PR use spaces for indentation. That's why I added the .editorconfig file. My "global" preference in VS is tabs, but the .editorconfig I added at the solution-level makes VS use and respect the solution-level setting of spaces (instead of my or anyone else's global preference).

So, that's another advantage to merging this PR. In the future, anyone editing the SSH.NET code in VS 2017 or later (or any of the 20+ other editors that support .editorconfig) will automatically use spaces for indentation since that's what the .editorconfig declares as the solution's preference. Then you'll have fewer PRs using tabs (or none, hopefully).

@drieseng
Copy link
Member

drieseng commented Jul 12, 2020

@menees I should've been more explicit: the fact that I closed the PR due to the tabs vs. spaces battle was a joke!

Can you move the .editorconfig to a separate PR? I'd like to review/discuss the config (and again, I'm not talking about tabs vs. spaces) before we merge it.

Removed .editorconfig from PR at [@drieseng's request](sshnet#356 (comment)).
@menees
Copy link
Contributor Author

menees commented Jul 12, 2020

I deleted .editorconfig from this PR because GitHub makes that easy. I really only need the fixes for UTC time handling merged in.

@menees menees changed the title Improved SFTP file UTC time handling Fix SFTP file UTC time handling Jul 12, 2020
@drieseng drieseng merged commit 90a13a6 into sshnet:develop Jul 18, 2020
@drieseng
Copy link
Member

@menees, thanks!!

@drieseng drieseng added this to the 2020.0.0-beta2 milestone Jul 18, 2020
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

Successfully merging this pull request may close these issues.

4 participants