Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to convert DATE in string from one format into another ?

How to convert DATE in string from one format into another ?

by  corvax  Posted    (Edited  )
Q: How to convert DATE in string from one format into another ?

Hello!

Sometimes there is need to reformat DATE which is represented as
string from one format into another (e.g. from "DD.MM.YYYY" to
"YY MON DD").
The very first solution of this problem you could think about is
sequence of (substring ... ...) combined into destination format.
But in cases when destination format is not defined at development time
this solution is too ugly - you should forecast all possible
formats and somehow select the right one.

Another solution: convert source string into DATE type value and then
customize string representation of this value.
This solution is ok when you use standart DATE formats and working with dates.
In case of user defined types this solution also is not efficient.

And now.
The third (not the last, and probably not the best ;) solution.
This small library which is capable to convert dates, time, month ... whatever !
Token oriented approach is used. Token are user defined - you can freely add
new tokens, tokengroups and collection. So you can add any functionality...
(as for me - i can hardly image other ways to use this library ...)

If You are not interested in functionality provided, just check code - there are
some interesting techniques used (tokens incapsulates both data and methods -
just like classes do).
(Writen in MONK. e*Gate 4.1.2 used)

How to use/try this ?
Put all the code from CUT section (further) into single file (test.monk)
And from the command prompt execute: stctrans -md test.monk >test.screen
Check the test.screen file for results.
(Example code is at the very end of CUT section)

There are not so many comments in code - originally all comments are in russian
and i'm too lazy to translate them. Of course, if somebody is interested -
i'll be glad to post/send also comented code with more examples.
Also any other feedback (comments, ideas, critic, questions, bug-reports)
is kindly welcommed.

Regards,

Romans Krjukovs (aka corvax)



!!!
All code is provided AS IS. With no warranties at all.
Use this code on your own risk. Author ot this scripts is not resposible
if something is wrong, etc., etc., etc.
!!!

<--------------------- CUT HERE : START ---------------------------------------------->
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HISTORY:
; Initial version: 1.0 Romans.Krjukovs@verdi.lv [16.09.2002]
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Terminology:
;
; * [token] - is a piece of information.
; Examples: month, day, year, lenght, switch status.
; * [token format] - alpha-numerical string with exactly identifies given
; token between other tokens in strings.
; Examples: "DD" - could be token format for days;
; "MON" - could be token format for months;
; "STATUS" - could be token format for switch status
; * [token image] - valid piece of data
; Examples: "12" - image of "DD" token, represents day #12
; "jan" - image of "MON" token, represents january
; "__ON__" - image of "STATUS" token, represents switch is on
; NOTE!
; 1. Length od token format and token images should be equal !
; "jan" is valid image of token format "MON",
; "2002" is invalid image ot token "DD".
; 2. Sometimes "token" is used instead of token format or token image if
; it is clear from context what we are talking about.
;
; * [token group] - group of different token formats, which
; represent the same token.
; Examples: "MM", "mm", "MON" - could be three different token formats
; which are used to represent months.
; * [token group colleaction] - group of token groups, which usually
; are used together.
; Example: tokengroup_Days, tokengroups_Month, tokengroups_Year
; could be placed in one collection for different date format string
; translations.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Implementation:
;
; [token] and [token image] - are strings;
; [token format] - is a vector with three elements:
; 1. token format as a string;
; 2. procedure which translates token image into standart internal value,
; which is common for all tokens in group.
; 3. procedure which translates internal token value into image.
; [token group] - vector of token formats;
; [tokengroup collection] - vector of token groups.
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(define DateTokenGroupCollection
#( tokengroup_Years
tokengroup_Months
tokengroup_Days
tokengroup_Hours
tokengroup_Minutes
tokengroup_Days
)
)

(define tokengroup_Years
#(; VALUE is number "NNNN"
#("yyyy"
(lambda(token) (string->number token)) ; TOKEN IMAGE -> VALUE
(lambda(value) (number->string value)); VALUE -> TOKEN IMAGE
)
#("YY"
(lambda(token) (+ (string->number token) 2000))
(lambda(value)
(string-append (if (< (set! value (- value 2000)) 10) "0" "") (number->string value))
)
)
)
)


