diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp
index cb17d8d5a332581fae0631070ce87832d4913351..7c7088218b5f2773038e5f80dba32b74cff02e39 100644
--- a/src/sbbs3/atcodes.cpp
+++ b/src/sbbs3/atcodes.cpp
@@ -712,7 +712,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode,
 	}
 	
 	if(strcmp(sp, "DATEFMT") == 0) {
-		return cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY";
+		return date_format(&cfg);
 	}
 
 	if(strcmp(sp, "BDATEFMT") == 0 || strcmp(sp, "BIRTHFMT") == 0) {
diff --git a/src/sbbs3/date_str.c b/src/sbbs3/date_str.c
index be4ea57087d8c4dfc99b8bd29eea6c9505aebdbb..8170c448a12cac0349a34f4eaacd51e3fca36e19 100644
--- a/src/sbbs3/date_str.c
+++ b/src/sbbs3/date_str.c
@@ -26,6 +26,20 @@ const char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 const char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
             ,"Jul","Aug","Sep","Oct","Nov","Dec"};
 
+/****************************************************************************/
+/****************************************************************************/
+const char* date_format(scfg_t* cfg)
+{
+	switch (cfg->sys_date_fmt) {
+		case DDMMYY: return "DD/MM/YY";
+		case MMDDYY: return "MM/DD/YY";
+		case YYMMDD: return "YY/MM/DD";
+	}
+	return "????????";
+}
+
+#define DECVAL(ch, mul)	(DEC_CHAR_TO_INT(ch) * (mul))
+
 /****************************************************************************/
 /* Converts a date string in format MM/DD/YY into unix time format			*/
 /****************************************************************************/
@@ -60,17 +74,23 @@ time32_t dstrtounix(scfg_t* cfg, const char *instr)
 	}
 
 	memset(&tm,0,sizeof(tm));
-	tm.tm_year=((p[6]&0xf)*10)+(p[7]&0xf);
+	if (cfg->sys_date_fmt == YYMMDD) {
+		tm.tm_year = DECVAL(p[0], 10) + DECVAL(p[1], 1);
+		tm.tm_mon = DECVAL(p[3], 10) + DECVAL(p[4], 1);
+		tm.tm_mday = DECVAL(p[6], 10) + DECVAL(p[7], 1);
+	} else {
+		tm.tm_year=((p[6]&0xf)*10)+(p[7]&0xf);
+		if(cfg->sys_date_fmt == DDMMYY) {
+			tm.tm_mon=((p[3]&0xf)*10)+(p[4]&0xf);
+			tm.tm_mday=((p[0]&0xf)*10)+(p[1]&0xf); 
+		}
+		else {
+			tm.tm_mon=((p[0]&0xf)*10)+(p[1]&0xf);
+			tm.tm_mday=((p[3]&0xf)*10)+(p[4]&0xf); 
+		}
+	}
 	if (tm.tm_year<Y2K_2DIGIT_WINDOW)
 		tm.tm_year+=100;
-	if(cfg->sys_misc&SM_EURODATE) {
-		tm.tm_mon=((p[3]&0xf)*10)+(p[4]&0xf);
-		tm.tm_mday=((p[0]&0xf)*10)+(p[1]&0xf); 
-	}
-	else {
-		tm.tm_mon=((p[0]&0xf)*10)+(p[1]&0xf);
-		tm.tm_mday=((p[3]&0xf)*10)+(p[4]&0xf); 
-	}
 	if (tm.tm_mon)
 		tm.tm_mon--;	/* zero-based month field */
 	tm.tm_isdst=-1;		/* Do not adjust for DST */
@@ -98,7 +118,10 @@ char* unixtodstr(scfg_t* cfg, time32_t t, char *str)
 		}
 		if(tm.tm_mday>31)
 			tm.tm_mday=1;
-		if(cfg->sys_misc&SM_EURODATE)
+		if (cfg->sys_date_fmt == YYMMDD)
+			sprintf(str,"%02u/%02u/%02u"
+				,TM_YEAR(tm.tm_year), tm.tm_mon+1, tm.tm_mday);
+		else if(cfg->sys_date_fmt == DDMMYY)
 			sprintf(str,"%02u/%02u/%02u",tm.tm_mday,tm.tm_mon+1
 				,TM_YEAR(tm.tm_year));
 		else
