[jcifs] timezone problems

Julian Reschke julian.reschke at gmx.de
Tue Mar 9 19:47:59 GMT 2004


Christopher R. Hertel wrote:

> On Tue, Mar 09, 2004 at 07:54:09PM +0100, Julian Reschke wrote:
> :
> 
>>>If the [file] time[stamp] being reported via SMB is based on the 
>>>*server's* local time [that is, if the SMB message contains the SMB_TIME 
>>>and SMB_DATE as listed in FAT], then the client must convert the time [for 
>>>display purposes] to the *client's* local time.
>>
>>No, it doesn't have to.
> 
> 
> Well, okay, I'm not being clear here.  I'm just trying to paint a picture 
> of the situation that would show this.
> 
> 
>>The SMB library itself is first of all required 
>>to report the correct UTC-based timestamp (this is what the Java API is 
>>about).
> 
> 
> To be comaptible with java.io.File we have to convert the SMB_TIME and 
> SMB_DATE values to Java UTC.

Great, it's good we have agreement here :-)

>>Of course a client running on top of that can use the client's local 
>>timezone settings to display the normalized UTC timestamp, but this is a 
>>transformation that should occur *on top* of SmbFile.getLastModified().
> 
> 
> Right, but that's the model I was working with.  :)

OK, so that's clarified now. It's not the model that applies to the Java 
UTC long timestamps used by SmbFile.

>>>Since the file timestamps are stored in server local time (in FAT) I
>>>assume that they are also reported that way via SMB.  To convert those
>>>into UTC you also need to know the difference between server time and UTC.
>>
>>I'm no SMB expert, and I have trouble following this description. If the 
>>SMB protocol provides an UTC-based timestamp, and JCifs is supposed to 
>>return UTC-based timestamps, why do we need a translation at this level?
> 
> 
> At session startup the server returns a timestamp in bozoseconds
> (10^-7) since Jan. 1 1601.  The client uses this to figure out the offset 
> between the server's time and its own time.
> 
> The problem is that the FAT filesystem stores timestamps in local time, 
> and SMB reports those times when reporting file timestamps.  The file 
> timestamps do not contain Daylight Savings information, just the raw local 
> time.  That's a royal pain, since the client has to figure out the 
> Daylight Savings information of the server in order to convert the file 
> timestamp information to UTC.

That doesn't seem to be consistent with the code I'm looking at...:


     static long readTime( byte[] src, int srcIndex ) {
         int low = readInt4( src, srcIndex );
         int hi = readInt4( src, srcIndex + 4 );
         long t = ((long)hi << 32 ) | ( (long)low & 0xFFFFFFFFL );
         t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 );

         synchronized( TZ ) {
             if( TZ.inDaylightTime( new Date() )) {
                 // in DST
                 if( TZ.inDaylightTime( new Date( t ))) {
                     // t also in DST so no correction
                     return t;
                 }
                 // t not in DST so add 1 hour
                 return t + 3600000;
             } else {
                 // not in DST
                 if( TZ.inDaylightTime( new Date( t ))) {
                     // t is in DST so subtract 1 hour
                     return t - 3600000;
                 }
                 // t isn't in DST either
                 return t;
             }
         }
     }

This certainly looks like code that unpacks a 64-bit timestamp, not a 
FAT timestamp....

> The same packet that returns the initial timestamp also returns a timezone 
> offset.  That offset is the *current* offset from UTC.
> 
> Anyway, I don't know the "normal" way of handling these file timestamps.  
> I have not tested this part of the protocol (recently), but assume that
> all clients simply adjust the SMB_TIME and SMB_DATE by using the 
> ServerTimeZone info provided in the NegProt at the start of the session.

But what's happening in the code above is that the *client's* timezone 
and DST settings are used for the adjustment. How is this supposed to be 
correct, unless both server and client happen to be in the same timezone?

> Anyway, as you can see this is complex.  It shouldn't be, but DOS, FAT, 
> and SMB all have long and convoluted histories.  My guess is that 
> upgrading to Samba 2.2.8a will fix this.  If not, then I'll run your code 
> and do some captures to see what's different.

The issue was triggered by JCifs' behaviour against a Windows2000 server 
(same for Windows 2003). I only tested Samba because you asked me to do 
so. As a matter of fact this was a good thing to do, because it shows 
that at least *that* Samba version behaves differently than W2K.


Julian

-- 
<green/>bytes GmbH -- http://www.greenbytes.de -- tel:+492512807760


More information about the jcifs mailing list