Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

SET DATE, DateFormat, SET CENTURY, Century, SET MARK TO, DateMark

These three SET commands and their equivalent local properties for text boxes combine to change the way that dates are displayed in your application. These settings are for display only, and make no difference in how the date is actually stored in the machine. (FoxPro always stores the full four-digit year; see “DBF, FPT, CDX, DBC—Hike!” for a description of the actual disk storage.)

Each of the SET commands may also be performed in the Tools | Options dialog, on the Regional tab. Within the development product, if saved as the default, they are stored in the Registry. They may be overridden at startup with commands in the configuration file CONFIG.FPW or programmatically at any time. Each of these SET commands is scoped to a private data session. SET SYSFORMATS ON causes FoxPro to ignore their settings and use the Control Panel’s Regional settings instead.

As with most SET commands, we feel that you should set them and forget them—leave them the same for the entire application if at all possible. Use the local equivalents to get local exceptional behavior. If possible, consider using the user’s preferences for date display, as set in the Control Panel Regional applet, using SET SYSFORMATS. Check out that topic for the care you’ll need to take with that command.

Usage

SET CENTURY ON | OFF | TO [ nCentury [ ROLLOVER nRollOver ] ]
cOnOrOff = SET( "CENTURY" )
nCentury = SET( "CENTURY", 1 )
nYear = SET( "CENTURY", 2 )
nSystemRolloverYear = SET( "CENTURY", 3)
TextBox.Century = nCenturySetting

Parameter

Value

Meaning

nCentury

1 to 99

The century to stick in front of two-digit years when converting to dates using the {} delimiters or the CTOD() and CTOT() functions.

Omitted

nCentury defaults to 19 (even if the system date is 2001!) and nRollOver defaults to 0.

nRollOver

0 to 99

Assume when converting two-digit years that years less than nRollOver occur in nCentury plus one.

Omitted

Rollover behavior defaults to setting of zero.

nCenturySetting

0

Century is OFF for this text box.

1

Century is ON for this text box.

2

Default—display or hide century depending on the global (if no private datasession) or form-wide setting of SET CENTURY.

SET CENTURY determines whether dates and datetimes should be displayed with two-digit years (OFF) or four-digit years (ON). It is the opinion of your authors that you had better be planning (or at least let your clients think you’re planning) applications that handle dates in both the new millennium and the old one. Unless you really can’t afford the screen space, SET CENTURY ON. TextBoxes and GET fields with CENTURY set ON accept two digits in the year portion of a date and add the correct century based on the TO and optional ROLLOVER settings.

The TO and ROLLOVER settings (and the corresponding options for SET(“CENTURY”)) were introduced in VFP 5 and bear some explanation. SET CENTURY TO tells VFP which century number to assign to the date if the date is supplied with only a two-digit year, during data entry or conversion. The ROLLOVER portion allows you to split up the dates, so that those on or after a certain year fall in the century specified, and those less are assumed to be in the next century. In many cases, these two settings can alleviate the need to require four-digit dates. However, in some cases, such as the lady born in 1898 whose license next expires in 2003, a single 100-year range may not be sufficient.

VFP 7 allows you to find out the system setting for the rollover year, which is set in the Control Panel’s Regional Options dialog. SET(“CENTURY”, 3) returns this value for Windows 98, Windows 2000 and later versions. In earlier versions of Windows, the function call returns 0.

Example

SET CENTURY ON
SET CENTURY TO 19 ROLLOVER 50
? {12/7/41}  && displays 12/07/2041
? {12/7/63}  && displays 12/07/1963
? SET("CENTURY", 3) && With default settings, displays 2029
Usage
SET DATE [TO] cDateFormat
cDateFormat = SET( "DATE" )
nOrder = SET( "DATE", 1 )
TextBox.DateFormat = nFormat

Parameter

Value

Meaning

cDateFormat

AMERICAN or MDY

Month-day-year order. MARK is a slash if not overridden by SET MARK.

ANSI

Year-month-day order with the period as the default MARK.