diff --git a/src/sbbs3/date_str.h b/src/sbbs3/date_str.h
index 8f43fc72ab441dd9532efa25f326a645f8e948a6..71b65d1457492cec9c6c572bbda3ba3dc6ce1c45 100644
--- a/src/sbbs3/date_str.h
+++ b/src/sbbs3/date_str.h
@@ -32,6 +32,7 @@ extern "C" {
 extern const char* wday[];	/* abbreviated weekday names */
 extern const char* mon[];	/* abbreviated month names */
 
+DLLEXPORT const char* date_format(scfg_t*);
 DLLEXPORT char *	zonestr(short zone);
 DLLEXPORT time32_t	dstrtounix(scfg_t*, const char *str);
 DLLEXPORT char *	unixtodstr(scfg_t*, time32_t, char *str);
diff --git a/src/sbbs3/newuser.cpp b/src/sbbs3/newuser.cpp
index e80e1a4f925b8c62b5e8e9c1f7e491d800440f1a..2eb1a01c5673435713fb13c0ba9be6605e491c0a 100644
--- a/src/sbbs3/newuser.cpp
+++ b/src/sbbs3/newuser.cpp
@@ -283,7 +283,7 @@ BOOL sbbs_t::newuser()
 		while((cfg.uq&UQ_BIRTH) && online && text[EnterYourBirthday][0]) {
 			bprintf(text[EnterYourBirthday], birthdate_format(&cfg));
 			format_birthdate(&cfg, useron.birth, str, sizeof(str));
-			if(gettmplt(str, "nn/nn/nnnn", K_EDIT) < 10)
+			if(gettmplt(str, cfg.sys_date_fmt == YYMMDD ? "nnnn/nn/nn" : "nn/nn/nnnn", K_EDIT) < 10)
 				continue;
 			int age = getage(&cfg, parse_birthdate(&cfg, str, tmp, sizeof(tmp)));
 			if(age >= 0 && age <= 200) { // TODO: Configurable min/max user age
diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h
index 6f6d2954837184a08d56fd1a8ff2e0d9e87ede07..fc900917cf337e6bf3c0bb3517b9c965b480fdb4 100644
--- a/src/sbbs3/sbbsdefs.h
+++ b/src/sbbs3/sbbsdefs.h
@@ -132,7 +132,7 @@
 							| UQ_REALNAME)
 
 								// Different bits in sys_misc				
-#define SM_CLOSED		(1<<0) 	// System is clsoed to New Users			
+#define SM_CLOSED		(1<<0) 	// System is closed to New Users			
 #define SM_SYSSTAT		(1<<1) 	// Sysops activity included in statistics	
 #define SM_NOSYSINFO	(1<<2) 	// Suppress system info display at logon	
 #define SM_PWEDIT		(1<<3) 	// Allow users to change their passwords	
@@ -149,7 +149,7 @@
 #define SM_AUTO_DST		(1<<14)	// Automatic Daylight Savings Toggle (US)   
 #define SM_R_SYSOP		(1<<15)	// Allow remote sysop login/commands		
 #define SM_QUOTE_EM		(1<<16)	// Allow quoting of e-mail					
-#define SM_EURODATE		(1<<17)	// European date format (DD/MM/YY)			
+#define SM_EURODATE		(1<<17)	// European date format (DD/MM/YY) - DEPRECATED
 #define SM_MILITARY		(1<<18)	// Military (24hr) time format 				
 #define SM_TIMEBANK		(1<<19)	// Allow time bank functions				
 #define SM_FILE_EM		(1<<20)	// Allow file attachments in E-mail 		
diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c
index 94e3357639f8c525346e0d754cfd229fbdd0df5d..b07cc7d8a78d2911f9519028b212306944a21679 100644
--- a/src/sbbs3/scfg/scfgsys.c
+++ b/src/sbbs3/scfg/scfgsys.c
@@ -1315,23 +1315,22 @@ int edit_sys_timefmt(int page, int total)
 int edit_sys_datefmt(int page, int total)
 {
 	int mode = WIN_SAV | WIN_MID;
-	int i = (cfg.sys_misc & SM_EURODATE) ? 1:0;
-	char* opts[3] = { "MM/DD/YY", "DD/MM/YY", NULL };
+	int i = cfg.sys_date_fmt;
+	char* opts[] = { "MM/DD/YY", "DD/MM/YY", "YY/MM/DD", NULL };
 	uifc.helpbuf=
 		"`Date Display Format:`\n"
 		"\n"
 		"If you would like abbreviated dates to be displayed in the traditional\n"
 		"U.S. date format of month first, choose `MM/DD/YY`.  If you prefer the\n"
 		"European traditional date format of day first, choose `DD/MM/YY`.\n"
+		"If you and your users would prefer year first, choose `YY/MM/DD`.\n"
 	;
 	if(page)
 		mode = wiz_help(page, total, uifc.helpbuf);
 	i=uifc.list(mode,0,10,0,&i,0
 		,"Date Display Format", opts);
-	if(i == 0)
-		cfg.sys_misc &= ~SM_EURODATE;
-	else if(i == 1)
-		cfg.sys_misc |= SM_EURODATE;
+	if(i >= 0)
+		cfg.sys_date_fmt = i;
 	return i;
 }
 
@@ -1656,6 +1655,7 @@ void sys_cfg(void)
 		snprintf(opt[i++],MAX_OPLN,"%-20s%s %s","Local Time Zone"
 			,smb_zonestr(cfg.sys_timezone,NULL)
 			,SMB_TZ_HAS_DST(cfg.sys_timezone) && cfg.sys_misc&SM_AUTO_DST ? "(Auto-DST)" : "");
+		snprintf(opt[i++],MAX_OPLN,"%-20s%s","Local Date Format", date_format(&cfg));
 		snprintf(opt[i++],MAX_OPLN,"%-20s%s","Operator",cfg.sys_op);
 
 		strcpy(opt[i++],"Notifications...");
@@ -1698,12 +1698,15 @@ void sys_cfg(void)
 				edit_sys_timezone(false, false);
 				break;
 			case 3:
-				edit_sys_operator(false, false);
+				edit_sys_datefmt(false, false);
 				break;
 			case 4:
+				edit_sys_operator(false, false);
+				break;
+			case 5:
 				cfg_notify();
 				break;
-			case 5:    /* Toggle Options */
+			case 6:    /* Toggle Options */
 				done=0;
 				while(!done) {
 					i=0;
@@ -1721,8 +1724,6 @@ void sys_cfg(void)
 						,cfg.sys_misc&SM_LISTLOC ? "Yes" : "No");
 					snprintf(opt[i++], MAX_OPLN, "%-33.33s%s","Military (24 hour) Time Format"
 						,cfg.sys_misc&SM_MILITARY ? "Yes" : "No");
-					snprintf(opt[i++], MAX_OPLN, "%-33.33s%s","European Date Format (DD/MM/YY)"
-						,cfg.sys_misc&SM_EURODATE ? "Yes" : "No");
 					snprintf(opt[i++], MAX_OPLN, "%-33.33s%s","Display Sys Info During Logon"
 						,cfg.sys_misc&SM_NOSYSINFO ? "No" : "Yes");
 					snprintf(opt[i++], MAX_OPLN, "%-33.33s%s","Display Node List During Logon"
@@ -1841,9 +1842,6 @@ void sys_cfg(void)
 							edit_sys_timefmt(false, false);
 							break;
 						case 7:
-							edit_sys_datefmt(false, false);
-							break;
-						case 8:
 							i=cfg.sys_misc&SM_NOSYSINFO ? 1:0;
 							uifc.helpbuf=
 								"`Display System Information During Logon:`\n"
@@ -1860,7 +1858,7 @@ void sys_cfg(void)
 								cfg.sys_misc|=SM_NOSYSINFO;
 							}
 							break;
-						case 9:
+						case 8:
 							i=cfg.sys_misc&SM_NONODELIST ? 1:0;
 							uifc.helpbuf=
 								"`Display Active Node List During Logon:`\n"
@@ -1880,7 +1878,7 @@ void sys_cfg(void)
 						}
 					}
 				break;
