Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
How do I convert a date to a strictdate
Message
De
10/02/2000 16:49:14
 
 
À
10/02/2000 15:04:52
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00329655
Message ID:
00330365
Vues:
17
>Ed,
>
>Here are my two functions to convert back and forth between date/datetime vars and strictdates. The first one has maybe more params than what you might want but I wanted to write it once to do a number of things; simplify it if you like; the second one is also handy for converting back. Some of the wrapping might also be off so check that before running it. Also, these are fairly new so they might not yet be bulletproof. If you have any suggestions, send them on.
>

It looks interesting, but I'm a lazy curmudgeon, and the RegExp can do a whole lot more than what I've shown here. Let's generalize the RegExp I've been using a bit:

oRegExp.pattern = "(\d{1,2}[-/\\](\d{1,2})[-/\\](\d{2,4}"
oRegExp.Global = .f.
s = oRegExp.replace(s,"{^$3-$2-$1}")

This handles any of the separators, 1 or 2 digit month and day; it's now a matter of checking to see if the character in position 5 is a digit or not, and if not, stuff the century into the string.

RegExp can do a whole lot more - for example - I want to know where I assign a value to a textbox property in a piece of code. By convention, I prefix textbox controls with "txt"; I can do something like:

oRegExp.pattern = "[\s.]txt[^.]*.[^=]*="
oMatches = oRegExp.Execute(FileToStr('MyCodeToCheck.PRG'))

oMatches now has a collection of things that hit, with their value, offset in the file, and length.

It can do case-insensitive searches, detect word boundaries, beggining/end of lines or strings, etc.

And if the WSH is installed, it's there for you to use.





