{decode,encode}-universal-time "time of the time" timezone semantics

Scott L. Burson

The implementation of EXT:GET-TIME-ZONE provides the underlying
mechanism.

Both GET-TIME-ZONE and DEFAULT-TIME-ZONE have been elevated to
supported status by virtue of promotion of their respective symbols to
the EXTENSIONS and SYSTEM packages, respectively.

ME: A mechanism for adding symbols to both SYS and EXT packages with
DEFINE-SYMBOL-MACRO didn't work, but left as comment at the end of
'time.lisp' for further work.
parent e6137401
......@@ -519,6 +519,7 @@ public class Autoload extends Function
autoload(PACKAGE_EXT, "file-directory-p", "probe_file", true);
autoload(PACKAGE_EXT, "gc", "gc", true);
autoload(PACKAGE_EXT, "get-floating-point-modes", "FloatFunctions", true);
autoload(PACKAGE_EXT, "get-time-zone", "Time", true);
autoload(PACKAGE_EXT, "make-slime-input-stream", "SlimeInputStream", true);
autoload(PACKAGE_EXT, "make-slime-output-stream", "SlimeOutputStream", true);
autoload(PACKAGE_EXT, "probe-directory", "probe_file", true);
......
......@@ -111,25 +111,46 @@ public final class Time
};
// ### default-time-zone => offset daylight-p
private static final Primitive DEFAULT_TIME_ZONE =
new Primitive("default-time-zone", PACKAGE_SYS, false)
public static final Primitive DEFAULT_TIME_ZONE = new pf_default_time_zone();
@DocString(name="default-time-zone",
args="",
returns="offset daylight-p",
doc="Returns the OFFSET of the default time zone for this instance of the implementation, and as a second value the state of the DAYLIGHT-P predicate.")
public static final class pf_default_time_zone extends Primitive {
pf_default_time_zone() {
super("default-time-zone", PACKAGE_SYS, true);
}
public LispObject execute()
{
@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 GET_TIME_ZONE.execute(LispInteger.getInstance(System.currentTimeMillis()));
}
};
public static final Primitive GET_TIME_ZONE = new pf_get_time_zone();
@DocString(name="get-time-zone",
args="time-in-millis",
returns="timezone",
doc="Return the timezone for TIME-IN-MILLIS via the Daylight assumptions that were in place at its occurance. i.e. implement 'time of the time semantics'." )
public static final class pf_get_time_zone extends Primitive {
pf_get_time_zone() {
super("get-time-zone", PACKAGE_EXT, true, "");
}
public LispObject execute(LispObject unixTimeMillis) {
// should be a reference to a singleton for the lifetime of an ABCL process
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.longValue()));
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);
}
};
}
......@@ -42,6 +42,8 @@
(defconstant november-17-1858 678882)
(defconstant weekday-november-17-1858 2)
;;; decode-universal-time universal-time &optional time-zone
;;; => second minute hour date month year day daylight-p zone
;;; If time-zone is not supplied, it defaults to the current time zone adjusted
......@@ -53,7 +55,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) (ext:get-time-zone universal-time)
(setf seconds-west (* time-zone 3600)
daylight daylight-p)))
(multiple-value-bind (weeks secs)
......@@ -127,7 +129,10 @@
(* (- year 1900) 365)))
(hours (+ hour (* days 24))))
(cond (time-zone
(+ second (* (+ minute (* (+ hours 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)))))
((> year 2037)
(labels ((leap-year-p (year)
(cond ((zerop (mod year 400)) t)
......@@ -143,3 +148,10 @@
(leap-years-before fake-year))))))))
(t
(+ second (* (+ minute (* (+ hours (default-time-zone)) 60)) 60))))))
#|
(intern "GET-TIME-ZONE" (find-package :ext))
(define-symbol-macro EXT:GET-TIME-ZONE
`(get-time-zone))
(export (intern "GET-TIME-ZONE" (find-package :ext)))
#|
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment