 : friday ( timestamp -- timestamp ) 5 day-this-week ;
 : saturday ( timestamp -- timestamp ) 6 day-this-week ;
 
+: beginning-of-day ( timestamp -- new-timestamp )
+    clone dup >r 0 0 0 r>
+    { set-timestamp-hour set-timestamp-minute set-timestamp-second }
+    set-slots ; inline
+
+: beginning-of-month ( timestamp -- new-timestamp )
+    beginning-of-day 1 over set-timestamp-day ;
+
+: beginning-of-week ( timestamp -- new-timestamp )
+    beginning-of-day sunday ;
+
+: beginning-of-year ( timestamp -- new-timestamp )
+    beginning-of-month 1 over set-timestamp-month ;
+
+: seconds-since-midnight ( timestamp -- x )
+    dup beginning-of-day timestamp- ;
+
 {
     { [ unix? ] [ "calendar.unix" ] }
     { [ windows? ] [ "calendar.windows" ] }

    [ [ >date< julian-day-number ] 2apply - 86400 * ] 2keep
    [ >time< >r >r 3600 * r> 60 * r> + + ] 2apply - + ;

: unix-1970
    1970 1 1 0 0 0 0 <timestamp> ;

: unix-time>timestamp ( n -- timestamp )
    >r unix-1970 r> seconds +dt ;

: timestamp>unix-time ( timestamp -- n )
    unix-1970 timestamp- >bignum ;

: timestamp>timeval ( timestamp -- timeval )
    timestamp>unix-time 1000 * make-timeval ;

USING: arrays hashtables io io.streams.string kernel math
math.vectors math.functions math.parser namespaces sequences
strings tuples system debugger combinators vocabs.loader
calendar.backend structs alien.c-types math.vectors
math.ranges shuffle ;
IN: calendar

TUPLE: timestamp year month day hour minute second gmt-offset ;