-			case 6:    /* New User Values */
+			case 7:    /* New User Values */
 				done=0;
 				while(!done) {
 					i=0;
@@ -2260,7 +2258,7 @@ void sys_cfg(void)
 						}
 					}
 				break;
-			case 7:
+			case 8:
 				uifc.helpbuf=
 					"`New User Questions/Prompts:`\n"
 					"\n"
@@ -2393,10 +2391,10 @@ void sys_cfg(void)
 					}
 				}
 				break;
-			case 8:
+			case 9:
 				security_cfg();
 				break;
-			case 9:	/* Advanced Options */
+			case 10:	/* Advanced Options */
 				done=0;
 				while(!done) {
 					i=0;
@@ -2827,7 +2825,7 @@ void sys_cfg(void)
 						}
 					}
 					break;
-			case 10: /* Loadable Modules */
+			case 11: /* Loadable Modules */
 				done=0;
 				while(!done) {
 					i=0;
diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h
index 5e66b59c9754147ca14a0a10428d46aca860d5c6..6383895d6ef6f6ed70ed611400ecffc1e54f9ff0 100644
--- a/src/sbbs3/scfgdefs.h
+++ b/src/sbbs3/scfgdefs.h
@@ -384,6 +384,8 @@ struct mqtt_cfg {
 	} tls;
 };
 