(define monthNamesShort #("jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep" "oct" "nov" "dec"))

(define tokengroup_Months
#(; VALUE is number of month (1-12)
#("MON"
(lambda(token)
(let ()
(display "Token = ") (display token) (newline)
(do* ( (i 0 (+ i 1)) (index -1))
( (or (= i 12) (>= index 0))
(if (= index -1) (throw expTokens "[+cx+]ERROR: invalid month token!\n") (+ index 1)))
(set! index (if (string=? token (vector-ref monthNamesShort i)) i -1))
)
)
)
(lambda(value)
(let()
(set! value (truncate (- value 1)))
(if (not (integer? value))
(throw expTokens "[+cx+]ERROR: Month number should be INTEGER!\n")
)
(if (or (< value 1) (> value 12))
(throw expTokens "[+cx+]ERROR: Invalid month number!\n")
(vector-ref monthNamesShort value)
)
)
)
)
#("MM"
(lambda(token) (string->number token))
(lambda(value) (number->string value))
)
)
)


(define tokengroup_Days
#(; VALUE is number "NN"
#("DD"
(lambda(token) (string->number token)) ; TOKEN IMAGE -> VALUE
(lambda(value) (number->string value)) ; VALUE -> TOKEN IMAGE
)
)
)


(define tokengroup_Hours
#(; VALUE is number "NN"
#("HH"
(lambda(token) (string->number token)) ; TOKEN IMAGE -> VALUE
(lambda(value) (number->string value)) ; VALUE -> TOKEN IMAGE
)
)
)


(define tokengroup_Minutes
#(; VALUE is number "NN"
#("MI"
(lambda(token) (string->number token)) ; TOKEN IMAGE -> VALUE
(lambda(value) (number->string value)) ; VALUE -> TOKEN IMAGE
)
)
)


