% This file was created automatically from string.msk. % DO NOT EDIT! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %A string.msk GAP documentation Martin Schoenert %A Alexander Hulpke %% %A @(#)$Id: string.msk,v 1.32.2.5 2008/11/23 10:11:51 alexk Exp $ %% %Y (C) 1998 School Math and Comp. Sci., University of St. Andrews, Scotland %Y Copyright (C) 2002 The GAP Group %% \Chapter{Strings and Characters} \index{type!strings} \index{doublequotes} \index{singlequotes} \>IsChar( <obj> ) C \>IsCharCollection( <obj> ) C A *character* is simply an object in {\GAP} that represents an arbitrary character from the character set of the operating system. Character literals can be entered in {\GAP} by enclosing the character in *singlequotes* `{'}'. \beginexample gap> x:= 'a'; IsChar( x ); 'a' true gap> '*'; '*' \endexample \>IsString( <obj> ) C A *string* is a dense list (see~"IsList", "IsDenseList") of characters (see~"IsChar"); thus strings are always homogeneous (see~"IsHomogeneousList"). A string literal can either be entered as the list of characters or by writing the characters between *doublequotes* `\"'. {\GAP} will always output strings in the latter format. However, the input via the double quote syntax enables {\GAP} to store the string in an efficient compact internal representation. See "IsStringRep" below for more details. Each character, in particular those which cannot be typed directly from the keyboard, can also be typed in three digit octal notation. And for some special characters (like the newline character) there is a further possibility to type them, see section "Special Characters". \beginexample gap> s1 := ['H','e','l','l','o',' ','w','o','r','l','d','.']; "Hello world." gap> IsString( s1 ); true gap> s2 := "Hello world."; "Hello world." gap> s1 = s2; true gap> s3 := ""; # the empty string "" gap> s3 = []; true gap> IsString( [] ); true gap> IsString( "123" ); IsString( 123 ); true false gap> IsString( [ '1', '2', '3' ] ); true gap> IsString( [ '1', '2', , '4' ] ); # strings must be dense false gap> IsString( [ '1', '2', 3 ] ); # strings must only contain characters false \endexample %notest \beginexample gap> s := "\007"; "\007" gap> Print(s); # rings bell in many terminals \endexample Note that a string is just a special case of a list. So everything that is possible for lists (see~"Lists") is also possible for strings. Thus you can access the characters in such a string (see~"List Elements"), test for membership (see~"Membership Test for Collections"), ask for the length, concatenate strings (see~"Concatenation"), form substrings etc. You can even assign to a mutable string (see~"List Assignment"). Of course unless you assign a character in such a way that the list stays dense, the resulting list will no longer be a string. \beginexample gap> Length( s2 ); 12 gap> s2[2]; 'e' gap> 'a' in s2; false gap> s2[2] := 'a';; s2; "Hallo world." gap> s1{ [1..4] }; "Hell" gap> Concatenation( s1{ [ 1 .. 6 ] }, s1{ [ 1 .. 4 ] } ); "Hello Hell" \endexample If a string is displayed by `View', for example as result of an evaluation (see~"Main Loop"), or by `ViewObj' and `PrintObj', it is displayed with enclosing doublequotes. (But note that there is an ambiguity for the empty string which is also an empty list of arbitrary {\GAP} objects; it is only printed like a string if it was input as empty string or converted to a string with "ConvertToStringRep".) The difference between `ViewObj' and `PrintObj' is that the latter prints *all* non-printable and non-ASCII characters in three digit octal notation, while `ViewObj' sends all printable characters to the output stream. The output of `PrintObj' can be read back into {\GAP}. Strings behave differently from other {\GAP} objects with respect to `Print', `PrintTo', or `AppendTo'. These commands *interpret* a string in the sense that they essentially send the characters of the string directly to the output stream/file. (But depending on the type of the stream and the presence of some special characters used as hints for line breaks there may be sent some additional newline (or backslash and newline) characters. \beginexample gap> s4:= "abc\"def\nghi";; gap> View( s4 ); Print( "\n" ); "abc\"def\nghi" gap> ViewObj( s4 ); Print( "\n" ); "abc\"def\nghi" gap> PrintObj( s4 ); Print( "\n" ); "abc\"def\nghi" gap> Print( s4 ); Print( "\n" ); abc"def ghi gap> s := "German uses strange characters: \344\366\374\337\n"; "German uses strange characters: äöüß\n" gap> Print(s); German uses strange characters: äöüß gap> PrintObj(s); "German uses strange characters: \344\366\374\337\n"gap> \endexample Note that only those line breaks are printed by `Print' that are contained in the string (`\\n' characters, see~"Special Characters"), as is shown in the example below. %notest \beginexample gap> s1; "Hello world." gap> Print( s1 ); Hello world.gap> Print( s1, "\n" ); Hello world. gap> Print( s1, "\nnext line\n" ); Hello world. next line \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Special Characters} \index{escaped characters} \index{special character sequences} There are a number of *special character sequences* that can be used between the singlequotes of a character literal or between the doublequotes of a string literal to specify characters. They consist of two characters. The first is a backslash $\backslash$. The second may be any character. If it is an octal digit (from `0' to `7') there must be two more such digits. The meaning is given in the following list \beginlist \indextt{\\n}\index{newline character} \item{`\\n'} *newline character*. This is the character that, at least on UNIX systems, separates lines in a text file. Printing of this character in a string has the effect of moving the cursor down one line and back to the beginning of the line. \indextt{\\\"}\index{doublequote character} \item{`\\\"'} *doublequote character*. Inside a string a doublequote must be escaped by the backslash, because it is otherwise interpreted as end of the string. \atindex{\\'}{@\noexpand`\\\pif'}\index{singlequote character} \item{`\\\pif'} *singlequote character*. Inside a character a singlequote must escaped by the backslash, because it is otherwise interpreted as end of the character. \indextt{\\\\}\index{backslash character} \item{`\\\\'} *backslash character*. Inside a string a backslash must be escaped by another backslash, because it is otherwise interpreted as first character of an escape sequence. \indextt{\\b}\index{backspace character} \item{`\\b'} *backspace character*. Printing this character should have the effect of moving the cursor back one character. Whether it works or not is system dependent and should not be relied upon. \indextt{\\r}\index{carriage return character} \item{`\\r'} *carriage return character*. Printing this character should have the effect of moving the cursor back to the beginning of the same line. Whether this works or not is again system dependent. \indextt{\\c}\index{flush character} \item{`\\c'} *flush character*. This character is not printed. Its purpose is to flush the output queue. Usually {\GAP} waits until it sees a <newline> before it prints a string. If you want to display a string that does not include this character use `\\c'. \indextt{\\XYZ}\index{octal character codes} \item{`\\XYZ'} with X, Y, Z three octal digits. This is translated to the character correponding to the number X*64+Y*8+Z modulo 256. This can be used to specify and store arbitrary binary data as a string in {\GAP}. \index{escaping non-special characters} \item{other} For any other character the backslash is simply ignored. \endlist Again, if the line is displayed as result of an evaluation, those escape sequences are displayed in the same way that they are input. Only `Print', `PrintTo', or `AppendTo' send the characters directly to the output stream. % XXX Should the characters \< and \> and their use with `Print' be documented? \beginexample gap> "This is one line.\nThis is another line.\n"; "This is one line.\nThis is another line.\n" gap> Print( last ); This is one line. This is another line. \endexample Note in particular that it is not allowed to enclose a <newline> inside the string. You can use the special character sequence `$\backslash$n' to write strings that include <newline> characters. If, however, an input string is too long to fit on a single line it is possible to *continue* it over several lines. In this case the last character of each input line, except the last line must be a backslash. Both backslash and <newline> are thrown away by {\GAP} while reading the string. Note that the same continuation mechanism is available for identifiers and integers, see~"Special Rules for Input Lines". %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Internally Represented Strings} \index{convert!to a string} \>IsStringRep( <obj> ) R `IsStringRep' is a special (internal) representation of dense lists of characters. Dense lists of characters can be converted into this representation using `ConvertToStringRep'. Note that calling `IsString' does *not* change the representation. \>ConvertToStringRep( <obj> ) F If <obj> is a dense internally represented list of characters then `ConvertToStringRep' changes the representation to `IsStringRep'. This is useful in particular for converting the empty list `[]', which usually is in `IsPlistRep', to `IsStringRep'. If <obj> is not a string then `ConvertToStringRep' signals an error. \>IsEmptyString( <str> ) F `IsEmptyString' returns `true' if <str> is the empty string in the representation `IsStringRep', and `false' otherwise. Note that the empty list `[]' and the empty string `\"\"' have the same type, the recommended way to distinguish them is via `IsEmptyString'. For formatted printing, this distinction is sometimes necessary. \beginexample gap> l:= [];; IsString( l ); IsEmptyString( l ); IsEmpty( l ); true false true gap> l; ConvertToStringRep( l ); l; [ ] "" gap> IsEmptyString( l ); IsEmptyString( "" ); IsEmptyString( "abc" ); true true false gap> ll:= [ 'a', 'b' ]; IsStringRep( ll ); ConvertToStringRep( ll ); "ab" false gap> ll; IsStringRep( ll ); "ab" true \endexample \>EmptyString( <len> ) F \>ShrinkAllocationString( <str> ) The function `EmptyString' returns an empty string in internal representation which has enough memory allocated for <len> characters. This can be useful for creating and filling a string with a known number of entries. The function `ShrinkAllocationString' gives back to {\GAP}s memory manager the physical memory which is allocated for the string <str> in internal representation but not needed by its current number of characters. These functions are intended for saving some of {\GAP}s memory in certain situations, see the explanations and the example for the analogeous functions `EmptyPlist' and `ShrinkAllocationPlist' for plain lists. \>`CharsFamily' V Each character lies in the family `CharFamily', each nonempty string lies in the collections family of this family. Note the subtle differences between the empty list `[]' and the empty string `\"\"' when both are printed. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Recognizing Characters} \>IsDigitChar( <c> ) F checks whether the character <c> is a digit, i.e., occurs in the string `\"0123456789\"'. \>IsLowerAlphaChar( <c> ) F checks whether the character <c> is a lowercase alphabet letter, i.e., occurs in the string `\"abcdefghijklmnopqrstuvwxyz\"'. \>IsUpperAlphaChar( <c> ) F checks whether the character <c> is an uppercase alphabet letter, i.e., occurs in the string `\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"'. \>IsAlphaChar( <c> ) F checks whether the character <c> is either a lowercase or an uppercase alphabet letter. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Comparisons of Strings} \>`<string1> = <string2>'{strings!equality of} \>`<string1> \<> <string2>'{strings!inequality of} The equality operator `=' returns to `true' if the two strings <string1> and <string2> are equal and `false' otherwise. The inequality operator `\<>' returns `true' if the two strings <string1> and <string2> are not equal and `false' otherwise. \beginexample gap> "Hello world.\n" = "Hello world.\n"; true gap> "Hello World.\n" = "Hello world.\n"; # string comparison is case sensitive false gap> "Hello world." = "Hello world.\n"; # the first string has no <newline> false gap> "Goodbye world.\n" = "Hello world.\n"; false gap> [ 'a', 'b' ] = "ab"; true \endexample \>`<string1> \< <string2>'{strings!lexicographic ordering of} The ordering of strings is lexicographically according to the order implied by the underlying, system dependent, character set. \beginexample gap> "Hello world.\n" < "Hello world.\n"; # the strings are equal false gap> "Hello World." < "Hello world."; # in ASCII capitals range before small letters true gap> "Hello world." < "Hello world.\n"; # prefixes are always smaller true gap> "Goodbye world.\n" < "Hello world.\n"; # `G' comes before `H', in ASCII at least true \endexample Strings can be compared via `\<' with certain {\GAP} objects that are not strings, see~"Comparisons" for the details. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Operations to Produce or Manipulate Strings} \>String( <obj> ) A \>String( <obj>, <length> ) O `String' returns a representation of <obj>, which may be an object of arbitrary type, as a string. This string should approximate as closely as possible the character sequence you see if you print <obj>. If <length> is given it must be an integer. The absolute value gives the minimal length of the result. If the string representation of <obj> takes less than that many characters it is filled with blanks. If <length> is positive it is filled on the left, if <length> is negative it is filled on the right. In the two argument case, the string returned is a new mutable string (in particular not a part of any other object); it can be modified safely, and `MakeImmutable' may be safely applied to it. \beginexample gap> String(123);String([1,2,3]); "123" "[ 1, 2, 3 ]" \endexample \>HexStringInt( <int> ) F returns a string which represents the integer <int> with hexa-decimal digits (using `A-F' as digits `10-15'). The inverse translation can be achieved with "IntHexString". \>StringPP( <int> ) F returns a string representing the prime factor decomposition of the integer <int>. \beginexample gap> StringPP(40320); "2^7*3^2*5*7" \endexample \>WordAlp( <alpha>, <nr> ) F returns a string that is the <nr>-th word over the alphabet list <alpha>, w.r.t. word length and lexicographical order. The empty word is `WordAlp( <alpha>, 0 )'. \beginexample gap> List([0..5],i->WordAlp("abc",i)); [ "", "a", "b", "c", "aa", "ab" ] \endexample \>LowercaseString( <string> ) F returns a lowercase version of the string <string>, that is, a string in which each uppercase alphabet character is replaced by the corresponding lowercase character. \beginexample gap> LowercaseString("This Is UpperCase"); "this is uppercase" \endexample \>SplitString( <string>, <seps>[, <wspace>] ) O This function accepts a string <string> and lists <seps> and, optionally, <wspace> of characters. Now string is split into substrings at each occurrence of a character in <seps> or <wspace>. The characters in <wspace> are interpreted as white space characters. Substrings of characters in <wspace> are treated as one white space character and they are ignored at the beginning and end of a string. Both arguments <seps> and <wspace> can be single characters. Each string in the resulting list of substring does not contain any characters in <seps> or <wspace>. A character that occurs both in <seps> and <wspace> is treated as a white space character. A separator at the end of a string is interpreted as a terminator; in this case, the separator does not produce a trailing empty string. Also see~"Chomp". \beginexample gap> SplitString( "substr1:substr2::substr4", ":" ); [ "substr1", "substr2", "", "substr4" ] gap> SplitString( "a;b;c;d;", ";" ); [ "a", "b", "c", "d" ] gap> SplitString( "/home//user//dir/", "", "/" ); [ "home", "user", "dir" ] \endexample \>ReplacedString( <string>, <old>, <new> ) F replaces occurrences of the string <old> in <string> by <new>, starting from the left and always replacing the first occurrence. To avoid infinite recursion, characters which have been replaced already, are not subject to renewed replacement. \beginexample gap> ReplacedString("abacab","a","zl"); "zlbzlczlb" gap> ReplacedString("ababa", "aba","c"); "cba" gap> ReplacedString("abacab","a","ba"); "babbacbab" \endexample \>NormalizeWhitespace( <string> ) F This function changes the string <string> in place. The characters ` ' (space), `\\n', `\\r' and `\\t' are considered as *white space*. Leading and trailing white space characters in <string> are removed. Sequences of white space characters between other characters are replaced by a single space character. See "NormalizedWhitespace" for a non-destructive version. \beginexample gap> s := " x y \n\n\t\r z\n \n"; " x y \n\n\t\r z\n \n" gap> NormalizeWhitespace(s); gap> s; "x y z" \endexample \>NormalizedWhitespace( <str> ) F This function returns a copy of string <str> to which "NormalizeWhitespace" was applied. \>RemoveCharacters( <string>, <chars> ) Both arguments must be strings. This function efficiently removes all characters given in <chars> from <string>. \beginexample gap> s := "ab c\ndef\n\ng h i .\n"; "ab c\ndef\n\ng h i .\n" gap> RemoveCharacters(s, " \n\t\r"); # remove all whitespace characters gap> s; "abcdefghi." \endexample For the possibility to print {\GAP} objects to strings, see~"String Streams". \>JoinStringsWithSeparator( <list>[, <sep>] ) F joins <list> (a list of strings) after interpolating <sep> (or `","' if the second argument is omitted) between each adjacent pair of strings; <sep> should be a string. *Examples* \beginexample gap> list := List([1..10], String); [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ] gap> JoinStringsWithSeparator(list); "1,2,3,4,5,6,7,8,9,10" gap> JoinStringsWithSeparator(["The", "quick", "brown", "fox"], " "); "The quick brown fox" gap> JoinStringsWithSeparator(["a", "b", "c", "d"], ",\n "); "a,\n b,\n c,\n d" gap> Print(" ", last, "\n"); a, b, c, d \endexample Recall, `last' is the last expression output by {\GAP}. \>Chomp( <str> ) F Like the similarly named Perl function, `Chomp' removes a trailing newline character (or carriage-return line-feed couplet) from a string argument <str> if present and returns the result. If <str> is not a string or does not have such trailing character(s) it is returned unchanged. This latter property means that `Chomp' is safe to use in cases where one is manipulating the result of another function which might sometimes return `fail', for example. \beginexample gap> Chomp("The quick brown fox jumps over the lazy dog.\n"); "The quick brown fox jumps over the lazy dog." gap> Chomp("The quick brown fox jumps over the lazy dog.\r\n"); "The quick brown fox jumps over the lazy dog." gap> Chomp("The quick brown fox jumps over the lazy dog."); "The quick brown fox jumps over the lazy dog." gap> Chomp(fail); fail gap> Chomp(32); 32 \endexample *Note:* `Chomp' only removes a trailing newline character from <str>. If your string contains several newline characters and you really want to split <str> into lines at the newline characters (and remove those newline characters) then you should use `SplitString' (see~"SplitString"), e.g. \beginexample gap> str := "The quick brown fox\njumps over the lazy dog.\n"; "The quick brown fox\njumps over the lazy dog.\n" gap> SplitString(str, "", "\n"); [ "The quick brown fox", "jumps over the lazy dog." ] gap> Chomp(str); "The quick brown fox\njumps over the lazy dog." \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Character Conversion} The following functions convert characters in their internal integer values and vice versa. Note that the number corresponding to a particular character might depend on the system used. While most systems use an extension of ASCII, in particular character values outside the range 32-126 might differ between architectures. All functions in this section are internal and behaviour is undefined if invarid arguments are given. \>INT_CHAR(<char>) F returns an integer value in the range 0-255 that corresponds to <char>. \>CHAR_INT(<int>) F returns a character which corresponds to the integer value <int>, which must be in the range 0-255. \beginexample gap> c:=CHAR_INT(65); 'A' gap> INT_CHAR(c); 65 \endexample \>SINT_CHAR(<char>) F returns a signed integer value in the range $-128$--127 that corresponds to <char>. \>CHAR_SINT(<int>) F returns a character which corresponds to the signed integer value <int>, which must be in the range $-128$--127. The signed and unsigned integer functions behave the same for values in the range from 0 to 127. \beginexample gap> SINT_CHAR(c); 65 gap> c:=CHAR_SINT(-20);; gap> SINT_CHAR(c); -20 gap> INT_CHAR(c); 236 gap> SINT_CHAR(CHAR_INT(255)); -1 \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Operations to Evaluate Strings} \index{evaluation!strings} \>Int( <str> )!{for strings} A \>Rat( <str> )!{for strings} A \>IntHexString( <str> ) F return either an integer (`Int' and `IntHexString'), or a rational (`Rat') as represented by the string <str>. `Int' returns `fail' if non-digit characters occur in <str>. For `Rat', the argument string may start with the sign character `{'}-{'}', followed by either a sequence of digits or by two sequences of digits that are separated by one of the characters `{'}/{'}' or `{'}.{'}', where the latter stands for a decimal dot. (The methods only evaluate numbers but do *not* perform arithmetic!) `IntHexString' evaluates an integer written with hexa-decimal digits. Here the letters <a-f> or <A-F> are used as *digits* <10-15>. An error occurs when a wrong character is found in the string. This function can be used (together with "HexStringInt") for efficiently storing and reading large integers from respectively into {\GAP}. Note that the translation between integers and their hexa-decimal representation costs linear computation time in terms of the number of digits, while translation from and into decimal representation needs substantial computations. If <str> is not in compact string representation then "ConvertToStringRep" is applied to it as side effect. \beginexample gap> Int("12345")+1; 12346 gap> Int("123/45"); fail gap> Int("1+2"); fail gap> Int("-12"); -12 gap> Rat("123/45"); 41/15 gap> Rat( "123.45" ); 2469/20 gap> IntHexString("-abcdef0123456789"); -12379813738877118345 gap> HexStringInt(last); "-ABCDEF0123456789" \endexample \>Ordinal( <n> ) F returns the ordinal of the integer <n> as a string. \beginexample gap> Ordinal(2); Ordinal(21); Ordinal(33); Ordinal(-33); "2nd" "21st" "33rd" "-33rd" \endexample \>EvalString( <expr> ) F passes <expr> (a string) through an input text stream so that {\GAP} interprets it, and returns the result. The following trivial example demonstrates its use. \beginexample gap> a:=10; 10 gap> EvalString("a^2"); 100 \endexample `EvalString' is intended for *single* expressions. A sequence of commands may be interpreted by using the functions `InputTextString' (see~"InputTextString") and `ReadAsFunction' (see~"ReadAsFunction!for streams") together; see "Operations for Input Streams" for an example. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Calendar Arithmetic} All calendar functions use the Gregorian calendar. \>DaysInYear( <year> ) F returns the number of days in a year. \>DaysInMonth( <month>, <year> ) F returns the number of days in month number <month> of <year> (and `fail' if `month' is integer not in valid range. \beginexample gap> DaysInYear(1998); 365 gap> DaysInMonth(3,1998); 31 \endexample \>DMYDay( <day> ) F converts a number of days, starting 1-Jan-1970 to a list `[<day>,<month>,<year>]' in Gregorian calendar counting. \>DayDMY( <dmy> ) F returns the number of days from 01-Jan-1970 to the day given by <dmy>. <dmy> must be a list of the form `[<day>,<month>,<year>]' in Gregorian calendar counting. The result is `fail' on input outside valid ranges. Note that this makes not much sense for early dates like: before 1582 (no Gregorian calendar at all), or before 1753 in many English countries or before 1917 in Russia. \>WeekDay( <date> ) F returns the weekday of a day given by <date>. <date> can be a number of days since 1-Jan-1970 or a list `[<day>,<month>,<year>]'. \>StringDate( <date> ) F converts <date> to a readable string. <date> can be a number of days since 1-Jan-1970 or a list `[<day>,<month>,<year>]'. \beginexample gap> DayDMY([1,1,1970]);DayDMY([2,1,1970]); 0 1 gap> DMYDay(12345); [ 20, 10, 2003 ] gap> WeekDay([11,3,1998]); "Wed" gap> StringDate([11,3,1998]); "11-Mar-1998" \endexample \>HMSMSec( <msec> ) F converts a number <msec> of milliseconds into a list `[<hour>,<min>,<sec>,<milli>]'. \>SecHMSM( <hmsm> ) F is the reverse of `HMSMSec'. \>StringTime( <time> ) F converts <time> (given as a number of milliseconds or a list `[<hour>, <min>, <sec>, <milli>]') to a readable string. \beginexample gap> HMSMSec(Factorial(10)); [ 1, 0, 28, 800 ] gap> SecHMSM([1,10,5,13]); 4205013 gap> StringTime([1,10,5,13]); " 1:10:05.013" \endexample \>SecondsDMYhms( <DMYhms> ) F returns the number of seconds from 01-Jan-1970, 00:00:00, to the time given by <DMYhms>. <DMYhms> must be a list of the form `[<day>,<month>,<year>,<hour>,<minute>,<second>]'. The remarks on the Gregorian calendar in the section on "DayDMY" apply here as well. The last three arguments must lie in the appropriate ranges. \>DMYhmsSeconds( <secs> ) F This is the inverse function to "SecondsDMYhms". \beginexample gap> SecondsDMYhms([ 9, 9, 2001, 1, 46, 40 ]); 1000000000 gap> DMYhmsSeconds(-1000000000); [ 24, 4, 1938, 22, 13, 20 ] \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E