Opened 8 years ago

Closed 8 years ago

#55 closed defect (fixed)

synchronize_times() may fail when the server is east of the client

Reported by: ftputiluser Owned by: schwa
Priority: major Milestone: 2.6
Component: Library Version: 2.5
Keywords: GMT, mtime, assertion Cc: tshinnic@…

Description (last modified by schwa)

synchronize_times() must fail with assertion

  ftputil.ftp_error.TimeShiftError: time shift (-31514426.37 s) > 1 day
  Debugging info: ftputil 2.5, Python 2.7 (win32)

when the client and/or server are in western time zones and the server reports file/dir time as GMT.

After creating a test file, synchronize_times() calls

    server_time = self.path.getmtime(helper_file_name)

to get the server-relative time. getmtime() uses the normal functions to develop the time value.

Within parse_unix_time() the code attempts to figure out which year a directory line references, e.g.

  line = -rw-r--r--    1 500      500             0 Jan 12 20:43 _ftputil_sync_

when no year value is present in a listing line like above. If the time value developed by the code assuming "this year" is some impossible *future* time value, then it decides the correct year must be "last year".

The code uses

    if st_mtime > time.time() + time_shift + 60.0:

as a check for whether the year is correct. But if the server time is GMT, and the local client is two or more time zones west of GMT, then this check will always be true, and the year return will *always* be last year, and the __assert_valid_time_shift() rule 1 will always fail.

As a check, I set the time_shift() value correctly, and then the problem didn't assert.

I got some snapshots while stepping through the code, and for the directory line above.

  (Pdb) year, month, day,  hour, minute
  (2011, 1, 12, 20, 43)

  (Pdb) st_mtime, time.asctime(time.localtime(st_mtime))
  (1294886580.0, 'Wed Jan 12 20:43:00 2011')

  197  -> if st_mtime > time.time() + time_shift + 60.0:
  (Pdb) st_mtime, time.time(), time_shift
  (1294886580.0, 1294865365.84, 0.0)
  198  ->                 st_mtime = time.mktime( (year-1, month, day,
  199                                              hour, minute, 0, 0, 0, -1) )

  (Pdb) st_mtime, time.asctime(time.localtime(st_mtime))
  (1263350580.0, 'Tue Jan 12 20:43:00 2010')
                                      ^^^^

I've seen mention of these symptoms with ftputil using Google, but don't remember where. I hope this explains the scenario. Maybe I'll have more insight to a solution later.

Change History (5)

comment:1 Changed 8 years ago by schwa

  • Description modified (diff)

Many thanks for the detailed report! :-)

(I added some code markup to the description for better readability.)

comment:2 in reply to: ↑ description Changed 8 years ago by schwa

  • Description modified (diff)
  • Status changed from new to assigned

Replying to ftputiluser:

The code uses if st_mtime > time.time() + time_shift + 60.0: as a check for whether the year is correct. But if the server time is GMT, and the local client is two or more time zones west of GMT, then this check will always be true, and the year return will *always* be last year, and the __assert_valid_time_shift() rule 1 will always fail.

The problem is that synchronize_times calls getmtime which calls parse_unix_time - but parse_unix_time uses the very time shift value that synchronize_times is supposed to set in the first place. So the time shift value at the time of the year determination is still 0.0, regardless of the actual time zone difference. This, in turn, makes parse_unix_time conclude a wrong year.

As a check, I set the time_shift() value correctly, and then the problem didn't assert.

This supports my interpretation nicely. :-)

comment:3 Changed 8 years ago by schwa

  • Milestone set to 2.6

The bug should be fixed in changeset [6d59213b9b9a]. It would be great if you could report if the problem is fixed for you.

comment:4 Changed 8 years ago by schwa

  • Summary changed from synchronize_times() fails in western time zones when server GMT times to synchronize_times() may fail when the server is east of the client

To help other users finding a solution to similar problems, I changed the title to reflect that the server doesn't have to be in the GMT time zone.

comment:5 Changed 8 years ago by schwa

  • Resolution set to fixed
  • Status changed from assigned to closed

The problem seems to be fixed according to an e-mail by the reporter of this ticket. Thanks!

Note: See TracTickets for help on using tickets.