[jcifs] timezone problems

Julian Reschke julian.reschke at gmx.de
Wed Mar 10 14:54:55 GMT 2004


Michael B Allen wrote:
> Julian Reschke said:
> 
> Ok, I think I see what you're talking about. I tried your program on
> Windows NT 4.0 and I see the discrepency. Something is definately wrong
> but I don't think it has to do with jCIFS. It's either the Java VM on
> Linux or the Java VM on Windows.

It's good that we agree that something is wrong. So let's try to find 
out what it is.

I think we can rule out java.io.File, because checking the timestamps 
using Cygwin's date utility confirms that the timestamp was created 
correctly.

Just to make sure, I'm also testing with standard Microsoft utilities:

    var fso, f;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    f = fso.GetFile(WScript.Arguments(0));
    WScript.Echo("created: " + f.DateCreated);
    WScript.Echo("mod: " + f.DateLastModified);

and they confirm that the timestamps are correct.

BTW: I really don't care what the Windows Explorer says because there's 
yet another layer of UI/"user friendlyness" stuff going on that I don't 
control. Anyway, on my machine Windows Explorer displays both files with 
1am, which is correct as I am in UTC+0100.

> Basically your program creates a java.io.File with a time of Jun 21 8PM
> but if you look at this timestamp in Windows Explorer it reads 7PM. That

So what does it look like when you use a standard tool such as "date" to 
check it?

> in itself is suspect. If I run the program on Linux with Samba 2.2.8a it
> works and all the timestamps match up. At one point you suggested there's
> a bug in Samba that's cancelling out a bug in jCIFS but if you 'stat' the
> files in Linux the times are still right. So the only deviant is
> java.io.File on Windows.

 From what I see, the only deviant is Samba (2.2.0 at least). On 
Windows, all of the following match for me:

- timestamp set by java.io.File
- timestamp reported by java.io.File
- timestamp reported by Cygwin "date"
- timestamp reported by Windows Scripting Host Filesystem object (all 
Microsoft :-)

> I don't see where UTC comes in. I'm in NYC which is -5 so that alone
> doesn't account for a descrepency of 1 hour.

Correct. The one hour discrepancy is caused by the DST adjustment, not 
the timezone.

>>>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?
> 
> 
> It's been a long while since I worked through this stuff and I never rule
> out the possabilty for a bug when working with CIFS but if you look at 3.7
> in the "CIFS Technical Reference" it claims timestamps are UTC but then
> explains that they "include an additional correction factor" of *the
> daylight savings in effect at the time the file was created/modified*
> minus the current daylight savings.

Yes, it says that (but it doesn't say that in the earlier draft).

Anyway. If there is a DST adjustment in the servers response, how does 
checking the *client's* timezone setting is supposed to help computing 
the UTC???

> So if the client is given the server time and timestamps emitted are
> relative to that you need to correct the "correction factor" by adjusting
> for DST and the difference between the server's TZ (provided in the
> negprot response) and your own (the clients) TZ.

Sorry, I still don't understand. For calculating the UTC from a 
timestamp in a server response, how is the *client's* timezone and DST 
setting relevant?

Looking again at the code:

         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;
             }
         }

Translating into pseudo-code:

if (client is in DST period) {
   if (timestamp is in DST period) {
     return timestamp
   }
   else {
     return timestamp + 1 hour
   }
}
else {
   if (timestamp is in DST period) {
     return timestamp - 1 hour
   }
   else {
     return timestamp
   }
}

Basically this means that the DST setting of the *client* machine on 
which JCifs is running is causing a 1-hour-shift for the *UTC* dates 
reported by SmbFile.

Is this really really intended?

> It's crazy enough that the calculation we're using could be wrong but
> currently I don't see a problem.

Well, we all agree that the system's behaviour is wrong, and we all can 
reproduce it. So it should be possible to identify thex exact component, 
right?

Best regards and thanks for the feedback,

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


More information about the jcifs mailing list