+enum date_fmt { MMDDYY, DDMMYY, YYMMDD };
+
 typedef struct
 {
 	DWORD			size;				/* sizeof(scfg_t) */
@@ -460,6 +462,7 @@ typedef struct
 	char 			sys_inetaddr[128];	/* System's internet address */
 	char 			sys_location[41];	/* System Location */
 	int16_t			sys_timezone;		/* Time Zone of BBS */
+	enum date_fmt	sys_date_fmt;
 	char 			sys_daily[LEN_CMD+1];	   /* Daily event */
 	char 			sys_logon[LEN_CMD+1];	   /* Logon event */
 	char 			sys_logout[LEN_CMD+1];	   /* Logoff event */
diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c
index 2f475eacf70fb14c8992a590e0767d7e7ccc04a2..75774bb42cfb6830dde23d50599a2158d8e9be33 100644
--- a/src/sbbs3/scfglib1.c
+++ b/src/sbbs3/scfglib1.c
@@ -102,6 +102,7 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
 
 	cfg->sys_timezone = iniGetInt16(ini, ROOT_SECTION, "timezone", 0);
 	cfg->sys_misc = iniGetUInteger(ini, ROOT_SECTION, "settings", 0);
+	cfg->sys_date_fmt = iniGetInteger(ini, ROOT_SECTION, "date_fmt", cfg->sys_misc & SM_EURODATE ? DDMMYY : MMDDYY);
 	cfg->sys_login = iniGetUInteger(ini, ROOT_SECTION, "login", 0);
 	cfg->sys_pwdays = iniGetInteger(ini, ROOT_SECTION, "pwdays", 0);
 	cfg->sys_deldays = iniGetInteger(ini, ROOT_SECTION, "deldays", 0);
diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c
index 2e4a3a794c2514358742af39aea17307ef7cfec7..47a993c9be6b7e24fe5218ecfe78afc2bb113297 100644
--- a/src/sbbs3/scfgsave.c
+++ b/src/sbbs3/scfgsave.c
@@ -122,6 +122,7 @@ BOOL write_main_cfg(scfg_t* cfg)
 	iniSetUInteger(&ini, ROOT_SECTION, "password_timeout", cfg->sys_pass_timeout, NULL);
 	iniSetInt16(&ini, ROOT_SECTION, "timezone", cfg->sys_timezone, NULL);
 	iniSetHexInt(&ini, ROOT_SECTION, "settings", cfg->sys_misc, NULL);
+	iniSetUInteger(&ini, ROOT_SECTION, "date_fmt", cfg->sys_date_fmt, NULL);
 	iniSetHexInt(&ini, ROOT_SECTION, "login", cfg->sys_login, NULL);
 	iniSetUInteger(&ini, ROOT_SECTION, "lastnode", cfg->sys_lastnode, NULL);
 	iniSetUInteger(&ini, ROOT_SECTION, "pwdays", cfg->sys_pwdays, NULL);
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index ca41ec1f26e65a50985e9b5a6c2ce4e8c6c7ccb6..be3c246ce42614cfc18a0f99f828da303368afa6 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -953,9 +953,21 @@ char* getbirthddmmyy(scfg_t* cfg, const char* birth, char* buf, size_t max)
 	return buf;
 }
 
+// Always returns string in YY/MM/DD format
+char* getbirthyymmdd(scfg_t* cfg, const char* birth, char* buf, size_t max)
+{
+	safe_snprintf(buf, max, "%02u/%02u/%02u"
+		, getbirthyear(birth) % 100
+		, getbirthmonth(cfg, birth)
+		, getbirthday(cfg, birth));
+	return buf;
+}
+
 char* getbirthdstr(scfg_t* cfg, const char* birth, char* buf, size_t max)
 {
-	if(cfg->sys_misc & SM_EURODATE)
+	if(cfg->sys_date_fmt == YYMMDD)
+		getbirthyymmdd(cfg, birth, buf, max);
+	else if(cfg->sys_date_fmt == DDMMYY)
 		getbirthddmmyy(cfg, birth, buf, max);
 	else
 		getbirthmmddyy(cfg, birth, buf, max);
@@ -991,11 +1003,13 @@ int getage(scfg_t* cfg, const char *birth)
 }
 
 /****************************************************************************/
