Index: src/org/armedbear/lisp/Time.java =================================================================== --- src/org/armedbear/lisp/Time.java (revision 14839) +++ src/org/armedbear/lisp/Time.java (working copy) @@ -117,19 +117,34 @@ @Override public LispObject execute() { - TimeZone tz = TimeZone.getDefault(); - //int offset = tz.getOffset(System.currentTimeMillis()); - // Classpath hasn't implemented TimeZone.getOffset(long). - int rawOffset = tz.getRawOffset(); - final boolean inDaylightTime = - tz.inDaylightTime(new Date(System.currentTimeMillis())); - if (inDaylightTime) - rawOffset += tz.getDSTSavings(); - // "Time zone values increase with motion to the west..." - // Convert milliseconds to hours. - return LispThread.currentThread().setValues( - Fixnum.getInstance(- rawOffset).divideBy(Fixnum.getInstance(3600000)), - inDaylightTime ? T : NIL); + return getTimeZone(System.currentTimeMillis()); } }; + + private static final LispObject getTimeZone(long unixTimeMillis) { + TimeZone tz = TimeZone.getDefault(); + //int offset = tz.getOffset(System.currentTimeMillis()); + // Classpath hasn't implemented TimeZone.getOffset(long). + int rawOffset = tz.getRawOffset(); + final boolean inDaylightTime = + tz.inDaylightTime(new Date(unixTimeMillis)); + if (inDaylightTime) + rawOffset += tz.getDSTSavings(); + // "Time zone values increase with motion to the west..." + // Convert milliseconds to hours. + return LispThread.currentThread().setValues( + Fixnum.getInstance(- rawOffset).divideBy(Fixnum.getInstance(3600000)), + inDaylightTime ? T : NIL); + } + + // ### get-time-zone universal-time => hours-west daylight-p + private static final Primitive GET_TIME_ZONE = + new Primitive("get-time-zone", PACKAGE_SYS, false) + { + @Override + public LispObject execute(LispObject arg) + { + return getTimeZone((arg.longValue() - 2208988800L) * 1000); + } + }; } Index: src/org/armedbear/lisp/time.lisp =================================================================== --- src/org/armedbear/lisp/time.lisp (revision 14839) +++ src/org/armedbear/lisp/time.lisp (working copy) @@ -53,7 +53,7 @@ (if time-zone (setf seconds-west (* time-zone 3600) daylight nil) - (multiple-value-bind (time-zone daylight-p) (default-time-zone) + (multiple-value-bind (time-zone daylight-p) (get-time-zone universal-time) (setf seconds-west (* time-zone 3600) daylight daylight-p))) (multiple-value-bind (weeks secs) @@ -142,4 +142,7 @@ (- (leap-years-before year) (leap-years-before fake-year)))))))) (t - (+ second (* (+ minute (* (+ hours (default-time-zone)) 60)) 60)))))) + (let* ((tz-guess (get-time-zone (* hours 3600))) + (guess (+ second (* 60 (+ minute (* 60 (+ hours tz-guess)))))) + (tz (get-time-zone guess))) + (+ guess (* 3600 (- tz tz-guess))))))))