(define tokengroup_Seconds
#(; VALUE is number "NN"
#("SS"
(lambda(token) (string->number token)) ; TOKEN IMAGE -> VALUE
(lambda(value) (number->string value)) ; VALUE -> TOKEN IMAGE
)
)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; findTokenIndexInGroup
;
; USAGE: (findTokenIndexInGroup token tokenGroup)
; ARGUMENTS: token - token to be found;
; tokenGroup - tokenGroup where search should be performed
; RESULT: (number) index of token in tokenGroup, or
; -1 if token is not defined in tokenGroup
; THROW: none
;
; DESCRIPTION:
; Searchs for specified token in given tokenGroup.
;
; HISTORY:
; Initial version: 1.0 Romans.Krjukovs@verdi.lv [16.09.2002]
; Changes:
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
(define findTokenIndexInGroup
(lambda (token tokenGroup)
(let ( (index -1)
(tokensInGroup (vector-length tokenGroup))
)
(do* ( (i 0 (+ i 1)) )
( (or (= i tokensInGroup) (>= index 0)) index)
(set! index (if (string=? token (vector-ref (vector-ref tokenGroup i) 0)) i -1))
); do*
)
)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; translateTokenInGroup
;
; USAGE: (translateTokenInGroup sourceToken sourceTokenImage destToken tokenGroup)
; ARGUMENTS: sourceToken - format of source token ("yyyy" for example)
; sourceTokenImage - image of source token ("2002" for example)
; destToken - format of dest. token ("YY" for example)
; tokenGroup - tokenGroup which is used to translate value
; RESULT: (string) - image of destination token
; THROW: expTokens - if error ocuers
;
; DESCRIPTION:
; Translates token image from one format into another using
; translation rules defined in specified tokenGroup.
;
; HISTORY:
; Initial version: 1.0 Romans.Krjukovs@verdi.lv [16.09.2002]
; Changes:
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
(define translateTokenInGroup
(lambda (sourceToken sourceTokenImage destToken tokenGroup)
(let ( (tokensInGroup (vector-length tokenGroup))
(sourceIndex -1)
(value "")
(destIndex -1)
(result "")
)
(if (>= (set! sourceIndex (findTokenIndexInGroup sourceToken tokenGroup)) 0)
(if (set! destIndex (findTokenIndexInGroup destToken tokenGroup))
(begin
(set! value (apply (eval (vector-ref (vector-ref tokenGroup sourceIndex) 1)) (list sourceTokenImage)))
(set! result (apply (eval (vector-ref (vector-ref tokenGroup destIndex) 2)) (list value)))
)
(throw expTokens (string-append "[+cx+]ERROR: Destination token is not found in given tokenGroup. Token = \"" destToken "\"\N"))
)
(throw expTokens (string-append "[+cx+]ERROR: Source token is not found in given tokenGroup. Token = \"" sourceToken "\"\N"))
)
result
)
)
)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; convertDateString
;
; USAGE: (convertDateString sourceString sourceFormat destFormat tokenGroupCollection)
; ARGUMENTS: sourceString - string to be translated;
; sourceFormat - format (with tokens) of source string to be translated;
; destFormat - format (with tokens) of destination string;
; tokenGroupCollection - collection of tokenGroups, which defined translation rules
; RESULT: (string) - destination string
; THROW: someexceptions
;
; DESCRIPTION:
; Function translates string from one format into another.
; Format strings should contain tokens. Translation is done
; according to translation rules of tokenGroups in specified collection.
;
;
; HISTORY:
; Initial version: 1.0 Romans.Krjukovs@verdi.lv [16.09.2002]
; Changes:
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
(define convertDateString
(lambda (sourceString sourceFormat destFormat tokenGroupCollection)
(let* ( (numberOfTokenGroups (vector-length tokenGroupCollection))
(dfLength (string-length destFormat))
(tokenGroup #())
(destString "")
(index 0)
(result "")
)
(do* ( (dfHead 0 (+ dfHead 1))
(tokenPasted #f #f) )
( (= dfHead dfLength) )
(do* ( (bufEnd dfLength (- bufEnd 1))
(buf "")
(bufIsToken #f #f) )
( (= bufEnd dfHead) )
(set! buf (substring destFormat dfHead bufEnd))
(do* ( (tokenGroupNum 0 (+ tokenGroupNum 1)) )
( (or (= tokenGroupNum numberOfTokenGroups) bufIsToken) )
(do* ( (curTokenGroup (vector-ref tokenGroupCollection tokenGroupNum))
(tokensInGroup (apply vector-length (list curTokenGroup)))
(tokenNum 0 (+ tokenNum 1))
(curToken #()) )
( (or (= tokenNum tokensInGroup) bufIsToken) )
(set! curToken (apply vector-ref (list curTokenGroup tokenNum)))
(if (set! bufIsToken (string=? buf (vector-ref curToken 0)))
(set! tokenGroup curTokenGroup)
)
)
)
(if bufIsToken
(begin
(set! dfHead (+ dfHead (string-length buf) -1))
(if (set! tokenPasted (number? (set! index (substring-index buf sourceFormat))))
(set! result (string-append result (substring sourceString index (+ index (string-length buf)))))
(do* ( (tokenNum 0 (+ tokenNum 1))
(tokenInGroup (apply vector-length (list tokenGroup)))
(memberTokenFound #f #f)
(memberToken "" "")
(value "") )
( (or (= tokenNum tokenInGroup) memberTokenFound) )
(set! memberToken (vector-ref (apply vector-ref (list tokenGroup tokenNum)) 0))
(set! memberTokenFound (number? (substring-index memberToken sourceFormat)))
(if memberTokenFound
(begin
(set! index (substring-index memberToken sourceFormat))
(set! value (substring sourceString index (+ index (string-length memberToken))))
(set! value (apply translateTokenInGroup (list memberToken value buf tokenGroup)))
(set! result (string-append result value))
(set! tokenPasted #t)
)
)
)
)
)
)
)
(if (not tokenPasted)
(set! result (string-append result (substring destFormat dfHead (+ dfHead 1))))
)
)
result
)
)
)

(newline)
(display (string-append "Lets convert \"30.09.2002\" in such format \"YY-MON-DD\". Result = \""
(convertDateString "30.09.2002" "DD.MM.yyyy" "YY-MON-DD" DateTokenGroupCollection) "\"\n"))
(display (string-append "Another convertion example. Source string is \"1977.12.01\" and the new format is: \""
(convertDateString "1977.12.01" "yyyy.MM.DD" "I was born at DD of MON in yyyy" DateTokenGroupCollection) "\"\n"))
<--------------------- CUT HERE : END ---------------------------------------------->
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top