     1970 <year-gmt> ; inline
 
 : millis>timestamp ( x -- timestamp )
-    [ unix-1970 ] dip milliseconds time+ ;
+    [ unix-1970 ] dip 1000 / +second ;
 
 : timestamp>millis ( timestamp -- n )
     unix-1970 (time-) 1000 * >integer ;
 
 : micros>timestamp ( x -- timestamp )
-    [ unix-1970 ] dip microseconds time+ ;
+    [ unix-1970 ] dip 1000000 / +second ;
 
 : timestamp>micros ( timestamp -- n )
     unix-1970 (time-) 1000000 * >integer ;
 
-: now ( -- timestamp ) gmt >local-time ;
+: now ( -- timestamp )
+    gmt gmt-offset-duration (time+) >>gmt-offset ;
+
 : hence ( duration -- timestamp ) now swap time+ ;
+
 : ago ( duration -- timestamp ) now swap time- ;
 
 : zeller-congruence ( year month day -- n )

    unix-1970 time+ ; inline

: timestamp>unix-time ( timestamp -- seconds )
    unix-1970 time- second>> ; inline

: unix-time>timestamp ( seconds -- timestamp )
    seconds since-1970 ; inline

{
    { [ os unix? ] [ "calendar.unix" ] }

: before ( duration -- -duration )
    -1 time* ;

<PRIVATE

: -slots ( obj1 obj2 quot -- n obj1 obj2 )
    [ bi@ - ] curry 2keep ; inline

PRIVATE>

M: duration time-
    over timestamp? [
        before time+
    ] [
        [ year>> ] -slots
        [ month>> ] -slots
        [ day>> ] -slots
        [ hour>> ] -slots
        [ minute>> ] -slots
        [ second>> ] -slots
        2drop <duration>
    ] if ;

: <zero> ( -- timestamp )
    0 0 0 <date-gmt> ; inline
