diff --git a/extra/calendar/calendar-tests.factor b/extra/calendar/calendar-tests.factor old mode 100644 new mode 100755 index 3b0cfc8455..a3ae5f115a --- a/extra/calendar/calendar-tests.factor +++ b/extra/calendar/calendar-tests.factor @@ -1,5 +1,5 @@ USING: arrays calendar kernel math sequences tools.test -continuations system ; +continuations system io.streams.string ; [ 2004 12 32 0 0 0 0 make-timestamp ] [ "invalid timestamp" = ] must-fail-with [ 2004 2 30 0 0 0 0 make-timestamp ] [ "invalid timestamp" = ] must-fail-with @@ -141,3 +141,23 @@ continuations system ; [ t ] [ 0 unix-time>timestamp unix-1970 = ] unit-test [ t ] [ 123456789 [ unix-time>timestamp timestamp>unix-time ] keep = ] unit-test [ t ] [ 123456789123456789 [ unix-time>timestamp timestamp>unix-time ] keep = ] unit-test + +[ 0 ] [ + "Z" [ read-rfc3339-gmt-offset ] with-string-reader +] unit-test + +[ 1 ] [ + "+01" [ read-rfc3339-gmt-offset ] with-string-reader +] unit-test + +[ -1 ] [ + "-01" [ read-rfc3339-gmt-offset ] with-string-reader +] unit-test + +[ -1-1/2 ] [ + "-01:30" [ read-rfc3339-gmt-offset ] with-string-reader +] unit-test + +[ 1+1/2 ] [ + "+01:30" [ read-rfc3339-gmt-offset ] with-string-reader +] unit-test diff --git a/extra/calendar/calendar.factor b/extra/calendar/calendar.factor index a8d76ac86f..5b89d6e8c5 100755 --- a/extra/calendar/calendar.factor +++ b/extra/calendar/calendar.factor @@ -373,32 +373,53 @@ M: timestamp year. ( timestamp -- ) #! Example: Tue, 15 Nov 1994 08:12:31 GMT >gmt timestamp>rfc822-string ; +: write-rfc3339-gmt-offset ( n -- ) + dup zero? [ drop "Z" write ] [ + dup 0 < [ CHAR: - write1 neg ] [ CHAR: + write1 ] if + 60 * 60 /mod swap write-00 CHAR: : write1 write-00 + ] if ; + : (timestamp>rfc3339) ( timestamp -- ) dup timestamp-year number>string write CHAR: - write1 dup timestamp-month write-00 CHAR: - write1 dup timestamp-day write-00 CHAR: T write1 dup timestamp-hour write-00 CHAR: : write1 dup timestamp-minute write-00 CHAR: : write1 - timestamp-second >fixnum write-00 CHAR: Z write1 ; + dup timestamp-second >fixnum write-00 + timestamp-gmt-offset write-rfc3339-gmt-offset ; : timestamp>rfc3339 ( timestamp -- str ) - >gmt [ (timestamp>rfc3339) ] with-string-writer ; + [ (timestamp>rfc3339) ] with-string-writer ; -: expect read1 assert= ; +: expect ( str -- ) + read1 swap member? [ "Parse error" throw ] unless ; + +: read-00 2 read string>number ; + +: read-0000 4 read string>number ; + +: read-rfc3339-gmt-offset ( -- n ) + read1 dup CHAR: Z = [ drop 0 ] [ + { { CHAR: + [ 1 ] } { CHAR: - [ -1 ] } } case + read-00 + read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case + 60 / + * + ] if ; : (rfc3339>timestamp) ( -- timestamp ) - 4 read string>number ! year - CHAR: - expect - 2 read string>number ! month - CHAR: - expect - 2 read string>number ! day - CHAR: T expect - 2 read string>number ! hour - CHAR: : expect - 2 read string>number ! minute - CHAR: : expect - 2 read string>number ! second - 0 ; + read-0000 ! year + "-" expect + read-00 ! month + "-" expect + read-00 ! day + "Tt" expect + read-00 ! hour + ":" expect + read-00 ! minute + ":" expect + read-00 ! second + read-rfc3339-gmt-offset ! timezone + ; : rfc3339>timestamp ( str -- timestamp ) [ (rfc3339>timestamp) ] with-string-reader ;