-/* Converts from either MM/DD/YYYYY or DD/MM/YYYY to YYYYMMDD				*/
+/* Converts from MM/DD/YYYYY, DD/MM/YYYY, or YYYY/MM/DD to YYYYMMDD			*/
 /****************************************************************************/
 char* parse_birthdate(scfg_t* cfg, const char* birthdate, char* out, size_t maxlen)
 {
-	if(cfg->sys_misc & SM_EURODATE)
+	if (cfg->sys_date_fmt == YYMMDD)
+		safe_snprintf(out, maxlen, "%.4s%.2s%.2s", birthdate, birthdate + 3, birthdate + 6);
+	else if (cfg->sys_date_fmt == DDMMYY)
 		safe_snprintf(out, maxlen, "%.4s%.2s%.2s", birthdate + 6, birthdate + 3, birthdate);
 	else
 		safe_snprintf(out, maxlen, "%.4s%.2s%.2s", birthdate + 6, birthdate, birthdate + 3);
@@ -1003,7 +1017,7 @@ char* parse_birthdate(scfg_t* cfg, const char* birthdate, char* out, size_t maxl
 }
 
 /****************************************************************************/
-/* Converts from user birth date to either MM/DD/YYYYY or DD/MM/YYYY		*/
+/* Converts from user birth date to MM/DD/YYYYY, DD/MM/YYYY, or YYYY/MM/DD	*/
 /****************************************************************************/
 char* format_birthdate(scfg_t* cfg, const char* birthdate, char* out, size_t maxlen)
 {
@@ -1011,7 +1025,10 @@ char* format_birthdate(scfg_t* cfg, const char* birthdate, char* out, size_t max
 		return NULL;
 	*out = '\0';
 	if(*birthdate) {
-		if(cfg->sys_misc & SM_EURODATE)
+		if (cfg->sys_date_fmt == YYMMDD)
+			safe_snprintf(out, maxlen, "%04u/%02u/%02u"
+				, getbirthyear(birthdate), getbirthmonth(cfg, birthdate), getbirthday(cfg, birthdate));
+		else if (cfg->sys_date_fmt == DDMMYY)
 			safe_snprintf(out, maxlen, "%02u/%02u/%04u"
 				,getbirthday(cfg, birthdate), getbirthmonth(cfg, birthdate), getbirthyear(birthdate));
 		else
@@ -1023,7 +1040,12 @@ char* format_birthdate(scfg_t* cfg, const char* birthdate, char* out, size_t max
 
 const char* birthdate_format(scfg_t* cfg)
 {
-	return cfg->sys_misc&SM_EURODATE ? "DD/MM/YYYY" : "MM/DD/YYYY";
+	switch (cfg->sys_date_fmt) {
+		case MMDDYY: return "MM/DD/YYYY";
+		case DDMMYY: return "DD/MM/YYYY";
+		case YYMMDD: return "YYYY/MM/DD";
+	}
+	return "??????????";
 }
 
 /****************************************************************************/
diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h
index 6b87703db0167f277a3301fa5e9147c02736ae71..dd25df51c0fbf66d14b591a9db186d5a570d3879 100644
--- a/src/sbbs3/userdat.h
+++ b/src/sbbs3/userdat.h
@@ -65,6 +65,7 @@ DLLEXPORT int	getbirthyear(const char* birthdate);
 DLLEXPORT char* getbirthdstr(scfg_t*, const char* birthdate, char* buf, size_t);
 DLLEXPORT char* getbirthmmddyy(scfg_t*, const char* birthdate, char* buf, size_t);
 DLLEXPORT char* getbirthddmmyy(scfg_t*, const char* birthdate, char* buf, size_t);
+DLLEXPORT char* getbirthyymmdd(scfg_t*, const char* birthdate, char* buf, size_t);
 DLLEXPORT char* parse_birthdate(scfg_t*, const char* birthdate, char* out, size_t);
 DLLEXPORT char* format_birthdate(scfg_t*, const char* birthdate, char* out, size_t);
 DLLEXPORT const char* birthdate_format(scfg_t*);