BRITISH, FRENCH or DMY

Day-month-year order with the slash as the default MARK.

GERMAN

Day-month-year with the period as the default MARK.

ITALIAN

Day-month-year with the dash as the default MARK.

JAPAN or TAIWAN or YMD

Year-month-day with slashes as the default MARK.

LONG or SHORT

The Date format is in accordance with the long or short settings in the Windows Control Panel Regional applet. These settings override the settingsof HOURS, CENTURY, MARK and SECONDS, whether made before or after SET DATE.

USA

Month-day-year with the dash as the default MARK.

nOrder

0

MDY

1

DMY

2

YMD

nFormat

Numeric

The format to use, based on this list:
1: American
2: ANSI
3: British
4: French
5: Italian
6: German
7: Japan
8: Taiwan
9: USA
10: MDY
11: DMY
12: YMD
13: Short
14: Long

SET DATE sets the date format to a specific pattern. Remember that this format is for display purposes only and does not affect the way the date is stored or manipulated internally. However, if your code assumes it can grab the numeric day of the month by calculating VAL(SUBSTR(DTOC(DATE()),4,2)), you’re in trouble. Use DAY() instead, or an appropriate function which does not assume a DATE setting.

The SHORT and LONG options were added in VFP 5. These let the display settings used in FoxPro be controlled by the Windows Control Panel Regional applet. While we’re all in favor of empowering the end users (it usually is their machine, after all), there are practical limitations to how far we’ll customize our application to support their needs. Dynamically resizing all of our text boxes to support date entry of “09/08/43” as well as “Wednesday, September 08, 1943” is a bit too much for us.

The introduction of nFormat as a property of text boxes lets us set the display format of individual text boxes. Unfortunately, Microsoft chose to make this property a numeric value, which makes it more difficult for a developer to recognize what format is in effect. We suspect that the numeric format was chosen to make localization easier, but at a cost of more difficult maintenance. We’d like to see the numeric constants added to FOXPRO.H so that code can be written as:

txtMyDate.DateFormat = C_GERMANDATE

If you have to know the position of the various components within the date, Microsoft introduced the ,1 argument to SET(“DATE”) in VFP 5.

Usage

SET MARK TO [ cExpression ]
cMark = SET( "MARK" )
TextBox.DateMark = cMark

Note that there are two SET MARK commands: SET MARK OF turns on and off marks associated with menu bars—see SET MARK OF for that one. SET MARK TO is the one associated with dates. SET MARK TO sets the delimiter between day, month and year to a particular character. While dashes, slashes and dots are typical, all character values seem to work.

SET MARK TO is a bit curious. There is always a date delimiter in place. SET MARK TO only overrides the existing date separator (except when DATE is set to SHORT or LONG, in which case the setting of MARK is ignored). If not specified, the delimiter is the default for the SET DATE in effect. So, if you are trying to determine the delimiter currently used, you need to check both SET(“MARK”) and, if that is empty, the underlying SET(“DATE”). See the example below.

Help seems to indicate that the delimiter is changed, from dashes to slashes to dots, using SET DATE. This is only the case if a MARK has not already been SET, either explicitly or by FoxPro reading a set of defaults from the Registration Database on startup. To be certain you change both the order and the mark of the date display, you must explicitly issue a separate SET MARK TO command with no argument (see below).

Help claims that omitting cExpression resets the mark to a slash. It doesn't—it resets the mark character to the default for the current setting of DATE. If SET("DATE") = "GERMAN" and you issue the command SET MARK TO, the mark is now a dot.

Example

SET MARK TO "#"
SET DATE TO ANSI
? DATE()            && Returns date with # delimiters
SET MARK TO
? DATE()            && Returns date with ANSI "." delimiter

See Also

#Include, Configuration Files, Date(), Day(), DMY(), DoW(), GoMonth(), MDY(), Month(), Registration Database, Set Hours, Set Mark Of, Set Seconds, Set SysFormats, StrictDateEntry, Year()