>Albert
>
>
>PROCEDURE DateTimeToStrictDate
>* procedure to convert a date to a non-amiguous (character) strict date
>* that can be used in FoxPro when SET STRICTDATE > 0; ideas came from
>* FPAdvisor article, August 1999, page 46, Tip called "A More Universal
>* cDateFormat() Function"; I have mainly added more parameters and checks
>
>* Written by: Albert Gostick
>* Last Updated: Jan 26, 2000
>
>* Parameters:
>* tdDateTime: date or datetime to convert
>* tcDateDelimiter: delimiters to add to either end of the resulting
>* string; optional; if nothing passed, default to adding curly braces
>* ie. {}; put as an option as some SQL languages require delimiting
>* with single quotes; if empty string explicitly passed, then NO
>* delimiters added as some SQL applications don't want delimiters
>* tcDateSeparator: character separator for date expressions; optional,
>* if not passed, defaults to SET MARK TO character (but this also
>* has to be either a hyphen, a forward slash, a period or a space);
>* reverts to forward slash if none of the above
>* tlOmitTime: if a datetime var is passed, if this is set to .T., only
>* returns the date portion of the datetime ie. ignores the time
>
>* Returns: date as character string in non-ambiguous format ie.
>* {^yyyy/mm/dd hh:mm:ss} or returns an empty date if date passed in
>* is empty to start with (ie { / / })
>
>LPARAMETERS tdDateTime, tcDateDelimiter, tcDateSeparator, tlOmitTime
>
>LOCAL lcVarType, lcLeftDelimiter, lcRightDelimiter, lcStrictDate, lcHours, ;
> lcMinutes, lcSeconds
>
>
>*** parameter checks and defaults ***
>
>* if no date passed in, return null character
>
>STORE TYPE("tdDateTime") TO lcVarType
>
>IF NOT lcVarType $ "DT"
> RETURN ""
>ENDIF
>
>* (going to check for empty dates first instead of doing rest of parameter
>* checks since no real need to do those if we are dealing with an empty date)
>
>*** Empty Date ***
>
>* Note: return a fully padded date string so that it has, pretty well, the
>* same length as a date that has been converted; but do not insert the
>* strictdate character (a carat ^) as that causes a bomb if the user then
>* tries to EVAL() it or use it when it is an empty date string; decided to
>* add a space where the carat would be so that if this is called in a SQL
>* statement (for example) the length returned is the same as a character
>* strictdate so that the column width is correct
>
>IF lcVarType = "D" AND EMPTY(tdDateTime)
> RETURN "{ / / }"
>ENDIF
>
>*** Empty Date Time ***
>
>* Note: the spaces in the below are not necessary and I tried then converting
>* the below with varying spaces (no spaces in date or time, spaces just in
>* date, spaces all) and they all convert to a datetime var okay; returned with
>* a space for the carat for reasons outlined above; did not put room in for
>* am or pm as not sure if I need; programmer can always convert to military
>* time or pad up if done in a SQL statement (or proc here could be changed)
>
>IF lcVarType = "T" AND EMPTY(tdDateTime)
> RETURN "{ / / , : : }"
>ENDIF
>
>
>*** Back to paramater checks ***
>
>* check for the delimiter passed in; following case statement is important
>* in its order as user can pass an empty string to indicate no delimiters
>
>DO CASE
>
> * check first if user passed an empty string as this means that no
> * delimiters should be used
>
> CASE TYPE("tcDateDelimiter") = "C" AND EMPTY(tcDateDelimiter)
> STORE "" TO lcLeftDelimiter, lcRightDelimiter
>
> CASE TYPE("tcDateDelimiter") = "C"
>
> * check that it is either a curly brace or a single or double quote
> * and if not, drop back to our default curly braces
>
> IF NOT tcDateDelimiter $ "{}'" AND tcDateDelimiter # ["]
> STORE "" TO tcDateDelimiter
> ENDIF
>
> * now stuff the left and right delimiters; if it is not a curly
> * brace, can just stuff both halves with passed in value
>
> IF EMPTY(tcDateDelimiter) OR tcDateDelimiter $ "{}"
>
> STORE "{" TO lcLeftDelimiter
> STORE "}" TO lcRightDelimiter
>
> ELSE
>
> STORE tcDateDelimiter TO lcLeftDelimiter, lcRightDelimiter
>
> ENDIF
>
> CASE TYPE("tcDateDelimiter") # "C"
>
> STORE "{" TO lcLeftDelimiter
> STORE "}" TO lcRightDelimiter
>
>ENDCASE
>
>* check for the date separator passed in
>
>IF TYPE("tcDateSeparator") # "C"
> STORE "" TO tcDateSeparator
>ENDIF
>
>* check that it is one of the allowable ones (hyphen, forward slash,
>* period or space)
>
>IF NOT tcDateSeparator $ "-/. "
> STORE "" TO tcDateSeparator
>ENDIF
>
>* if still empty, fish out the separator using SET MARK; but only
>* do this if the date separator is not exactly equal to one space
>* as this is a legitimate value
>
>IF NOT tcDateSeparator == " "
>
> STORE SET("Mark") TO tcDateSeparator
>
> * it could still be empty since SET("Mark") returns null if
> * the separator is a forward slash (the default); so if still
> * empty, stuff in the forward slash
>
> IF EMPTY(tcDateSeparator)
> STORE "/" TO tcDateSeparator
> ENDIF
>
>ENDIF
>
>
>*** ready to convert the date ***
>
>* note: I started to do this with LTRIM(STR(YEAR(tdDateTime))) etc but the
>* below actually has a lot less function calls
>
>* checks: DTOS() returns a 4 digit century regardless of SET CENTURY
>
>* Note: we do not have to check for invalid dates as they would have been
>* caught above when checking for an empty date; cannot even stuff a date
>* time with an empty date but a valid time so if an invalid datetime is
>* passed in, it will always be empty and be caught above
>
>STORE LEFT(DTOS(tdDateTime),4) + tcDateSeparator + SUBSTR(DTOS(tdDateTime),5,2) + ;
> tcDateSeparator + SUBSTR(DTOS(tdDateTime),7,2) TO lcStrictDate
>
>* add in the date delimiters and the strict date ^ sign
>
>STORE lcLeftDelimiter + "^" + lcStrictDate + lcRightDelimiter TO lcStrictDate
>
>
>*** Time section ***
>
>* if a date time var was passed in and the programmer has not indicated
>* that they want to suppress the inclusion of the time portion, convert
>* this and add it in
>
>IF lcVarType = "T" AND NOT tlOmitTime
>
> * tested and HOURS() is not affected by SET HOUR TO 12/24 so no need
> * to set or release this; pad all numbers with leading 0's for uniformity
>
> STORE PADL(LTRIM(STR(HOUR(tdDateTime))),2,"0") TO lcHours
> STORE PADL(LTRIM(STR(MINUTE(tdDateTime))),2,"0") TO lcMinutes
> STORE PADL(LTRIM(STR(SEC(tdDateTime))),2,"0") TO lcSeconds
>
> * add these into our string delimited with colons and with a space
> * in between the date and the time (both a comma and a space are
> * permissable; I am not sure about SQL syntax yet therefore, since
> * FoxPro seems to return them with a space more often, will use that
> * and hopefully it will be the best default
>
> STORE lcStrictDate + " " + lcHours + ":" + lcMinutes + ":" + ;
> lcSeconds TO lcStrictDate
>
>ENDIF
>
>RETURN lcStrictDate
>
>
>PROCEDURE StrictDateToDateTime
>* procedure to convert a StrictDate[Time] character string to a true
>* date variable; this conversion is done by using the optional parameters
>* in DATE() and DATETIME() to convert; since these functions require
>* that the year, day and month be passed as numeric, it means that we
>* would continually have to parse the character string and pull out each
>* of these values, hence the function
>
>* Written by: Albert Gostick
>* Last Updated: Jan 26, 2000
>
>* Parameters:
>* tcStrictDate: strict date or datetime string to convert ie. can be in the
>* format {^2000/01/26} or {^2000/01/26 12:23:05};
>
>* Returns: a date variable, empty if strictdate was empty
>
>LPARAMETERS tcStrictDate
>
>LOCAL llHasDate, ;
> ;
> lnYear,lnMonth,lnDay,lnHours,lnMinutes,lnSeconds, ;
> ;
> llDateOkay,lcOldOnError,ldTestDate,llTimeOkay, ;
> ;
> ldReturnDate
>
>* default on some vars
>STORE .F. TO llHasDate
>
>* parameter check, has to be character
>
>IF TYPE("tcStrictDate") # "C"
> STORE "" TO tcStrictDate
>ENDIF
>
>* parameter also has to be at least 13 chars long eg. "{^2000/01/26}"
>* or something is wrong
>
>IF LEN(tcStrictDate) >= 13
> STORE .T. TO llHasDate
>ENDIF
>
>* if date is empty, just return an empty date string; note: I tested
>* and there should NOT be a carat (^) in an empty date; also, if there
>* is no date, even if there is a time in the string, cannot create a
>* DateTime var so just return as well
>
>IF NOT llHasDate
> RETURN {//}
>ENDIF
>
>* otherwise, go ahead and parse the string and convert
>
>STORE VAL(SUBSTR(tcStrictDate,3,4)) TO lnYear
>STORE VAL(SUBSTR(tcStrictDate,8,2)) TO lnMonth
>STORE VAL(SUBSTR(tcStrictDate,11,2)) TO lnDay
>
>* Design: originally I just tested to see that lnYear etc fell within
>* their prescribed limits (eg. Month >=1 and <= 12); but this does not
>* test to see if the date combination is an actual valid date (eg.
>* Sept 31st is a bad date; therefore, easiest thing to do is to trap for
>* an error trigger and just send the date off to that
>
>STORE .T. TO llDateOkay
>
>* save old error condition
>STORE ON("Error") TO lcOldOnError
>
>* set up error trap
>ON ERROR STORE .F. TO llDateOkay
>
>STORE DATE(lnYear,lnMonth,lnDay) TO ldTestDate
>
>* reset the error program
>ON ERROR &lcOldOnError
>
>* if not okay to go on, just return an empty date as we cannot
>* do the time anyhow
>
>IF NOT llDateOkay
> RETURN {//}
>ENDIF
>
>* now parse for the time information; have to check to see if even
>* in string; a string with valid time should be at least 22 chars;
>* will discard also if too long as something must be funny
>
>* default whether time is okay to .F.
>STORE .F. TO llTimeOkay
>
>IF LEN(tcStrictDate) = 22
>
> * parse out the time into vars
> STORE VAL(SUBSTR(tcStrictDate,14,2)) TO lnHours
> STORE VAL(SUBSTR(tcStrictDate,17,2)) TO lnMinutes
> STORE VAL(SUBSTR(tcStrictDate,20,2)) TO lnSeconds
>
> * these ranges can just be tested numerically to see if
> * they all fall into acceptable ranges
>
> IF lnHours >= 0 AND lnHours <= 23 AND lnMinutes >= 0 AND ;
> lnMinutes <= 59 AND lnSeconds >= 0 AND lnSeconds <= 59
>
> STORE .T. TO llTimeOkay
>
> ENDIF
>
>ENDIF
>
>* convert based upon whether date or time or both okay; cannot
>* just pass only date stuff to DATETIME() as it defaults to a
>* datetime var with the date and midnight (00:00:00) as the time
>* which we probably do not want; we have already covered off if
>* date is not okay by returning above so only two options
>
>IF llDateOkay AND llTimeOkay
>
> STORE DATETIME(lnYear,lnMonth,lnDay,lnHours,lnMinutes,lnSeconds) ;
> TO ldReturnDate
>
>ELSE && only date okay
>
> STORE DATE(lnYear,lnMonth,lnDay) TO ldReturnDate
>
>ENDIF
>
>* return this value
>RETURN (ldReturnDate)
EMail: EdR@edrauh.com
"See, the sun is going down..."
"No, the horizon is moving up!"
- Firesign Theater


NT and Win2K FAQ .. cWashington WSH/ADSI/WMI site
MS WSH site ........... WSH FAQ Site
Wrox Press .............. Win32 Scripting Journal
eSolutions Services, LLC

The Surgeon General has determined that prolonged exposure to the Windows Script Host may be addictive to laboratory mice and codemonkeys
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform