From sross at common-lisp.net Thu Mar 17 11:40:39 2005 From: sross at common-lisp.net (Sean Ross) Date: Thu, 17 Mar 2005 12:40:39 +0100 (CET) Subject: [cl-l10n-cvs] CVS update: cl-l10n/ChangeLog Message-ID: <20050317114039.69DAB8866B@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv32081 Modified Files: ChangeLog Log Message: Changelog 2005-03-17 Date: Thu Mar 17 12:40:36 2005 Author: sross Index: cl-l10n/ChangeLog diff -u cl-l10n/ChangeLog:1.11 cl-l10n/ChangeLog:1.12 --- cl-l10n/ChangeLog:1.11 Tue Feb 22 15:18:25 2005 +++ cl-l10n/ChangeLog Thu Mar 17 12:40:34 2005 @@ -1,6 +1,12 @@ +2005-03-17 Sean Ross + * doc/cl-l10n.texi: Cleaned up so that it + works with makeinfo. + 2005-02-22 Sean Ross * printers.lisp: Added a formatter compiler macro to remove unnecessary calls to parse-fmt-string. + * load-locale.lisp: Added a loader for the locale + function which will be called if passed in. 2005-02-17 Sean Ross * locale.lisp: Added support for Allegro CL. From sross at common-lisp.net Thu Mar 17 11:40:41 2005 From: sross at common-lisp.net (Sean Ross) Date: Thu, 17 Mar 2005 12:40:41 +0100 (CET) Subject: [cl-l10n-cvs] CVS update: cl-l10n/doc/cl-l10n.texi Message-ID: <20050317114041.008AC88678@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n/doc In directory common-lisp.net:/tmp/cvs-serv32081/doc Modified Files: cl-l10n.texi Log Message: Changelog 2005-03-17 Date: Thu Mar 17 12:40:39 2005 Author: sross Index: cl-l10n/doc/cl-l10n.texi diff -u cl-l10n/doc/cl-l10n.texi:1.5 cl-l10n/doc/cl-l10n.texi:1.6 --- cl-l10n/doc/cl-l10n.texi:1.5 Thu Dec 30 12:56:45 2004 +++ cl-l10n/doc/cl-l10n.texi Thu Mar 17 12:40:39 2005 @@ -99,7 +99,7 @@ CL-L10N uses @uref{http://cliki.net/asdf,,asdf} as it's system definition tool and is required whenever you load the package. You will need to download it, or if you have @uref{http://sbcl.org,,sbcl} - at lisp (require 'asdf) @end lisp + at code{(require 'asdf)} @section Downloading @@ -107,7 +107,7 @@ @item ASDF-INSTALL CL-L10N is available through asdf-install. If you are new to Common Lisp this is the suggested download method. With asdf-install loaded run - at lisp (asdf-install:install :cl-l10n) @end lisp + at code{(asdf-install:install :cl-l10n)} This will download and install the package for you. Asdf-install will try to verify that the package signature is correct and that you trust the author. If the key is not found or the trust level is not sufficient a continuable error will be signalled. @@ -141,25 +141,25 @@ @chapter API @section Variables - at anchor {Variable *locale*} + at anchor{Variable *locale*} @vindex *locale* @deftp {Variable} *locale* The default locale which will be used. @end deftp - at anchor {Variable *locale-path*} + at anchor{Variable *locale-path*} @vindex *locale-path* @deftp {Variable} *locale-path* The default pathname where locale definition files can be found. @end deftp - at anchor {Variable *locales*} + at anchor{Variable *locales*} @vindex *locales* @deftp {Variable} *locales* A hash table containing loaded locales keyed on locale name. @end deftp - at anchor {Variable *float-digits*} + at anchor{Variable *float-digits*} @vindex *float-digits* @deftp {Variable} *float-digits* An integer value which determines the number of digits @@ -170,12 +170,12 @@ @section Functions - at anchor {Function locale-name} + at anchor{Function locale-name} @deffn {Function} locale-name locale Returns the name of @emph{locale}. @end deffn - at anchor {Function locale} + at anchor{Function locale} @deffn {Function} locale name &key (use-cache t) (errorp t) Loads the locale designated by the locale-designator @emph{name} which is expected to be found in @code{*locale-path*}. If use-cache is @code{nil} the @@ -184,25 +184,25 @@ will be signalled. @end deffn - at anchor {Function locale-value} + at anchor{Function locale-value} @deffn {Function} locale-value locale category-name key Returns the value of @emph{key} in cagetory @emph{category-name} found in the @code{locale} @emph{locale}. @end deffn - at anchor {Function load-all-locales} + at anchor{Function load-all-locales} @deffn {Function} load-all-locales &optional (path *locale-path*) Load all locales found in pathname @emph{path}. @end deffn - at anchor {Function print-number} + at anchor{Function print-number} @deffn {Function} print-number number &key (stream *standard-output) no-ts no-dp locale *locale* Prints @emph{number} using locale @emph{locale}. If @emph{no-ts} is not nil no thousand seperators will be used when printing @emph{number}. If @emph{no-dp} is not nil the decimal seperator will be suppressed if @emph{number} is not an integer. @end deffn - at anchor {Function format-number} + at anchor{Function format-number} @deffn {Function} format-number stream arg no-dp no-ts &optional (locale *locale*) format-number is intended to be used as an argument to the ~/ / format directive. Example (assuming *locale* is en_ZA) @@ -214,14 +214,14 @@ @end deffn - at anchor {Function print-money} + at anchor{Function print-money} @deffn {Function} print-money value &key (stream *standard-output) use-int-sym no-ts (locale *locale*) Prints @emph{value} as a monetary value using locale @emph{locale}. If @emph{no-ts} is not nil no thousand seperators will be used when printing @emph{number}. If @emph{use-int-sym} is not nil @code{locale-int-curr-symbol} will be used instead of the default @code{locale-currency-symbol} @end deffn - at anchor {Function format-money} + at anchor{Function format-money} @deffn {Function} format-money stream arg use-int-sym no-ts &optional (locale *locale*) Prints @emph{value} as a monetary value using locale @emph{locale}. format-money is intended to be used as the function to the ~/ / format directive @@ -238,13 +238,13 @@ @end lisp @end deffn - at anchor {Function print-time} + at anchor{Function print-time} @deffn {Function} print-time ut &key show-date show-time (stream *standard-output) (locale *locale) fmt Prints the @code{universal-time} @emph{ut} as a locale specific time to @emph{stream}. Equivalent to @code{(format-time stream ut show-date show-time locale fmt)}. @end deffn - at anchor {Function format-time} + at anchor{Function format-time} @deffn {function} format-time stream ut show-date show-time &optional (locale *locale*) fmt Prints the @code{universal-time} @emph{ut} as a locale specific time to @emph{stream}. The format of the time printed is controlled by @emph{show-time} and @emph{show-date}. @@ -284,7 +284,7 @@ @end verbatim @end deffn - at anchor {Function format} + at anchor{Function format} @deffn {Function} format stream fmt-string &rest args Format is an unexported symbol in the cl-l10n package. It's use is to make formatting of dates, times, numbers and monetary @@ -318,27 +318,27 @@ @end deffn - at anchor {Macro formatter} + at anchor{Macro formatter} @deffn {Macro} formatter fmt-string Formatter is another unexported symbol in the cl-l10n package Shadow importing formatter gives support for the new format control directives. @end deffn - at anchor {Function parse-number} + at anchor{Function parse-number} @deffn {Function} parse-number num-string &optional (locale *locale*) Parses the string @emph{num-string} into a number using @emph{locale}. @end deffn @section Classes - at anchor {Class locale} + at anchor{Class locale} @deftp {Class} locale Class Precedence: @code{standard-object} The class representing a loaded locale. @end deftp - at anchor {Class category} + at anchor{Class category} @deftp {Class} category Class Precedence: @code{standard-object} The class representing a loaded category within a locale. @@ -346,7 +346,7 @@ @section Conditions - at anchor {Condition locale-error} + at anchor{Condition locale-error} @deftp {Condition} locale-error Class Precedence: @code{condition} @@ -419,7 +419,7 @@ @end lisp @section API - at anchor {Generic add-resource} + at anchor{Generic add-resource} @deffn {Generic} add-resource bundle from to locale-name Adds an entry to @emph{bundle} for @emph{locale-name} mapping @emph{from} to @emph{to}. The @emph{locale-name} does not @@ -435,7 +435,7 @@ @end lisp @end deffn - at anchor {Macro add-resources} + at anchor{Macro add-resources} @deffn {Macro} add-resources (bundle locale-name) &rest entries Utility macro to group large amounts of entries into a single logical block for a locale. @@ -456,7 +456,7 @@ @end lisp @end deffn - at anchor {Function gettext} + at anchor{Function gettext} @deffn {Function} gettext name bundle &optional (*locale* *locale* ) Looks for a mapping for @emph{name} in @emph{bundle}. If no mapping is found returns name. From sross at common-lisp.net Wed Mar 23 10:58:18 2005 From: sross at common-lisp.net (Sean Ross) Date: Wed, 23 Mar 2005 11:58:18 +0100 (CET) Subject: [cl-l10n-cvs] CVS update: cl-l10n/ChangeLog cl-l10n/cl-l10n.asd cl-l10n/printers.lisp cl-l10n/tests.lisp cl-l10n/utils.lisp Message-ID: <20050323105818.99EFF884E2@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv11902 Modified Files: ChangeLog cl-l10n.asd printers.lisp tests.lisp utils.lisp Log Message: Changelog 2005-03-23 Date: Wed Mar 23 11:58:16 2005 Author: sross Index: cl-l10n/ChangeLog diff -u cl-l10n/ChangeLog:1.12 cl-l10n/ChangeLog:1.13 --- cl-l10n/ChangeLog:1.12 Thu Mar 17 12:40:34 2005 +++ cl-l10n/ChangeLog Wed Mar 23 11:58:16 2005 @@ -1,6 +1,9 @@ +2005-03-23 Sean Ross + * printers.lisp: Fixed the %w, %e, %x, %X, %d and %j time format directives. + * tests.lisp: Added a test for each supported time format directive. + 2005-03-17 Sean Ross - * doc/cl-l10n.texi: Cleaned up so that it - works with makeinfo. + * doc/cl-l10n.texi: Cleaned up so that it works with makeinfo. 2005-02-22 Sean Ross * printers.lisp: Added a formatter compiler macro Index: cl-l10n/cl-l10n.asd diff -u cl-l10n/cl-l10n.asd:1.9 cl-l10n/cl-l10n.asd:1.10 --- cl-l10n/cl-l10n.asd:1.9 Tue Feb 22 15:18:25 2005 +++ cl-l10n/cl-l10n.asd Wed Mar 23 11:58:16 2005 @@ -11,7 +11,7 @@ :name "CL-L10N" :author "Sean Ross " :maintainer "Sean Ross " - :version "0.2.3" + :version "0.2.5" :description "Portable CL Locale Support" :long-description "Portable CL Package to support localization" :licence "MIT" Index: cl-l10n/printers.lisp diff -u cl-l10n/printers.lisp:1.10 cl-l10n/printers.lisp:1.11 --- cl-l10n/printers.lisp:1.10 Tue Feb 22 15:18:25 2005 +++ cl-l10n/printers.lisp Wed Mar 23 11:58:16 2005 @@ -36,9 +36,8 @@ (defun print-number (number &key (stream *standard-output*) no-ts no-dp (locale *locale*)) - (let ((locale (locale-des->locale locale))) - (format-number stream number no-dp no-ts locale) - number)) + (format-number stream number no-dp no-ts locale) + number) ;; Money @@ -86,9 +85,8 @@ (defun print-money (num &key (stream *standard-output*) use-int-sym no-ts (locale *locale*)) - (let ((locale (locale-des->locale locale))) - (format-money stream num use-int-sym no-ts locale) - num)) + (format-money stream num use-int-sym no-ts locale) + num) ;; ;; Time and date printing. (defun get-time-fmt-string (locale show-date show-time) @@ -119,12 +117,19 @@ it (locale-error "No format directive for char ~S." char))) -(defun princ-pad-val (val stream &optional (pad "0")) +(defun princ-pad-val (val stream &optional (pad "0") (size 2)) (declare (type stream stream) (optimize speed) (type fixnum val)) - (when (< val 10) - (princ pad stream)) - (princ val stream)) + (assert (not (minusp val)) (val) "Value ~A cannot be smaller than 0." val) + (cond ((zerop val) + (dotimes (x (1- size)) + (princ pad stream)) + (princ 0 stream)) + (t + (loop for x = (* val 10) then (* x 10) + until (>= x (expt 10 size)) do + (princ pad stream)) + (princ val stream)))) (defun last-2-digits (val) (mod val 100)) @@ -139,17 +144,16 @@ (if (> day 6) (decf day 7)) (princ (nth day (locale-day locale)) stream))) - (def-formatter #\b - (cl:format stream (cl:formatter "~:(~A~)") + (cl:format stream (cl:formatter "~A") (nth (1- month) (locale-abmon locale)))) (def-formatter #\B - (cl:format stream (cl:formatter "~:(~A~)") + (cl:format stream (cl:formatter "~A") (nth (1- month) (locale-mon locale)))) (def-formatter #\c - (print-time-string "%a %b %d %T %Z %Y" stream ut locale)) + (print-time-string (locale-d-t-fmt locale) stream ut locale)) (def-formatter #\C (princ-pad-val (truncate (/ year 100)) stream)) @@ -161,7 +165,7 @@ (print-time-string "%m/%d/%y" stream ut locale)) (def-formatter #\e - (princ-pad-val month stream " ")) + (princ-pad-val date stream " ")) (def-formatter #\F (print-time-string "%Y-%m-%d" stream ut locale)) @@ -202,7 +206,7 @@ (incf total date))) (def-formatter #\j - (princ (day-of-year date month year) stream)) + (princ-pad-val (day-of-year date month year) stream "0" 3)) (def-formatter #\k (princ-pad-val hour stream " ")) @@ -236,7 +240,7 @@ stream)) (def-formatter #\r - (print-time-string "%X %p" stream ut locale)) + (print-time-string "%H:%M:%S %p" stream ut locale)) (def-formatter #\R (print-time-string "%H:%M" stream ut locale)) @@ -253,7 +257,7 @@ (princ #\Tab stream)) (def-formatter #\T - (print-time-string "%X" stream ut locale)) + (print-time-string "%H:%M:%S" stream ut locale)) (def-formatter #\u (let ((day (1+ day))) @@ -269,19 +273,19 @@ (locale-error "Unsupported time format directive ~S." #\V)) (def-formatter #\w - (let ((day (1- day))) - (if (< day 0) (incf day 7)) - (princ day stream))) + (let ((day (1+ day))) + (when (>= day 7) (decf day 7)) + (princ day stream))) ;; FIXME (def-formatter #\W (locale-error "Unsupported time format directive ~S." #\W)) (def-formatter #\x - (print-time-string "%m/%d/%y" stream ut locale)) + (print-time-string (locale-d-fmt locale) stream ut locale)) (def-formatter #\X - (print-time-string "%R:%S" stream ut locale)) + (print-time-string (locale-t-fmt locale) stream ut locale)) (def-formatter #\y (princ-pad-val (last-2-digits year) stream)) @@ -326,9 +330,8 @@ (defun print-time (ut &key show-date show-time (stream *standard-output*) (locale *locale*) fmt) - (let ((locale (locale-des->locale locale))) - (format-time stream ut show-date show-time locale fmt) - ut)) + (format-time stream ut show-date show-time locale fmt) + ut) ;; Format Index: cl-l10n/tests.lisp diff -u cl-l10n/tests.lisp:1.5 cl-l10n/tests.lisp:1.6 --- cl-l10n/tests.lisp:1.5 Tue Feb 1 08:58:25 2005 +++ cl-l10n/tests.lisp Wed Mar 23 11:58:16 2005 @@ -77,7 +77,7 @@ (deftest time.2 (format nil "~v:@/cl-l10n:format-time/" "sv_SE" 3091103120) - "s?n 12 Dec 1997 17.45.20") + "s?n 14 dec 1997 17.45.20") (deftest time.3 (format nil "~v/cl-l10n:format-time/" "en_US" 3091103120) @@ -95,26 +95,55 @@ (format nil "~v@/cl-l10n:format-time/" "sv_SE" 3091103120) "17.45.20") -(defparameter *full-test* - (format nil "%% %a %A %b %B %c %C %d %D %e %F %g %G %h %H %I ~ -%j %k %l %m %M %n %N %p %P %r %R %S %t %T %u %w %x %X %y %z %Z")) - -(deftest time.7 - (format nil "~v,v/cl-l10n:format-time/" "en_ZA" *full-test* 3091103120) - "% Sun Sunday Dec December Sun Dec 14 17:45:20 +0200 1997 19 14 12/14/97 12 1997-12-14 97 1997 Dec 17 05 348 17 5 12 45 - 000000000 17:45:20 17:45 20 17:45:20 7 5 12/14/97 17:45:20 97 +0200 +0200") - - -(deftest time.8 - (format nil "~v,v/cl-l10n:format-time/" "en_US" *full-test* 3091103120) - "% Sun Sunday Dec December Sun Dec 14 17:45:20 +0200 1997 19 14 12/14/97 12 1997-12-14 97 1997 Dec 17 05 348 17 5 12 45 - 000000000 17:45:20 17:45 20 17:45:20 7 5 12/14/97 17:45:20 97 +0200 +0200") - -(deftest time.9 - (format nil "~v,v/cl-l10n:format-time/" "sv_SE" *full-test* 3091103120) -"% s?n s?ndag Dec December s?n Dec 14 17:45:20 +0200 1997 19 14 12/14/97 12 1997-12-14 97 1997 dec 17 05 348 17 5 12 45 - 000000000 17:45:20 17:45 20 17:45:20 7 5 12/14/97 17:45:20 97 +0200 +0200") - +(defmacro def-time-directive-test (name directive result) + `(deftest ,name (format nil "~v,vU" "en_ZA" ,directive 3320556360) + ,result)) + +(def-time-directive-test directive.1 "%%" "%") +(def-time-directive-test directive.2 "%a" "Wed") +(def-time-directive-test directive.3 "%A" "Wednesday") +(def-time-directive-test directive.4 "%b" "Mar") +(def-time-directive-test directive.5 "%B" "March") +(def-time-directive-test directive.6 "%c" "Wed 23 Mar 2005 10:46:00 +0200") +(def-time-directive-test directive.7 "%C" "20") +(def-time-directive-test directive.8 "%d" "23") +(def-time-directive-test directive.9 "%D" "03/23/05") +(def-time-directive-test directive.10 "%e" "23") +(def-time-directive-test directive.11 "%F" "2005-03-23") +(def-time-directive-test directive.12 "%g" "05") +(def-time-directive-test directive.13 "%G" "2005") +(def-time-directive-test directive.14 "%h" "Mar") +(def-time-directive-test directive.15 "%H" "10") +(def-time-directive-test directive.16 "%I" "10") +(def-time-directive-test directive.17 "%j" "082") +(def-time-directive-test directive.18 "%k" "10") +(def-time-directive-test directive.19 "%l" "10") +(def-time-directive-test directive.21 "%m" "03") +(def-time-directive-test directive.22 "%M" "46") +(def-time-directive-test directive.23 "%n" " +") +(def-time-directive-test directive.24 "%N" "000000000") +(def-time-directive-test directive.25 "%p" "") +(def-time-directive-test directive.26 "%P" "") +(def-time-directive-test directive.27 "%r" "10:46:00 ") +(def-time-directive-test directive.28 "%R" "10:46") +(def-time-directive-test directive.29 "%s" "1111567560") +(def-time-directive-test directive.30 "%S" "00") +(def-time-directive-test directive.31 "%t" " ") +(def-time-directive-test directive.32 "%T" "10:46:00") +(def-time-directive-test directive.33 "%u" "3") +;(def-time-directive-test directive.34 "%U" "12") +;(def-time-directive-test directive.35 "%V" "12") +(def-time-directive-test directive.36 "%w" "3") +;(def-time-directive-test directive.37 "%W" "12") +(def-time-directive-test directive.38 "%x" "23/03/2005") +(def-time-directive-test directive.39 "%X" "10:46:00") +(def-time-directive-test directive.40 "%y" "05") +(def-time-directive-test directive.41 "%Y" "2005") +(def-time-directive-test directive.42 "%z" "+0200") +(def-time-directive-test directive.43 "%Z" "+0200") + + ;; i18n tests (defvar *my-bundle* (make-instance 'bundle)) Index: cl-l10n/utils.lisp diff -u cl-l10n/utils.lisp:1.5 cl-l10n/utils.lisp:1.6 --- cl-l10n/utils.lisp:1.5 Thu Dec 30 12:56:38 2004 +++ cl-l10n/utils.lisp Wed Mar 23 11:58:16 2005 @@ -48,11 +48,6 @@ (and (consp list) (not (cdr list)))) -(defun mklist (thing) - (if (listp thing) - thing - (list thing))) - (defun last1 (list) (car (last list))) From sross at common-lisp.net Thu Mar 24 14:47:06 2005 From: sross at common-lisp.net (Sean Ross) Date: Thu, 24 Mar 2005 15:47:06 +0100 (CET) Subject: [cl-l10n-cvs] CVS update: cl-l10n/ChangeLog cl-l10n/cl-l10n.asd cl-l10n/load-locale.lisp cl-l10n/printers.lisp Message-ID: <20050324144706.C30E7884E2@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv12231 Modified Files: ChangeLog cl-l10n.asd load-locale.lisp printers.lisp Log Message: Changelog 2005-03-24 Date: Thu Mar 24 15:47:02 2005 Author: sross Index: cl-l10n/ChangeLog diff -u cl-l10n/ChangeLog:1.13 cl-l10n/ChangeLog:1.14 --- cl-l10n/ChangeLog:1.13 Wed Mar 23 11:58:16 2005 +++ cl-l10n/ChangeLog Thu Mar 24 15:47:01 2005 @@ -1,3 +1,9 @@ +2005-03-24 Sean Ross + * cl-l10n.asd, load-locale.lisp: Moved loading of initial locale + to the asdf load-op. + * load-locale.lisp: Bug fix, incorrect order of arguments to + get-category in copy-category. + 2005-03-23 Sean Ross * printers.lisp: Fixed the %w, %e, %x, %X, %d and %j time format directives. * tests.lisp: Added a test for each supported time format directive. Index: cl-l10n/cl-l10n.asd diff -u cl-l10n/cl-l10n.asd:1.10 cl-l10n/cl-l10n.asd:1.11 --- cl-l10n/cl-l10n.asd:1.10 Wed Mar 23 11:58:16 2005 +++ cl-l10n/cl-l10n.asd Thu Mar 24 15:47:01 2005 @@ -11,7 +11,7 @@ :name "CL-L10N" :author "Sean Ross " :maintainer "Sean Ross " - :version "0.2.5" + :version "0.2.6" :description "Portable CL Locale Support" :long-description "Portable CL Package to support localization" :licence "MIT" @@ -26,6 +26,7 @@ :depends-on (:cl-ppcre)) (defmethod perform :after ((o load-op) (c (eql (find-system :cl-l10n)))) + (funcall (find-symbol "LOAD-DEFAULT-LOCALE" "CL-L10N")) (provide 'cl-l10n)) @@ -40,4 +41,4 @@ (defmethod perform ((op test-op) (sys (eql (find-system :cl-l10n-tests)))) (funcall (find-symbol "DO-TESTS" "REGRESSION-TEST"))) -;; EOF \ No newline at end of file +;; EOF Index: cl-l10n/load-locale.lisp diff -u cl-l10n/load-locale.lisp:1.10 cl-l10n/load-locale.lisp:1.11 --- cl-l10n/load-locale.lisp:1.10 Tue Feb 22 15:18:25 2005 +++ cl-l10n/load-locale.lisp Thu Mar 24 15:47:01 2005 @@ -196,7 +196,7 @@ (let ((from (trim (subseq line (position #\Space line)) (cons #\" *whitespace*)))) (handler-case (let* ((locale (locale from))) - (or (get-category cat locale) + (or (get-category locale cat) (locale-error "No category ~A in locale ~A." cat from))) (error (c) (locale-error "Unable to copy Category ~A from ~A. ~A." @@ -318,7 +318,6 @@ (locale (getenv "LC_CTYPE") :errorp nil) (locale "POSIX"))) -(load-default-locale) ;; EOF Index: cl-l10n/printers.lisp diff -u cl-l10n/printers.lisp:1.11 cl-l10n/printers.lisp:1.12 --- cl-l10n/printers.lisp:1.11 Wed Mar 23 11:58:16 2005 +++ cl-l10n/printers.lisp Thu Mar 24 15:47:01 2005 @@ -338,7 +338,7 @@ (define-compiler-macro format (&whole form dest control &rest args) "Compiler macro to remove unnecessary calls to parse-fmt-string." (if (stringp control) - `(cl::format ,dest ,(really-parse-fmt-string control) , at args) + `(cl::format ,dest ,(parse-fmt-string control) , at args) form)) (defmacro formatter (fmt-string) From sross at common-lisp.net Wed Mar 30 11:14:56 2005 From: sross at common-lisp.net (Sean Ross) Date: Wed, 30 Mar 2005 13:14:56 +0200 (CEST) Subject: [cl-l10n-cvs] CVS update: cl-l10n/ChangeLog cl-l10n/cl-l10n.asd cl-l10n/package.lisp cl-l10n/parsers.lisp cl-l10n/printers.lisp Message-ID: <20050330111456.BCDA88866D@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv11724 Modified Files: ChangeLog cl-l10n.asd package.lisp parsers.lisp printers.lisp Log Message: Changelog 2005-03-30 Date: Wed Mar 30 13:14:54 2005 Author: sross Index: cl-l10n/ChangeLog diff -u cl-l10n/ChangeLog:1.14 cl-l10n/ChangeLog:1.15 --- cl-l10n/ChangeLog:1.14 Thu Mar 24 15:47:01 2005 +++ cl-l10n/ChangeLog Wed Mar 30 13:14:53 2005 @@ -1,3 +1,14 @@ +2005-03-30 Sean Ross + * parse-time.lisp: New file borrowed from cmucl with + minor changes to be less hostile towards non english + dates and times. + * package.lisp: Exported parse-time and various pattern + symbols. + +2005-03-29 Sean Ross + * printers.lisp: Fix to %z time format directive, 0 time zone + was printed as -0000, should be +0000 + 2005-03-24 Sean Ross * cl-l10n.asd, load-locale.lisp: Moved loading of initial locale to the asdf load-op. Index: cl-l10n/cl-l10n.asd diff -u cl-l10n/cl-l10n.asd:1.11 cl-l10n/cl-l10n.asd:1.12 --- cl-l10n/cl-l10n.asd:1.11 Thu Mar 24 15:47:01 2005 +++ cl-l10n/cl-l10n.asd Wed Mar 30 13:14:53 2005 @@ -11,7 +11,7 @@ :name "CL-L10N" :author "Sean Ross " :maintainer "Sean Ross " - :version "0.2.6" + :version "0.2.9" :description "Portable CL Locale Support" :long-description "Portable CL Package to support localization" :licence "MIT" @@ -22,6 +22,7 @@ (:file "load-locale" :depends-on ("locale")) (:file "printers" :depends-on ("load-locale")) (:file "parsers" :depends-on ("printers" "parse-number")) + (:file "parse-time" :depends-on ("parsers")) (:file "i18n" :depends-on ("printers"))) :depends-on (:cl-ppcre)) Index: cl-l10n/package.lisp diff -u cl-l10n/package.lisp:1.4 cl-l10n/package.lisp:1.5 --- cl-l10n/package.lisp:1.4 Thu Dec 30 12:56:38 2004 +++ cl-l10n/package.lisp Wed Mar 30 13:14:53 2005 @@ -10,5 +10,8 @@ #:*locale* #:*locale-path* #:*locales* #:format-number #:print-number #:format-money #:print-money #:format-time #:print-time #:add-resources #:bundle - #:add-resource #:gettext #:parse-number #:*float-digits*)) + #:add-resource #:gettext #:parse-number #:*float-digits* + #:parse-time #:month #:day #:year #:hour #:minute #:second + #:date-divider #:time-divider #:weekday #:noon-midn + #:secondp #:am-pm #:zone)) Index: cl-l10n/parsers.lisp diff -u cl-l10n/parsers.lisp:1.2 cl-l10n/parsers.lisp:1.3 --- cl-l10n/parsers.lisp:1.2 Fri Dec 17 11:06:43 2004 +++ cl-l10n/parsers.lisp Wed Mar 30 13:14:53 2005 @@ -9,15 +9,15 @@ (case (length ts) (0 num) (1 (remove (schar ts 0) num)) - (t num)))) + (t num)))) ; FIXME (defun replace-dp (num locale) (let ((dp (locale-decimal-point locale))) (case (length dp) (0 num) (1 (substitute #\. (schar dp 0) num)) - (t num)))) - + (t num)))) ; FIXME ;; money parser -;; EOF \ No newline at end of file + +;; EOF Index: cl-l10n/printers.lisp diff -u cl-l10n/printers.lisp:1.12 cl-l10n/printers.lisp:1.13 --- cl-l10n/printers.lisp:1.12 Thu Mar 24 15:47:01 2005 +++ cl-l10n/printers.lisp Wed Mar 30 13:14:54 2005 @@ -21,7 +21,7 @@ (princ "0" s))))) (defun format-number (stream arg no-dp no-ts - &optional (locale *locale*)) + &optional (locale *locale*)) (let ((locale (locale-des->locale locale)) (float-part (float-part (coerce (abs arg) 'double-float)))) (cl:format stream @@ -35,7 +35,7 @@ (values))) (defun print-number (number &key (stream *standard-output*) - no-ts no-dp (locale *locale*)) + no-ts no-dp (locale *locale*)) (format-number stream number no-dp no-ts locale) number) @@ -84,7 +84,7 @@ (values)) (defun print-money (num &key (stream *standard-output*) use-int-sym no-ts - (locale *locale*)) + (locale *locale*)) (format-money stream num use-int-sym no-ts locale) num) @@ -135,56 +135,56 @@ (mod val 100)) (def-formatter #\a - (let ((day (1+ day))) - (if (> day 6) (decf day 7)) - (princ (nth day (locale-abday locale)) stream))) + (let ((day (1+ day))) + (if (> day 6) (decf day 7)) + (princ (nth day (locale-abday locale)) stream))) (def-formatter #\A - (let ((day (1+ day))) - (if (> day 6) (decf day 7)) - (princ (nth day (locale-day locale)) stream))) + (let ((day (1+ day))) + (if (> day 6) (decf day 7)) + (princ (nth day (locale-day locale)) stream))) (def-formatter #\b - (cl:format stream (cl:formatter "~A") - (nth (1- month) (locale-abmon locale)))) + (cl:format stream (cl:formatter "~A") + (nth (1- month) (locale-abmon locale)))) (def-formatter #\B - (cl:format stream (cl:formatter "~A") - (nth (1- month) (locale-mon locale)))) + (cl:format stream (cl:formatter "~A") + (nth (1- month) (locale-mon locale)))) (def-formatter #\c (print-time-string (locale-d-t-fmt locale) stream ut locale)) (def-formatter #\C - (princ-pad-val (truncate (/ year 100)) stream)) + (princ-pad-val (truncate (/ year 100)) stream)) (def-formatter #\d - (princ-pad-val date stream)) + (princ-pad-val date stream)) (def-formatter #\D - (print-time-string "%m/%d/%y" stream ut locale)) + (print-time-string "%m/%d/%y" stream ut locale)) (def-formatter #\e - (princ-pad-val date stream " ")) + (princ-pad-val date stream " ")) (def-formatter #\F - (print-time-string "%Y-%m-%d" stream ut locale)) + (print-time-string "%Y-%m-%d" stream ut locale)) (def-formatter #\g - (print-time-string "%y" stream ut locale)) + (print-time-string "%y" stream ut locale)) (def-formatter #\G - (print-time-string "%Y" stream ut locale)) + (print-time-string "%Y" stream ut locale)) (def-formatter #\h - (princ (nth (1- month) (locale-abmon locale)) - stream)) + (princ (nth (1- month) (locale-abmon locale)) + stream)) (def-formatter #\H - (princ-pad-val hour stream)) + (princ-pad-val hour stream)) (def-formatter #\I - (princ-pad-val (if (> hour 12) (- hour 12) hour) stream)) + (princ-pad-val (if (> hour 12) (- hour 12) hour) stream)) (defvar *mon-days* '(31 28 31 30 31 30 31 31 30 31 30 31)) @@ -201,85 +201,85 @@ (defun day-of-year (date month year) (let ((total 0)) (loop repeat (1- month) - for x in (if (leap-year-p year) *mon-days-leap* *mon-days*) do - (incf total x)) + for x in (if (leap-year-p year) *mon-days-leap* *mon-days*) do + (incf total x)) (incf total date))) (def-formatter #\j - (princ-pad-val (day-of-year date month year) stream "0" 3)) + (princ-pad-val (day-of-year date month year) stream "0" 3)) (def-formatter #\k - (princ-pad-val hour stream " ")) + (princ-pad-val hour stream " ")) (def-formatter #\l - (princ-pad-val (if (> hour 12) (- hour 12) hour) stream - " ")) + (princ-pad-val (if (> hour 12) (- hour 12) hour) stream + " ")) (def-formatter #\m - (princ-pad-val month stream)) + (princ-pad-val month stream)) (def-formatter #\M - (princ-pad-val min stream)) + (princ-pad-val min stream)) (def-formatter #\n - (princ #\Newline stream)) + (princ #\Newline stream)) (def-formatter #\N - (princ "000000000" stream)) + (princ "000000000" stream)) (defun get-am-pm (hour locale) (funcall (if (< hour 12) #'car #'cadr) (locale-am-pm locale))) (def-formatter #\p - (princ (string-upcase (get-am-pm hour locale)) - stream)) + (princ (string-upcase (get-am-pm hour locale)) + stream)) (def-formatter #\P - (princ (string-downcase (get-am-pm hour locale)) - stream)) + (princ (string-downcase (get-am-pm hour locale)) + stream)) (def-formatter #\r - (print-time-string "%H:%M:%S %p" stream ut locale)) + (print-time-string "%H:%M:%S %p" stream ut locale)) (def-formatter #\R - (print-time-string "%H:%M" stream ut locale)) + (print-time-string "%H:%M" stream ut locale)) (defvar *1970-01-01* (encode-universal-time 0 0 0 01 01 1970 0)) (def-formatter #\s - (princ (- ut *1970-01-01*) stream)) + (princ (- ut *1970-01-01*) stream)) (def-formatter #\S - (princ-pad-val sec stream)) + (princ-pad-val sec stream)) (def-formatter #\t - (princ #\Tab stream)) + (princ #\Tab stream)) (def-formatter #\T - (print-time-string "%H:%M:%S" stream ut locale)) + (print-time-string "%H:%M:%S" stream ut locale)) (def-formatter #\u - (let ((day (1+ day))) - (when (> day 7) (decf day 7)) - (princ day stream))) + (let ((day (1+ day))) + (when (> day 7) (decf day 7)) + (princ day stream))) ;; FIXME (def-formatter #\U - (locale-error "Unsupported time format directive ~S." #\U)) + (locale-error "Unsupported time format directive ~S." #\U)) ;; FIXME (def-formatter #\V - (locale-error "Unsupported time format directive ~S." #\V)) + (locale-error "Unsupported time format directive ~S." #\V)) (def-formatter #\w - (let ((day (1+ day))) - (when (>= day 7) (decf day 7)) - (princ day stream))) + (let ((day (1+ day))) + (when (>= day 7) (decf day 7)) + (princ day stream))) ;; FIXME (def-formatter #\W - (locale-error "Unsupported time format directive ~S." #\W)) + (locale-error "Unsupported time format directive ~S." #\W)) (def-formatter #\x (print-time-string (locale-d-fmt locale) stream ut locale)) @@ -288,25 +288,34 @@ (print-time-string (locale-t-fmt locale) stream ut locale)) (def-formatter #\y - (princ-pad-val (last-2-digits year) stream)) + (princ-pad-val (last-2-digits year) stream)) (def-formatter #\Y - (princ year stream)) + (princ year stream)) -(def-formatter #\z - (let ((d-zone (if daylight-p (1- zone) zone))) - (multiple-value-bind (hr mn) (truncate (abs d-zone)) - (princ (if (minusp d-zone) #\+ #\-) stream) - (cl:format stream (cl:formatter "~2,'0D~2,'0D") - hr (floor (* 60 mn)))))) -;; FIXME should be printing SAST rather than +0200 +; This was all severely broken until I took a look +; at Daniel Barlow's net-telent-date package, +; which is a must read for anyone working with dates +; in CL. +(def-formatter #\z + (let ((d-zone (if daylight-p (1- zone) zone))) + (multiple-value-bind (hr mn) (truncate (abs d-zone)) + (princ (if (<= d-zone 0) #\+ #\-) stream) + (cl:format stream (cl:formatter "~2,'0D~2,'0D") + hr (floor (* 60 mn)))))) + +;; Probably Should be printing SAST rather than +0200 +;; but since all these wonderful codes are not +;; standardized i'm keeping it the same as %z +;; so that we can parse it back. +;; eg. Does IST mean 'Israeli Standard Time','Indian Standard Time' +;; or 'Irish Summer Time' ? (def-formatter #\Z - (print-time-string "%z" stream ut locale)) - + (print-time-string "%z" stream ut locale)) (defun format-time (stream ut show-date show-time &optional (locale *locale*) - fmt) + fmt) (let ((locale (locale-des->locale (or locale *locale*)))) (print-time-string (or fmt (get-time-fmt-string locale show-date show-time)) @@ -317,19 +326,19 @@ (declare (optimize speed) (type simple-string fmt-string)) (let ((values (multiple-value-list (decode-universal-time ut)))) (loop for x across fmt-string - with perc = nil do - (case x - (#\% (if perc - (progn (princ #\% stream) (setf perc nil)) - (setf perc t))) - (t (if perc - (progn (apply (the function (lookup-formatter x)) - stream locale ut values) - (setf perc nil)) - (princ x stream))))))) + with perc = nil do + (case x + (#\% (if perc + (progn (princ #\% stream) (setf perc nil)) + (setf perc t))) + (t (if perc + (progn (apply (the function (lookup-formatter x)) + stream locale ut values) + (setf perc nil)) + (princ x stream))))))) (defun print-time (ut &key show-date show-time (stream *standard-output*) - (locale *locale*) fmt) + (locale *locale*) fmt) (format-time stream ut show-date show-time locale fmt) ut) @@ -367,17 +376,17 @@ (declare (optimize speed) (type string string)) (with-output-to-string (fmt-string) (loop for char across string - with tilde = nil do - (case char - ((#\@ #\v #\, #\:) (princ char fmt-string)) - (#\~ (princ char fmt-string) - (if tilde - (setf tilde nil) - (setf tilde t))) - (t (if tilde - (progn (setf tilde nil) - (princ (get-replacement char) fmt-string)) - (princ char fmt-string))))))) + with tilde = nil do + (case char + ((#\@ #\v #\, #\:) (princ char fmt-string)) + (#\~ (princ char fmt-string) + (if tilde + (setf tilde nil) + (setf tilde t))) + (t (if tilde + (progn (setf tilde nil) + (princ (get-replacement char) fmt-string)) + (princ char fmt-string))))))) (defvar *directive-replacements* '((#\M . "/cl-l10n:format-money/") From sross at common-lisp.net Wed Mar 30 11:23:56 2005 From: sross at common-lisp.net (Sean Ross) Date: Wed, 30 Mar 2005 13:23:56 +0200 (CEST) Subject: [cl-l10n-cvs] CVS update: cl-l10n/parse-time.lisp Message-ID: <20050330112356.E9C758866D@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv12565 Added Files: parse-time.lisp Log Message: Added parse-time.lisp Date: Wed Mar 30 13:23:56 2005 Author: sross From sross at common-lisp.net Thu Mar 31 13:53:47 2005 From: sross at common-lisp.net (Sean Ross) Date: Thu, 31 Mar 2005 15:53:47 +0200 (CEST) Subject: [cl-l10n-cvs] CVS update: cl-l10n/ChangeLog cl-l10n/README cl-l10n/cl-l10n.asd cl-l10n/load-locale.lisp cl-l10n/locale.lisp cl-l10n/package.lisp cl-l10n/parse-number.lisp cl-l10n/parse-time.lisp cl-l10n/printers.lisp cl-l10n/tests.lisp Message-ID: <20050331135347.02764886FE@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n In directory common-lisp.net:/tmp/cvs-serv7026 Modified Files: ChangeLog README cl-l10n.asd load-locale.lisp locale.lisp package.lisp parse-number.lisp parse-time.lisp printers.lisp tests.lisp Log Message: Changelog 2005-03-31 Date: Thu Mar 31 15:53:42 2005 Author: sross Index: cl-l10n/ChangeLog diff -u cl-l10n/ChangeLog:1.15 cl-l10n/ChangeLog:1.16 --- cl-l10n/ChangeLog:1.15 Wed Mar 30 13:14:53 2005 +++ cl-l10n/ChangeLog Thu Mar 31 15:53:42 2005 @@ -1,3 +1,22 @@ +2005-03-31 Sean Ross + Version 0.3 Release + * parse-time.lisp, load-locale.lisp: Create + more comprehensive time parsers for each locale + at locale load time. 02/03/04 now parses correctly. + * tests.lisp: Added tests for the time parser. + * printers.lisp: Added a time-zone argument to format-time + and print-time. + * parse-number.lisp: Changed invalid-number condition to + parser-error condition. + * parse-time.lisp: Changed errors which are signalled during + parsing to be of type parser-error. + * locale.lisp: Changed superclass of locale-error to be error. + * tests.lisp: Changed all time related tests to use + a default time zone since they were crashing when running + in a zone other than +0200 (-2 CL Zone). + * doc/cl-l10n.texi: Made current and added full listing of + locale accessor functions and time format control characters. + 2005-03-30 Sean Ross * parse-time.lisp: New file borrowed from cmucl with minor changes to be less hostile towards non english @@ -23,7 +42,7 @@ * doc/cl-l10n.texi: Cleaned up so that it works with makeinfo. 2005-02-22 Sean Ross - * printers.lisp: Added a formatter compiler macro + * printers.lisp: Added a format compiler macro to remove unnecessary calls to parse-fmt-string. * load-locale.lisp: Added a loader for the locale function which will be called if passed in. Index: cl-l10n/README diff -u cl-l10n/README:1.2 cl-l10n/README:1.3 --- cl-l10n/README:1.2 Thu Dec 30 12:56:38 2004 +++ cl-l10n/README Thu Mar 31 15:53:42 2005 @@ -3,18 +3,22 @@ Homepage: http://www.common-lisp.net/project/cl-l10n/ - 0. About cl-l10n is a localization package for common-lisp. It is meant to be serve the same purpose as Allegro Common Lisp's various locale functions. It currently runs on -CMUCL, SBCL, CLISP, ECL and Lispworks although porting to a new -implementation should be ridiculously trivial. +CMUCL, SBCL, CLISP, ECL, Lispworks and Allegro CL although porting +to a new implementation should be trivial. 1. API -Check docs/cl-l10n.texi +See docs/cl-l10n.texi + +2. Testing +Run (asdf:oos 'asdf:test-op :cl-l10n) to test the package. +If any tests fail please drop me a line at the mailing lists +or at (sross common-lisp.net). Enjoy Sean. Index: cl-l10n/cl-l10n.asd diff -u cl-l10n/cl-l10n.asd:1.12 cl-l10n/cl-l10n.asd:1.13 --- cl-l10n/cl-l10n.asd:1.12 Wed Mar 30 13:14:53 2005 +++ cl-l10n/cl-l10n.asd Thu Mar 31 15:53:42 2005 @@ -11,7 +11,7 @@ :name "CL-L10N" :author "Sean Ross " :maintainer "Sean Ross " - :version "0.2.9" + :version "0.3" :description "Portable CL Locale Support" :long-description "Portable CL Package to support localization" :licence "MIT" @@ -22,7 +22,7 @@ (:file "load-locale" :depends-on ("locale")) (:file "printers" :depends-on ("load-locale")) (:file "parsers" :depends-on ("printers" "parse-number")) - (:file "parse-time" :depends-on ("parsers")) + (:file "parse-time" :depends-on ("load-locale")) (:file "i18n" :depends-on ("printers"))) :depends-on (:cl-ppcre)) Index: cl-l10n/load-locale.lisp diff -u cl-l10n/load-locale.lisp:1.11 cl-l10n/load-locale.lisp:1.12 --- cl-l10n/load-locale.lisp:1.11 Thu Mar 24 15:47:01 2005 +++ cl-l10n/load-locale.lisp Thu Mar 31 15:53:42 2005 @@ -60,6 +60,7 @@ escape comment)) (setf (get-category locale (category-name it)) it))))) (add-printers locale) + (add-parsers locale) locale))) (defun load-all-locales (&optional (path *locale-path*)) @@ -140,6 +141,53 @@ (create-money-fmt-string locale nil t)) (printers locale)))) +(defun day-element-p (x) + (member x '(#\d #\e))) + +(defun month-element-p (x) + (char= x #\m)) + +(defun year-element-p (x) + (member x '(#\y #\Y))) + +(defun element-type (char) + (cond ((day-element-p char) 'day) + ((month-element-p char) 'month) + ((year-element-p char) 'year))) + +(defvar date-dividers '(#\\ #\/ #\-)) + +;; FIXME +;; this effort definitely doesn't cover +;; every single case but it will do for now. +(defun locale-date-month-order (locale) + (let ((fmt (locale-d-fmt locale))) + (cond ((string= fmt "%D") '(month day year)) + ((string= fmt "%F") '(year month day)) + (t (compute-order fmt))))) + +(defun compute-order (fmt) + (let ((res nil)) + (loop for char across fmt + with perc = nil do + (cond ((char= char #\%) (setf perc (not perc))) + ((member char date-dividers) nil) + (perc (let ((val (element-type char))) + (when val (push val res)) + (setf perc nil))))) + (nreverse res))) + + +(defun add-parsers (locale) + (destructuring-bind (first second third) + (locale-date-month-order locale) + (setf (parsers locale) + (list `((noon-midn) (weekday) ,first (date-divider) ,second (date-divider) ,third (noon-midn)) + `((weekday) ,first (date-divider) ,second (date-divider) ,third hour (time-divider) minute + (time-divider) (secondp) (am-pm) (date-divider) (zone)) + `(hour (time-divider) minute (time-divider) (secondp) (am-pm) (weekday) ,first (date-divider) + (secondp) (date-divider) ,third (date-divider) (zone)))))) + (defvar *category-loaders* '(("LC_IDENTIFICATION" . load-identification) ("LC_MONETARY" . load-category) @@ -308,7 +356,7 @@ (notany #'(lambda (x) (search x line :test #'string=)) *ignore-categories*)) - (return-from next-header line)))) + (return-from next-header (trim line))))) (defun load-default-locale () (setf *locale* (get-default-locale))) Index: cl-l10n/locale.lisp diff -u cl-l10n/locale.lisp:1.8 cl-l10n/locale.lisp:1.9 --- cl-l10n/locale.lisp:1.8 Tue Feb 22 15:18:25 2005 +++ cl-l10n/locale.lisp Thu Mar 31 15:53:42 2005 @@ -4,8 +4,8 @@ ;; TODO ;; What to do with LC_CTYPE, LC_COLLATE ;; Test on windows. -;; Parsers (money and time) -;; locale aliases +;; Parsers (money) +;; locale aliases? ;; Optimizing print-time ;; Thread safety @@ -24,7 +24,7 @@ (defun locale-report (obj stream) (cl:format stream "~A" (mesg obj))) -(define-condition locale-error () +(define-condition locale-error (error) ((mesg :accessor mesg :initarg :mesg :initform "Unknown.")) (:report locale-report)) @@ -37,6 +37,7 @@ :initform (required-arg :name)) (title :accessor title :initarg :title :initform nil) (printers :accessor printers :initarg :printers :initform nil) + (parsers :accessor parsers :initarg :parsers :initform nil) (source :accessor source :initarg :source :initform nil) (language :accessor language :initarg :language :initform nil) (territory :accessor territory :initarg :territory :initform nil) Index: cl-l10n/package.lisp diff -u cl-l10n/package.lisp:1.5 cl-l10n/package.lisp:1.6 --- cl-l10n/package.lisp:1.5 Wed Mar 30 13:14:53 2005 +++ cl-l10n/package.lisp Thu Mar 31 15:53:42 2005 @@ -13,5 +13,5 @@ #:add-resource #:gettext #:parse-number #:*float-digits* #:parse-time #:month #:day #:year #:hour #:minute #:second #:date-divider #:time-divider #:weekday #:noon-midn - #:secondp #:am-pm #:zone)) + #:secondp #:am-pm #:zone #:parser-error)) Index: cl-l10n/parse-number.lisp diff -u cl-l10n/parse-number.lisp:1.3 cl-l10n/parse-number.lisp:1.4 --- cl-l10n/parse-number.lisp:1.3 Thu Dec 30 12:56:38 2004 +++ cl-l10n/parse-number.lisp Thu Mar 31 15:53:42 2005 @@ -32,7 +32,7 @@ (in-package #:cl-l10n) -(define-condition invalid-number () +(define-condition parser-error (error) ((value :reader value :initarg :value :initform nil) @@ -40,7 +40,7 @@ :initarg :reason :initform "Not specified")) (:report (lambda (c s) - (cl:format s "Invalid number: ~S [Reason: ~A]" + (cl:format s "Unable to parse: ~S [Reason: ~A]" (value c) (reason c))))) (declaim (inline parse-integer-and-places)) @@ -106,7 +106,7 @@ (defun %parse-number (string &key (start 0) (end nil) (radix 10)) "Given a string, and start, end, and radix parameters, produce a number according to the syntax definitions in the Common Lisp Hyperspec." (flet ((invalid-number (reason) - (error 'invalid-number + (error 'parser-error :value (subseq string start end) :reason reason))) (let ((end (or end (length string)))) @@ -179,7 +179,7 @@ :end end :key #'char-downcase))) (unless r-pos - (error 'invalid-number + (error 'parser-error :value (subseq string start end) :reason "Missing R in #radixR")) (parse-real-number string @@ -198,7 +198,7 @@ (let ((end (or end (length string))) (first-char (char string start))) (flet ((invalid-number (reason) - (error 'invalid-number + (error 'parser-error :value (subseq string start end) :reason reason)) (base-for-exponent-marker (char) Index: cl-l10n/parse-time.lisp diff -u cl-l10n/parse-time.lisp:1.1 cl-l10n/parse-time.lisp:1.2 --- cl-l10n/parse-time.lisp:1.1 Wed Mar 30 13:23:56 2005 +++ cl-l10n/parse-time.lisp Thu Mar 31 15:53:42 2005 @@ -13,14 +13,13 @@ ;;; ********************************************************************** ;; This has been borrowed and slightly modified to be more friendly -;; towards non english time strings and differing locales. +;; towards non english time strings and locales. ;; Sean Ross 29 March 2005. (in-package :cl-l10n) (defvar whitespace-chars '(#\space #\tab #\newline #\, #\' #\`)) (defvar time-dividers '(#\: #\.)) -(defvar date-dividers '(#\\ #\/ #\-)) (defvar *error-on-mismatch* nil "If t, an error will be signalled if parse-time is unable @@ -69,7 +68,12 @@ ;;; year, time-divider, date-divider, am-pm, zone, izone, weekday, ;;; noon-midn, and any special symbol. -; TODO (add more linux like dates. eg 3 days ago) +#| + + + +|# + (defparameter *default-date-time-patterns* '( @@ -88,13 +92,9 @@ ((noon-midn) month (date-divider) year) ((noon-midn) year (date-divider) month) - ;; Time formats. - (hour (time-divider) (minute) (time-divider) (secondp) (am-pm) - (date-divider) (zone)) - (noon-midn) - (hour (noon-midn)) - ;; Time/date combined formats. + ;; Time/date combined formats. + ((weekday) month (date-divider) day (date-divider) year hour (time-divider) (minute) (time-divider) (secondp) (am-pm) (date-divider) (zone)) @@ -131,6 +131,13 @@ (hour (time-divider) (minute) (time-divider) (secondp) (am-pm) (date-divider) (zone) year (date-divider) month) + + ;; Time formats. + (hour (time-divider) (minute) (time-divider) (secondp) (am-pm) + (date-divider) (zone)) + (noon-midn) + (hour (noon-midn)) + ;; Weird, non-standard formats. (weekday month day hour (time-divider) minute (time-divider) secondp (am-pm) @@ -402,8 +409,9 @@ (let ((test-value (special-string-p substring))) (if test-value (cons 'special test-value))) (if *error-on-mismatch* - (error "\"~A\" is not a recognized word or abbreviation." - substring) + (error 'parser-error + :value substring + :reason "Not a recognized word or abbreviation.") (return-from match-substring nil))))) ;;; Decompose-string takes the time/date string and decomposes it into a @@ -473,11 +481,9 @@ (t ;; Unrecognized character - barf voraciously. (if *error-on-mismatch* - (error - 'simple-error - :format-control "Can't parse time/date string.~%>>> ~A~ - ~%~VT^-- Bogus character encountered here." - :format-arguments (list string (+ string-index 4))) + (error 'parser-error + :value string + :reason "Can't parse time/date string. Bogus character encountered.") (return-from decompose-string nil))))))) ;;; Match-pattern-element tries to match a pattern element with a datum @@ -533,7 +539,8 @@ (setf (decoded-time-hour parsed-values) 12)) ((eq form-value 'midn) (setf (decoded-time-hour parsed-values) 0)) - (t (error "Unrecognized symbol: ~A" form-value))) + (t (error 'parser-error :value form-value + :reason "Unrecognized symbol."))) (setf (decoded-time-minute parsed-values) 0) (setf (decoded-time-second parsed-values) 0)) @@ -548,12 +555,12 @@ (setf (decoded-time-hour parsed-values) 0)) ((not (<= 0 hour 12)) (if *error-on-mismatch* - (error "~D is not an AM hour, dummy." hour))))) + (error 'parser-error :value hour :reason "Not an AM hour, dummy."))))) ((eq form-value 'pm) (if (<= 0 hour 11) (setf (decoded-time-hour parsed-values) (mod (+ hour 12) 24)))) - (t (error "~A isn't AM/PM - this shouldn't happen." + (t (error 'parser-error :value form-value :reason "Not an AM/PM - this shouldn't happen." form-value))))) ;;; Internet numerical time zone, e.g. RFC1123, in hours and minutes. @@ -582,47 +589,8 @@ (am-pm (deal-with-am-pm form-value parsed-values)) (noon-midn (deal-with-noon-midn form-value parsed-values)) (special (funcall form-value parsed-values)) - (t (error "Unrecognized symbol in form list: ~A." form-type)))))) - -(defun day-element-p (x) - (member x '(#\d #\e))) - -(defun month-element-p (x) - (char= x #\m)) + (t (error 'parser-error :value form-type :reason "Unrecognized symbol in form list.")))))) -(defun year-element-p (x) - (member x '(#\y #\Y))) - -(defun element-type (char) - (cond ((day-element-p char) 'day) - ((month-element-p char) 'month) - ((year-element-p char) 'year))) - -;; FIXME -;; this effort definitely doesn't cover -;; every single case but it will do for now. -(defun locale-date-month-order () - (let ((fmt (locale-d-fmt))) - (cond ((string= fmt "%D") '(month day year)) - ((string= fmt "%F") '(year month day)) - (t (compute-order fmt))))) - -(defun compute-order (fmt) - (let ((res nil)) - (loop for char across fmt - with perc = nil do - (cond ((char= char #\%) (setf perc (not perc))) - ((member char date-dividers) nil) - (perc (let ((val (element-type char))) - (when val (push val res)) - (setf perc nil))))) - (nreverse res))) - -(defun locale-date-pattern () - (let ((order (locale-date-month-order))) - (when order - (loop for x in order - append (list x '(date-divider)))))) (defun default-patterns-p (patterns) (eq patterns *default-date-time-patterns*)) @@ -632,11 +600,12 @@ ;; patterns have not been explicitly specified so we try ;; to match against locale a specific date pattern first. ;; eg. 03/04/2005 is 3rd April in UK but 4 March in US. - (let ((res (match-pattern (locale-date-pattern) - string-parts - parts-length))) - (when res - (return-from get-matching-pattern res)))) + (dolist (pattern (parsers *locale*)) + (let ((res (match-pattern pattern + string-parts + parts-length))) + (when res + (return-from get-matching-pattern res))))) (dolist (pattern patterns) (let ((match-result (match-pattern pattern string-parts parts-length))) @@ -652,8 +621,8 @@ (default-month nil) (default-year nil) (default-zone nil) (default-weekday nil) (locale *locale*)) - "Tries very hard to make sense out of the argument time-string and - returns a single integer representing the universal time if + "Tries very hard to make sense out of the argument time-string using + locale and returns a single integer representing the universal time if successful. If not, it returns nil. If the :error-on-mismatch keyword is true, parse-time will signal an error instead of returning nil. Default values for each part of the time/date @@ -674,7 +643,7 @@ (set-time-values string-form parsed-values) (convert-to-unitime parsed-values)) (if *error-on-mismatch* - (error "\"~A\" is not a recognized time/date format." time-string) + (error 'parser-error :value time-string :reason "Not a recognized time/date format.") nil)))) Index: cl-l10n/printers.lisp diff -u cl-l10n/printers.lisp:1.13 cl-l10n/printers.lisp:1.14 --- cl-l10n/printers.lisp:1.13 Wed Mar 30 13:14:54 2005 +++ cl-l10n/printers.lisp Thu Mar 31 15:53:42 2005 @@ -314,9 +314,11 @@ (def-formatter #\Z (print-time-string "%z" stream ut locale)) -(defun format-time (stream ut show-date show-time &optional (locale *locale*) - fmt) - (let ((locale (locale-des->locale (or locale *locale*)))) +(defvar *time-zone* (nth-value 8 (get-decoded-time))) + +(defun format-time (stream ut show-date show-time &optional (locale *locale*) fmt time-zone) + (let ((locale (locale-des->locale (or locale *locale*))) + (*time-zone* (or time-zone *time-zone*))) (print-time-string (or fmt (get-time-fmt-string locale show-date show-time)) stream ut locale)) @@ -324,7 +326,7 @@ (defun print-time-string (fmt-string stream ut locale) (declare (optimize speed) (type simple-string fmt-string)) - (let ((values (multiple-value-list (decode-universal-time ut)))) + (let ((values (multiple-value-list (decode-universal-time ut *time-zone*)))) (loop for x across fmt-string with perc = nil do (case x @@ -338,8 +340,8 @@ (princ x stream))))))) (defun print-time (ut &key show-date show-time (stream *standard-output*) - (locale *locale*) fmt) - (format-time stream ut show-date show-time locale fmt) + (locale *locale*) fmt time-zone) + (format-time stream ut show-date show-time locale fmt time-zone) ut) Index: cl-l10n/tests.lisp diff -u cl-l10n/tests.lisp:1.6 cl-l10n/tests.lisp:1.7 --- cl-l10n/tests.lisp:1.6 Wed Mar 23 11:58:16 2005 +++ cl-l10n/tests.lisp Thu Mar 31 15:53:42 2005 @@ -8,95 +8,95 @@ (rem-all-tests) (deftest load-locs - (progn (locale "en_ZA") (locale "sv_SE") (locale "en_GB") + (progn (locale "en_ZA") (locale "sv_SE") (locale "en_GB") (locale "en_US") (locale "af_ZA") t) - t) + t) + ;; Format number tests (deftest number.1 - (format nil "~v:/cl-l10n:format-number/" "en_ZA" 1000) - "1,000") + (format nil "~v:/cl-l10n:format-number/" "en_ZA" 1000) + "1,000") (deftest number.2 - (format nil "~v:@/cl-l10n:format-number/" "en_ZA" 1000) - "1000") + (format nil "~v:@/cl-l10n:format-number/" "en_ZA" 1000) + "1000") (deftest number.3 - (format nil "~v/cl-l10n:format-number/" "en_ZA" 1000) - "1,000.00") + (format nil "~v/cl-l10n:format-number/" "en_ZA" 1000) + "1,000.00") (deftest number.4 - (format nil "~v/cl-l10n:format-number/" "sv_SE" 1000) - "1 000,00") + (format nil "~v/cl-l10n:format-number/" "sv_SE" 1000) + "1 000,00") (deftest number.5 - (format nil "~v:/cl-l10n:format-number/" "sv_SE" 1000) - "1 000") + (format nil "~v:/cl-l10n:format-number/" "sv_SE" 1000) + "1 000") (deftest number.6 - (format nil "~v:/cl-l10n:format-number/" "sv_SE" 1/2) - "0,50") + (format nil "~v:/cl-l10n:format-number/" "sv_SE" 1/2) + "0,50") (deftest number.7 - (format nil "~v:/cl-l10n:format-number/" "en_GB" 100.12312d0) - "100.12312") + (format nil "~v:/cl-l10n:format-number/" "en_GB" 100.12312d0) + "100.12312") ;; Money tests (deftest money.1 - (format nil "~v:/cl-l10n:format-money/" "en_ZA" 1000) - "ZAR 1,000.00") + (format nil "~v:/cl-l10n:format-money/" "en_ZA" 1000) + "ZAR 1,000.00") (deftest money.2 - (format nil "~v@/cl-l10n:format-money/" "en_ZA" 1000) - "R1000.00") + (format nil "~v@/cl-l10n:format-money/" "en_ZA" 1000) + "R1000.00") (deftest money.3 - (format nil "~v:@/cl-l10n:format-money/" "en_ZA" 1000) - "ZAR 1000.00") + (format nil "~v:@/cl-l10n:format-money/" "en_ZA" 1000) + "ZAR 1000.00") (deftest money.4 - (format nil "~v:/cl-l10n:format-money/" "sv_SE" 1000) - "1 000,00 SEK") + (format nil "~v:/cl-l10n:format-money/" "sv_SE" 1000) + "1 000,00 SEK") (deftest money.5 - (format nil "~v@/cl-l10n:format-money/" "sv_SE" 1000) - "1000,00 kr") + (format nil "~v@/cl-l10n:format-money/" "sv_SE" 1000) + "1000,00 kr") (deftest money.6 - (format nil "~v:@/cl-l10n:format-money/" "sv_SE" 1000) - "1000,00 SEK") - + (format nil "~v:@/cl-l10n:format-money/" "sv_SE" 1000) + "1000,00 SEK") ;; Time tests (deftest time.1 - (format nil "~v:@/cl-l10n:format-time/" "en_ZA" 3091103120) - "Sun 14 Dec 1997 17:45:20 +0200") + (format nil "~v,,v:@/cl-l10n:format-time/" "en_ZA" 0 3091103120) + "Sun 14 Dec 1997 15:45:20 +0000") (deftest time.2 - (format nil "~v:@/cl-l10n:format-time/" "sv_SE" 3091103120) - "s?n 14 dec 1997 17.45.20") + (format nil "~v,,v:@/cl-l10n:format-time/" "sv_SE" 0 3091103120) + "s?n 14 dec 1997 15.45.20") (deftest time.3 - (format nil "~v/cl-l10n:format-time/" "en_US" 3091103120) - "05:45:20 ") + (format nil "~v,,v/cl-l10n:format-time/" "en_US" 0 3091103120) + "03:45:20 ") (deftest time.4 - (format nil "~v:/cl-l10n:format-time/" "en_US" 3091103120) - "12/14/1997") + (format nil "~v:/cl-l10n:format-time/" "en_US" 3091103120) + "12/14/1997") (deftest time.5 - (format nil "~v@/cl-l10n:format-time/" "en_US" 3091103120) - "17:45:20 ") + (format nil "~v,,v@/cl-l10n:format-time/" "en_US" 0 3091103120) + "15:45:20 ") (deftest time.6 - (format nil "~v@/cl-l10n:format-time/" "sv_SE" 3091103120) - "17.45.20") + (format nil "~v,,v@/cl-l10n:format-time/" "sv_SE" 0 3091103120) + "15.45.20") (defmacro def-time-directive-test (name directive result) - `(deftest ,name (format nil "~v,vU" "en_ZA" ,directive 3320556360) + `(deftest ,name (format nil "~v,v,vU" "en_ZA" ,directive 0 3320556360) ,result)) (def-time-directive-test directive.1 "%%" "%") @@ -104,7 +104,7 @@ (def-time-directive-test directive.3 "%A" "Wednesday") (def-time-directive-test directive.4 "%b" "Mar") (def-time-directive-test directive.5 "%B" "March") -(def-time-directive-test directive.6 "%c" "Wed 23 Mar 2005 10:46:00 +0200") +(def-time-directive-test directive.6 "%c" "Wed 23 Mar 2005 08:46:00 +0000") (def-time-directive-test directive.7 "%C" "20") (def-time-directive-test directive.8 "%d" "23") (def-time-directive-test directive.9 "%D" "03/23/05") @@ -113,11 +113,11 @@ (def-time-directive-test directive.12 "%g" "05") (def-time-directive-test directive.13 "%G" "2005") (def-time-directive-test directive.14 "%h" "Mar") -(def-time-directive-test directive.15 "%H" "10") -(def-time-directive-test directive.16 "%I" "10") +(def-time-directive-test directive.15 "%H" "08") +(def-time-directive-test directive.16 "%I" "08") (def-time-directive-test directive.17 "%j" "082") -(def-time-directive-test directive.18 "%k" "10") -(def-time-directive-test directive.19 "%l" "10") +(def-time-directive-test directive.18 "%k" " 8") +(def-time-directive-test directive.19 "%l" " 8") (def-time-directive-test directive.21 "%m" "03") (def-time-directive-test directive.22 "%M" "46") (def-time-directive-test directive.23 "%n" " @@ -125,23 +125,23 @@ (def-time-directive-test directive.24 "%N" "000000000") (def-time-directive-test directive.25 "%p" "") (def-time-directive-test directive.26 "%P" "") -(def-time-directive-test directive.27 "%r" "10:46:00 ") -(def-time-directive-test directive.28 "%R" "10:46") +(def-time-directive-test directive.27 "%r" "08:46:00 ") +(def-time-directive-test directive.28 "%R" "08:46") (def-time-directive-test directive.29 "%s" "1111567560") (def-time-directive-test directive.30 "%S" "00") (def-time-directive-test directive.31 "%t" " ") -(def-time-directive-test directive.32 "%T" "10:46:00") +(def-time-directive-test directive.32 "%T" "08:46:00") (def-time-directive-test directive.33 "%u" "3") ;(def-time-directive-test directive.34 "%U" "12") ;(def-time-directive-test directive.35 "%V" "12") (def-time-directive-test directive.36 "%w" "3") ;(def-time-directive-test directive.37 "%W" "12") (def-time-directive-test directive.38 "%x" "23/03/2005") -(def-time-directive-test directive.39 "%X" "10:46:00") +(def-time-directive-test directive.39 "%X" "08:46:00") (def-time-directive-test directive.40 "%y" "05") (def-time-directive-test directive.41 "%Y" "2005") -(def-time-directive-test directive.42 "%z" "+0200") -(def-time-directive-test directive.43 "%Z" "+0200") +(def-time-directive-test directive.42 "%z" "+0000") +(def-time-directive-test directive.43 "%Z" "+0000") @@ -155,48 +155,111 @@ "howareyou" "How are you") (deftest i18n.1 - (gettext "howareyou" *my-bundle* "en_ZA") - "How are you") + (gettext "howareyou" *my-bundle* "en_ZA") + "How are you") (deftest i18n.2 - (gettext "howareyou" *my-bundle* "af_ZA") - "Hoe lyk it") + (gettext "howareyou" *my-bundle* "af_ZA") + "Hoe lyk it") ;; format (deftest format.1 - (format nil "~v:@U" "en_ZA" 3091103120) - "Sun 14 Dec 1997 17:45:20 +0200") + (format nil "~v,,v:@U" "en_ZA" -2 3091103120) + "Sun 14 Dec 1997 17:45:20 +0200") (deftest format.2 - (format nil "~v:n" "en_ZA" 1000) - "1,000") + (format nil "~v:n" "en_ZA" 1000) + "1,000") (deftest format.3 - (format nil "~v:@m" "sv_SE" 1000) - "1000,00 SEK") + (format nil "~v:@m" "sv_SE" 1000) + "1000,00 SEK") ;; formatter (deftest formatter.1 - (format nil (formatter "~v:@U") "en_ZA" 3091103120) - "Sun 14 Dec 1997 17:45:20 +0200") + (format nil (formatter "~v,,v:@U") "en_ZA" -2 3091103120) + "Sun 14 Dec 1997 17:45:20 +0200") (deftest formatter.2 - (format nil (formatter "~v:n") "en_ZA" 1000) - "1,000") + (format nil (formatter "~v:n") "en_ZA" 1000) + "1,000") (deftest formatter.3 - (format nil (formatter "~v:@m") "sv_SE" 1000) - "1000,00 SEK") + (format nil (formatter "~v:@m") "sv_SE" 1000) + "1000,00 SEK") ;; parse-number (deftest parse-number.1 - (parse-number (format nil "~vn" "af_ZA" -1001231.5) "af_ZA") - -1001231.5) + (parse-number (format nil "~vn" "af_ZA" -1001231.5) "af_ZA") + -1001231.5) (deftest parse-number.2 - (parse-number (format nil "~v@:n" "en_ZA" -1001231.5) "en_ZA") - -1001231.5) + (parse-number (format nil "~v@:n" "en_ZA" -1001231.5) "en_ZA") + -1001231.5) + +(deftest parse-number.3 + (parse-number (format nil "~v@:n" "sv_SE" -1001231.5) "sv_SE") + -1001231.5) + + +;; parse-time +(deftest parse-time.1 + (let ((*locale* "en_ZA") + (time (get-universal-time))) + (= time (parse-time (format nil "~:U~:* ~@U" time)))) + t) + +(deftest parse-time.2 + (let ((*locale* "sv_SE") + (time (get-universal-time))) + (= time (parse-time (format nil "~:U~:* ~@U" time)))) + t) + +(deftest parse-time.3 + (let ((*locale* "en_US") + (time (get-universal-time))) + (= time (parse-time (format nil "~:U~:* ~@U" time)))) + t) + +(deftest parse-time.4 + (let ((*locale* "en_GB") + (time (get-universal-time))) + (= time (parse-time (format nil "~:U~:* ~@U" time)))) + t) + +(deftest parse-time.5 + (parse-time "05/04/03" :default-zone -2 :locale "en_ZA") + 3258482400) + +(deftest parse-time.6 + (parse-time "05/04/03" :default-zone -2 :locale "en_US") + 3260988000) + +(deftest parse-time.7 + (parse-time "05/04/03" :default-zone -2 :locale "en_ZA") + 3258482400) + +(deftest parse-time.8 + (let ((*locale* "en_ZA") + (time (get-universal-time))) + (= time (parse-time (format nil "~:@U" time)))) + t) + +(deftest parse-time.9 + (let ((*locale* "en_US") + (time (get-universal-time))) + (= time (parse-time (format nil "~:@U" time)))) + t) + +(deftest parse-time.10 + (let ((*locale* "sv_SE") + (time (get-universal-time))) + (= time (parse-time (format nil "~:@U" time)))) + t) + + + ;; EOF From sross at common-lisp.net Thu Mar 31 13:53:49 2005 From: sross at common-lisp.net (Sean Ross) Date: Thu, 31 Mar 2005 15:53:49 +0200 (CEST) Subject: [cl-l10n-cvs] CVS update: cl-l10n/doc/cl-l10n.texi Message-ID: <20050331135349.40C7F88700@common-lisp.net> Update of /project/cl-l10n/cvsroot/cl-l10n/doc In directory common-lisp.net:/tmp/cvs-serv7026/doc Modified Files: cl-l10n.texi Log Message: Changelog 2005-03-31 Date: Thu Mar 31 15:53:47 2005 Author: sross Index: cl-l10n/doc/cl-l10n.texi diff -u cl-l10n/doc/cl-l10n.texi:1.6 cl-l10n/doc/cl-l10n.texi:1.7 --- cl-l10n/doc/cl-l10n.texi:1.6 Thu Mar 17 12:40:39 2005 +++ cl-l10n/doc/cl-l10n.texi Thu Mar 31 15:53:47 2005 @@ -90,6 +90,7 @@ @item CLISP @item Lispworks @item ECL + at item Allegro CL @end itemize @@ -239,13 +240,13 @@ @end deffn @anchor{Function print-time} - at deffn {Function} print-time ut &key show-date show-time (stream *standard-output) (locale *locale) fmt + at deffn {Function} print-time ut &key show-date show-time (stream *standard-output) (locale *locale) fmt time-zone Prints the @code{universal-time} @emph{ut} as a locale specific time to @emph{stream}. -Equivalent to @code{(format-time stream ut show-date show-time locale fmt)}. +Equivalent to @code{(format-time stream ut show-date show-time locale fmt time-zone)}. @end deffn @anchor{Function format-time} - at deffn {function} format-time stream ut show-date show-time &optional (locale *locale*) fmt + at deffn {function} format-time stream ut show-date show-time &optional (locale *locale*) fmt time-zone Prints the @code{universal-time} @emph{ut} as a locale specific time to @emph{stream}. The format of the time printed is controlled by @emph{show-time} and @emph{show-date}. @@ -262,10 +263,10 @@ @end table If @emph{fmt} is not nil then @emph{show-date} and @emph{show-time} are ignored -and @emph{fmt} is used as the format control string. For details of format -directive look at 'man 1 date' although some directives are not supported, namely %U, %V and %W. +and @emph{fmt} is used as the format control string. See the Notes Section for +the defined control characters which can be used. -Examples (assuming *locale* is ``en_ZA'') +Examples (assuming *locale* is ``en_ZA'' and a CL -2 Time Zone) @verbatim (format t "~:/cl-l10n:format-time/" 3192624000) prints `03/03/01' @@ -281,6 +282,11 @@ (format t "~,v/cl-l10n:format-time/" "%A" 3192624000) prints `Saturday' + +; The Time Zone can be overriden with an extra v argument +(format t "~v,v,v/cl-l10n:format-time/" "en_ZA" "%A" -8 3192624000) + print `Sunday' + @end verbatim @end deffn @@ -297,7 +303,7 @@ drop in replacements for the ~/cl-l10n:format-?/ calls. @verbatim -;; These examples assume an en_ZA locale +;; These examples assume an en_ZA locale and a CL -2 Time Zone (in-package :cl-user) (shadowing-import 'cl-l10n::format) @@ -330,6 +336,30 @@ Parses the string @emph{num-string} into a number using @emph{locale}. @end deffn + at anchor{Function parse-time} + at deffn {Function} parse-time time-string &key (start 0) (end (length time-string)) (error-on-mismatch nil) (patterns *default-date-time-patterns*) (default-seconds nil) (default-minutes nil) (default-hours nil) (default-day nil) (default-month nil) (default-year nil) (default-zone nil) (default-weekday nil) (locale *locale*) + +Tries very hard to make sense out of the argument time-string using +locale and returns a single integer representing the universal time if +successful. If not, it returns nil. If the :error-on-mismatch +keyword is true, parse-time will signal an error instead of +returning nil. Default values for each part of the time/date +can be specified by the appropriate :default- keyword. These +keywords can be given a numeric value or the keyword :current +to set them to the current value. The default-default values +are 00:00:00 on the current date, current time-zone. + +Example, what date does the string ``02/03/05'' specify? +parse-time will use the current locale or the locale-designator +passed to it to determine the correct format for dates. +In America (en_US) this date is the 3rd of February 2005, with an South African English (en_ZA) +locale this date is the 2nd of March 2005 and with a Swedish locale (sv_SE) it's the 5th of March 2002. + +Note. This is not my work but was done by Jim Healy and is a part of the CMUCL project, + which has been modified to handle differt locales. + + at end deffn + @section Classes @anchor{Class locale} @@ -348,12 +378,20 @@ @section Conditions @anchor{Condition locale-error} @deftp {Condition} locale-error -Class Precedence: @code{condition} +Class Precedence: @code{error} Root CL-L10N condition which will be signalled when an exceptional situation occurs. @end deftp + at anchor{Condition parser-error} + at deftp {Condition} parser-error +Class Precedence: @code{error} +Error which is signalled when an error occurs when parsing numbers +or time strings. + at end deftp + + @node I18N @chapter I18N @@ -482,17 +520,108 @@ is loaded. If these two have failed then the POSIX locale is loaded as the default. + at section Time Format Control Characters +The following is a list of each legal control character in a time +format string followed by a description of what is does. + at itemize + at item %% A percentage sign. + at item %a locale's abbreviated weekday name (Sun..Sat) + at item %A locale's full weekday name, variable length (Sunday..Saturday) + at item %b locale's abbreviated month name (Jan..Dec) + at item %B locale's full month name, variable length (January..December) + at item %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) + at item %C century [00-99] + at item %d day of month (01..31) + at item %D date (mm/dd/yy) + at item %e day of month, blank padded ( 1..31) + at item %F same as %Y-%m-%d + at item %g the 2-digit year corresponding to the %V week number + at item %G the 4-digit year corresponding to the %V week number + at item %h same as %b + at item %H hour (00..23) + at item %I hour (01..12) + at item %j day of year (001..366) + at item %k hour ( 0..23) + at item %l hour ( 1..12) + at item %m month (01..12) + at item %M minute (00..59) + at item %n a newline + at item %N nanoseconds (Always 000000000) + at item %p locale's upper case AM or PM indicator (blank in many locales) + at item %P locale's lower case am or pm indicator (blank in many locales) + at item %r time, 12-hour (hh:mm:ss [AP]M) + at item %R time, 24-hour (hh:mm) + at item %s seconds since `00:00:00 1970-01-01 UTC' + at item %S second (00..60) + at item %t a horizontal tab + at item %T time, 24-hour (hh:mm:ss) + at item %u day of week (1..7); 1 represents Monday + at item %U week number of year with Sunday as first day of week (00..53) + at item %V week number of year with Monday as first day of week (01..53) + at item %w day of week (0..6); 0 represents Sunday + at item %W week number of year with Monday as first day of week (00..53) + at item %x locale's date representation (locale-d-fmt) + at item %X locale's time representation (locale-t-fmt) + at item %y last two digits of year (00..99) + at item %Y year (1900...) + at item %z RFC-2822 style numeric timezone (-0500) + at item %Z RFC-2822 style numeric timezone (-0500) + at end itemize + @section Accessors to Locale Values. There are a number of accessor functions to the various locale attributes defined. The functions are named by replacing -underscores with hypens and prepending locale- to the name -For example the attribute int_frac_digits -can be accessed by the function @code{locale-int-frac-digits}. +underscores with hypens and prepending locale- to the name. +The following is each defined accessor function in the format +Category, Keyword and the accessor function for it. + at itemize + at item LC_MONETARY int_curr_symbol @code{locale-int-curr-symbol} + at item LC_MONETARY currency_symbol @code{locale-currency-symbol} + at item LC_MONETARY mon_decimal_point @code{locale-mon-decimal-point} + at item LC_MONETARY mon_thousands_sep @code{locale-mon-thousands-sep} + at item LC_MONETARY mon_grouping @code{locale-mon-grouping} + at item LC_MONETARY positive_sign @code{locale-positive-sign} + at item LC_MONETARY negative_sign @code{locale-negative-sign} + at item LC_MONETARY int_frac_digits @code{locale-int-frac-digits } + at item LC_MONETARY frac_digits @code{locale-frac-digits } + at item LC_MONETARY p_cs_precedes @code{locale-p-cs-precedes } + at item LC_MONETARY p_sep_by_space @code{locale-p-sep-by-space } + at item LC_MONETARY n_cs_precedes @code{locale-n-cs-precedes } + at item LC_MONETARY n_sep_by_space @code{locale-n-sep-by-space } + at item LC_MONETARY p_sign_posn @code{locale-p-sign-posn } + at item LC_MONETARY n_sign_posn @code{locale-n-sign-posn } + at item LC_NUMERIC decimal_point @code{locale-decimal-point} + at item LC_NUMERIC thousands_sep @code{locale-thousands-sep} + at item LC_NUMERIC grouping @code{locale-grouping } + at item LC_TIME abday @code{locale-abday} + at item LC_TIME day @code{locale-day} + at item LC_TIME abmon @code{locale-abmon} + at item LC_TIME mon @code{locale-mon} + at item LC_TIME d_t_fmt @code{locale-d-t-fmt} + at item LC_TIME d_fmt @code{locale-d-fmt} + at item LC_TIME t_fmt @code{locale-t-fmt} + at item LC_TIME am_pm @code{locale-am-pm} + at item LC_TIME t_fmt_ampm @code{locale-t-fmt-ampm} + at item LC_TIME date_fmt @code{locale-date-fmt} + at item LC_MESSAGES yesexpr @code{locale-yesexpr} + at item LC_MESSAGES noexpr @code{locale-noexpr} + at item LC_PAPER height @code{locale-height} + at item LC_PAPER width @code{locale-width} + at item LC_NAME name_fmt @code{locale-name-fmt} + at item LC_NAME name_gen @code{locale-name-gen} + at item LC_NAME name_mr @code{locale-name-mr} + at item LC_NAME name_mrs @code{locale-name-mrs} + at item LC_NAME name_miss @code{locale-name-miss} + at item LC_NAME name_ms @code{locale-name-ms} + at item LC_ADDRESS postal_fmt @code{locale-postal-fmt} + at item LC_TELEPHONE tel_int_fmt @code{locale-tel-int-fmt} + at item LC_MEASUREMENT measurement @code{locale-measurement} + at end itemize @section Known Issues @itemize @bullet @item LC_COLLATE and LC_CTYPE categories in the locale files are currently ignored. - at item Not all time format directives are supported. + at item Not all time format directives are supported (U, V and W are not implemented). @end itemize