diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp index 86977bb6c59ec9ac2fd7c6accb5adfe71723f145..e2cce3a4d1e68017fd268f6ff970b4da266d4766 100644 --- a/src/sbbs3/atcodes.cpp +++ b/src/sbbs3/atcodes.cpp @@ -758,7 +758,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, return(smb_zonestr(sys_timezone(&cfg),str)); if(!strcmp(sp,"DATE") || !strcmp(sp,"SYSDATE")) { - return(unixtodstr(&cfg,time32(NULL),str)); + return datestr(time(NULL)); } if(strncmp(sp, "DATE:", 5) == 0 || strncmp(sp, "TIME:", 5) == 0) { @@ -1113,7 +1113,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, } if(strcmp(sp, "PWDATE") == 0 || strcmp(sp, "MEMO") == 0) - return(unixtodstr(&cfg,useron.pwmod,str)); + return datestr(useron.pwmod); if(strncmp(sp, "PWDATE:", 7) == 0) { SAFECOPY(tmp, sp + 7); @@ -1131,7 +1131,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, } if(!strcmp(sp,"SINCE")) - return(unixtodstr(&cfg,useron.firston,str)); + return datestr(useron.firston); if(strncmp(sp, "SINCE:", 6) == 0) { SAFECOPY(tmp, sp + 6); @@ -1205,7 +1205,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, return(timestr(useron.laston)); if(!strcmp(sp,"LASTDATEON")) - return(unixtodstr(&cfg,useron.laston,str)); + return datestr(useron.laston); if(strncmp(sp, "LASTON:", 7) == 0) { SAFECOPY(tmp, sp + 7); @@ -1235,7 +1235,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, return(timestr(useron.firston)); if(!strcmp(sp,"FIRSTDATEON")) - return(unixtodstr(&cfg,useron.firston,str)); + return datestr(useron.firston); if(strncmp(sp, "FIRSTON:", 8) == 0) { SAFECOPY(tmp, sp + 8); @@ -1413,7 +1413,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, } if(!strcmp(sp,"LASTNEW")) - return(unixtodstr(&cfg,(time32_t)ns_time,str)); + return datestr(ns_time); if(strncmp(sp, "LASTNEW:", 8) == 0) { SAFECOPY(tmp, sp + 8); @@ -1483,7 +1483,7 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, } if(!strcmp(sp,"EXDATE") || !strcmp(sp,"EXPDATE")) - return(unixtodstr(&cfg,useron.expire,str)); + return datestr(useron.expire); if(strncmp(sp, "EXPDATE:", 8) == 0) { if(!useron.expire) diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp index e5349109c6e60260f2a1861ecb0b9d1d4d657af2..4f248339965e20b387a252a076b83888e607bb4f 100644 --- a/src/sbbs3/con_out.cpp +++ b/src/sbbs3/con_out.cpp @@ -1121,7 +1121,6 @@ void sbbs_t::getdimensions() /****************************************************************************/ void sbbs_t::ctrl_a(char x) { - char tmp1[128]; uint atr = curatr; struct tm tm; @@ -1219,7 +1218,7 @@ void sbbs_t::ctrl_a(char x) break; case 'D': /* Date */ now=time(NULL); - bputs(unixtodstr(&cfg,(time32_t)now,tmp1)); + bputs(datestr(now)); break; case ',': /* Delay 1/10 sec */ mswait(100); diff --git a/src/sbbs3/date_str.c b/src/sbbs3/date_str.c index 2e0f82951a2546023765a4b1212cf2d6db369a8e..db6a6830c6fb262854c181b14bdba54833077154 100644 --- a/src/sbbs3/date_str.c +++ b/src/sbbs3/date_str.c @@ -148,6 +148,33 @@ char* unixtodstr(scfg_t* cfg, time32_t t, char *str) return str; } +/****************************************************************************/ +/****************************************************************************/ +char* datestr(scfg_t* cfg, time_t t, char* str) +{ + if(t == 0) + return "---------"; + if(!cfg->sys_date_verbal) + return unixtodstr(cfg, (time32_t)t, str); + struct tm tm = {}; + if(localtime_r(&t, &tm) == NULL) + return "!!!!!!!!!"; + char fmt[32] = ""; + switch(cfg->sys_date_fmt) { + case MMDDYY: + snprintf(fmt, sizeof fmt, "%%b%%d%c%%y", cfg->sys_date_sep); + break; + case DDMMYY: + snprintf(fmt, sizeof fmt, "%%d%c%%b%%y", cfg->sys_date_sep); + break; + case YYMMDD: + snprintf(fmt, sizeof fmt, "%%y%c%%b%%d", cfg->sys_date_sep); + break; + } + strftime(str, 9, fmt, &tm); + return str; +} + /****************************************************************************/ /* Takes the value 'sec' and makes a string the format HH:MM:SS */ /****************************************************************************/ diff --git a/src/sbbs3/date_str.h b/src/sbbs3/date_str.h index ad87b45b6dc4ca422d0ded7ae86b83e7e7348157..3d070f2ce4835fc273fa986bf1258b99cda7f2a0 100644 --- a/src/sbbs3/date_str.h +++ b/src/sbbs3/date_str.h @@ -37,6 +37,7 @@ DLLEXPORT char * date_template(scfg_t*, char* buf, size_t); DLLEXPORT char * zonestr(short zone); DLLEXPORT time32_t dstrtounix(scfg_t*, const char *str); DLLEXPORT char * unixtodstr(scfg_t*, time32_t, char *str); +DLLEXPORT char * datestr(scfg_t*, time_t, char* str); DLLEXPORT char * sectostr(uint sec, char *str); DLLEXPORT char * seconds_to_str(uint, char*); DLLEXPORT char * hhmmtostr(scfg_t* cfg, struct tm* tm, char* str); diff --git a/src/sbbs3/execmisc.cpp b/src/sbbs3/execmisc.cpp index f7310cca1921fb51535ad1f192730a9b4833d4af..7e1d0119cdc0ae337cbc0fb243094d74dde4d04b 100644 --- a/src/sbbs3/execmisc.cpp +++ b/src/sbbs3/execmisc.cpp @@ -567,7 +567,7 @@ int sbbs_t::exec_misc(csi_t* csi, const char *path) lp=getintvar(csi,*(int32_t *)csi->ip); csi->ip+=4; /* Skip int variable name */ if(pp && lp) { - unixtodstr(&cfg,*lp,str); + datestr(*lp, str); *pp=copystrvar(csi,*pp,str); } return(0); diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index 3da154443381c0c8a657d41209e0a3ce90db946c..a6a611de6d9256b7752e8aa0c7f783e1e548a425 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -2228,7 +2228,7 @@ js_html_encode(JSContext *cx, uintN argc, jsval *arglist) case 'D': now=time(NULL); - j+=sprintf(outbuf+j,"%s",unixtodstr(p->cfg,(time32_t)now,tmp1)); + j+=sprintf(outbuf+j,"%s",datestr(p->cfg,now,tmp1)); break; case 'T': now=time(NULL); diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c index d0dadb5f3ee3ad49708bd3db3edaa424d3be27f2..ab9eecb0fccc69921f6276aebb14894f40f98c20 100644 --- a/src/sbbs3/js_system.c +++ b/src/sbbs3/js_system.c @@ -1292,7 +1292,7 @@ js_datestr(JSContext *cx, uintN argc, jsval *arglist) } JS_ValueToECMAUint32(cx,argv[0],(uint32_t*)&t); } - unixtodstr(sys->cfg,t,str); + datestr(sys->cfg,t,str); if((js_str = JS_NewStringCopyZ(cx, str))==NULL) return(JS_FALSE); diff --git a/src/sbbs3/putnode.cpp b/src/sbbs3/putnode.cpp index 1f905eba57af5822d1255cae9363d40fe931ac7e..333dcea0a1eb6cb3e4be6059c76f8a1d7f372504 100644 --- a/src/sbbs3/putnode.cpp +++ b/src/sbbs3/putnode.cpp @@ -28,7 +28,7 @@ /****************************************************************************/ int sbbs_t::putnodedat(uint number, node_t* node) { - char str[256],firston[25]; + char str[256]; char path[MAX_PATH+1]; int wr=0; int wrerr=0; @@ -54,7 +54,7 @@ int sbbs_t::putnodedat(uint number, node_t* node) ,useron.sex ,useron.comp ,useron.ipaddr - ,unixtodstr(&cfg,useron.firston,firston) + ,datestr(useron.firston) ,node->aux&0xff ,node->connection ); diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp index 7d3e6a7e8b827ac74c6ecf02ead5ad80114a7f79..4a03eb1d04357105291069bd9500969ec9b231fa 100644 --- a/src/sbbs3/readmsgs.cpp +++ b/src/sbbs3/readmsgs.cpp @@ -343,7 +343,6 @@ static int find_post(smb_t* smb, uint32_t msgnum, post_t* post) void sbbs_t::show_thread(uint32_t msgnum, post_t* post, unsigned curmsg, int thread_depth, uint64_t reply_mask) { - char date[32]; smbmsg_t msg; int i = find_post(&smb, msgnum, post); @@ -373,7 +372,7 @@ void sbbs_t::show_thread(uint32_t msgnum, post_t* post, unsigned curmsg, int thr ? text[Anonymous] : msghdr_field(&msg, msg.from) ,(unsigned)i == curmsg ? '<' : ' ' ,msg_listing_flag(smb.subnum, &msg, &post[i]) - ,unixtodstr(&cfg, msg.hdr.when_written.time, date)); + ,datestr(msg.hdr.when_written.time)); if(thread_depth) { if(msg.hdr.thread_first) diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 85d2e26f4ca44bf012807c591e49252bedc07f91..7266d7920a37b13acb2f5e4192d42fc3419b408a 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -822,7 +822,7 @@ public: void revert_text(void); char* server_host_name(void); char* timestr(time_t); - char* datestr(time_t); + char* datestr(time_t, char* str = nullptr); char timestr_output[60]{}; char datestr_output[60]{}; char* age_of_posted_item(char* buf, size_t max, time_t); diff --git a/src/sbbs3/scfg/scfg.c b/src/sbbs3/scfg/scfg.c index e409353647d274ea89df80f4da9bf5dc485fb2a0..7831e1398c74fa4b5a21344573cb12aaaba0fa90 100644 --- a/src/sbbs3/scfg/scfg.c +++ b/src/sbbs3/scfg/scfg.c @@ -199,7 +199,7 @@ void cfg_wizard(void) } int stage = 0; - int total = 16; + int total = 17; scfg_t saved_cfg = cfg; do { switch(stage) { @@ -292,6 +292,12 @@ void cfg_wizard(void) continue; } break; + case __COUNTER__: + if(edit_sys_date_verbal(stage, total) < 0) { + --stage; + continue; + } + break; case __COUNTER__: if(edit_sys_newuser_policy(stage, total) < 0) { --stage; diff --git a/src/sbbs3/scfg/scfg.h b/src/sbbs3/scfg/scfg.h index d88894127bea6334369afc02ede0657393f1da42..bf45bcffd6a9ec3b264f7a6f33add44975690afe 100644 --- a/src/sbbs3/scfg/scfg.h +++ b/src/sbbs3/scfg/scfg.h @@ -154,6 +154,7 @@ int edit_sys_inetaddr(int page, int total); int edit_sys_timezone(int page, int total); int edit_sys_timefmt(int page, int total); int edit_sys_datefmt(int page, int total); +int edit_sys_date_verbal(int page, int total); int edit_sys_newuser_policy(int page, int total); int edit_sys_alias_policy(int page, int total); int edit_sys_delmsg_policy(int page, int total); diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c index 11877491f26fcda96deddcbb7bc6a399e4074028..cbdb7d36f8eab1e5a96beb5dea4393c37788acc3 100644 --- a/src/sbbs3/scfg/scfgsys.c +++ b/src/sbbs3/scfg/scfgsys.c @@ -465,7 +465,7 @@ int edit_sys_newuser_policy(int page, int total) ; if(page) mode = wiz_help(page, total, uifc.helpbuf); - i=uifc.list(mode,0,10,0,&i,0 + i=uifc.list(mode,0,11,0,&i,0 ,"Open to New Users",uifcYesNoOpts); if(i == 0) { cfg.sys_misc &= ~SM_CLOSED; @@ -1329,7 +1329,7 @@ int edit_sys_datefmt(int page, int total) "MM DD YY", "DD MM YY", "YY MM DD", NULL }; uifc.helpbuf= - "`Date Display Format:`\n" + "`Numeric Date 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" @@ -1344,7 +1344,7 @@ int edit_sys_datefmt(int page, int total) uifc.list_height = 7; } i=uifc.list(mode, 0, 11, 0,&i,0 - ,"Date Display Format", opts); + ,"Numeric Date Format", opts); if (i < 0) return i; cfg.sys_date_fmt = i % 3; @@ -1359,6 +1359,32 @@ int edit_sys_datefmt(int page, int total) return i; } +int edit_sys_date_verbal(int page, int total) +{ + int mode = WIN_SAV | WIN_MID; + int i = cfg.sys_date_verbal; + char* opts[] = { + "Numeric", "Verbal", + NULL }; + uifc.helpbuf= + "`Short Date Display Format:`\n" + "\n" + "If you would like abbreviated dates to be displayed using verbal\n" + "(non-numeric, unambiguous) month name abbreviations, choose `Verbal`."; + ; + if(page) { + mode = wiz_help(page, total, uifc.helpbuf); + mode |= WIN_FIXEDHEIGHT; + uifc.list_height = 2; + } + i=uifc.list(mode, 0, 11, 0,&i,0 + ,"Short Date Display Format", opts); + if (i < 0) + return i; + cfg.sys_date_verbal = i; + return i; +} + int edit_sys_alias_policy(int page, int total) { int mode = WIN_SAV | WIN_MID; @@ -1669,6 +1695,7 @@ void sys_cfg(void) static int uq_cur, uq_bar; static int newtog_cur, newtog_bar; char str[81],done=0; + char dstr[9]; int i,j; scfg_t saved_cfg = cfg; char sys_pass[sizeof(cfg.sys_pass)]; @@ -1680,7 +1707,9 @@ 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, str, sizeof str)); + snprintf(opt[i++],MAX_OPLN,"%-20s%s (e.g. %s)","Short Date Format" + ,date_format(&cfg, str, sizeof str) + ,datestr(&cfg, time(NULL), dstr)); snprintf(opt[i++],MAX_OPLN,"%-20s%s","Operator",cfg.sys_op); strcpy(opt[i++],"Notifications..."); @@ -1723,7 +1752,8 @@ void sys_cfg(void) edit_sys_timezone(false, false); break; case 3: - edit_sys_datefmt(false, false); + if(edit_sys_datefmt(false, false) >= 0) + edit_sys_date_verbal(false, false); break; case 4: edit_sys_operator(false, false); diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index 0f7e90da3ba39ed3469c1effaec55296021d5087..2f7316078a3daf07b26524f3fa5e16c7c97fd743 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -464,6 +464,7 @@ typedef struct int16_t sys_timezone; /* Time Zone of BBS */ enum date_fmt sys_date_fmt; char sys_date_sep; + bool sys_date_verbal; 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 90f724f6f10a2e4d46014433ebc3549766697889..56ca69705cde99529e73ae5c1288cc4f5152e794 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -104,6 +104,7 @@ bool read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) 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_date_sep = *iniGetString(ini, NULL, "date_sep", "/", value); + cfg->sys_date_verbal = iniGetBool(ini, NULL, "date_verbal", false); 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 1541e7e482a21140600b600e37be772e814c6082..8830a928169a99033c43e489faa3ea598de2f146 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -125,6 +125,7 @@ bool write_main_cfg(scfg_t* cfg) iniSetUInteger(&ini, ROOT_SECTION, "date_fmt", cfg->sys_date_fmt, NULL); SAFEPRINTF(tmp, "%c", cfg->sys_date_sep); iniSetString(&ini, ROOT_SECTION, "date_sep", tmp, NULL); + iniSetBool(&ini, ROOT_SECTION, "date_verbal", cfg->sys_date_verbal, 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/str.cpp b/src/sbbs3/str.cpp index be469aad49114b757a586b0cbecd1e3555f8785e..b690d61313747a44056526e11f47cc57ec6662dd 100644 --- a/src/sbbs3/str.cpp +++ b/src/sbbs3/str.cpp @@ -217,14 +217,14 @@ void sbbs_t::userlist(int mode) sprintf(name,"%s #%d",user.alias,i); sprintf(line[j],text[UserListFmt],name ,cfg.sys_misc&SM_LISTLOC ? user.location : user.note - ,unixtodstr(&cfg,user.laston,tmp) + ,datestr(user.laston,tmp) ,user.modem); } else { sprintf(name,"%s #%u",user.alias,i); bprintf(text[UserListFmt],name ,cfg.sys_misc&SM_LISTLOC ? user.location : user.note - ,unixtodstr(&cfg,user.laston,tmp) + ,datestr(user.laston,tmp) ,user.modem); } j++; @@ -976,9 +976,11 @@ char* sbbs_t::timestr(time_t intime) return(::timestr(&cfg,(time32_t)intime,timestr_output)); } -char* sbbs_t::datestr(time_t t) +char* sbbs_t::datestr(time_t t, char* str) { - return unixtodstr(&cfg, (time32_t)t, datestr_output); + if(str == nullptr) + str = datestr_output; + return ::datestr(&cfg, t, str); } void sbbs_t::sys_info() @@ -1030,9 +1032,9 @@ void sbbs_t::user_info() if(localtime32(&useron.laston,&tm)!=NULL) bprintf(text[UserDates] - ,unixtodstr(&cfg,useron.firston,str) - ,unixtodstr(&cfg,useron.expire,tmp) - ,unixtodstr(&cfg,useron.laston,tmp2) + ,datestr(useron.firston,str) + ,datestr(useron.expire,tmp) + ,datestr(useron.laston,tmp2) ,tm.tm_hour,tm.tm_min); bprintf(text[UserTimes] diff --git a/src/sbbs3/upload.cpp b/src/sbbs3/upload.cpp index 00034462de64d4633b79d5b7c700049ad7c7f81c..3a4ca228e4ad1739af7b34bcd6f2679dc9dbf9c9 100644 --- a/src/sbbs3/upload.cpp +++ b/src/sbbs3/upload.cpp @@ -358,7 +358,7 @@ bool sbbs_t::upload(int dirnum, const char* fname) now=time(NULL); if(descbeg[0]) strcat(descbeg," "); - SAFEPRINTF(str,"%s ",unixtodstr(&cfg,(time32_t)now,tmp)); + SAFEPRINTF(str,"%s ",datestr(now,tmp)); strcat(descbeg,str); } if(cfg.dir[dirnum]->misc&DIR_MULT) { diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp index 4f1db5534d5f4aced583217407bb775cdc31c44a..fbd368b00913b07ecca95421ec5d17be56a25faa 100644 --- a/src/sbbs3/useredit.cpp +++ b/src/sbbs3/useredit.cpp @@ -87,7 +87,7 @@ void sbbs_t::useredit(int usernumber) SAFEPRINTF2(user_pass, "%.*s..", (int)(max_len - 2), user.pass); bprintf(text[UeditAliasPassword] ,user.alias - ,unixtodstr(&cfg,user.pwmod,tmp) + ,datestr(user.pwmod,tmp) ,(user.level>useron.level || !(cfg.sys_misc&SM_ECHO_PW)) ? "<hidden>" : user_pass ); bprintf(text[UeditRealNamePhone] @@ -115,8 +115,8 @@ void sbbs_t::useredit(int usernumber) if(localtime32(&user.laston,&tm)==NULL) return; bprintf(text[UserDates] - ,unixtodstr(&cfg,user.firston,str),unixtodstr(&cfg,user.expire,tmp) - ,unixtodstr(&cfg,user.laston,tmp2),tm.tm_hour, tm.tm_min); + ,datestr(user.firston,str),datestr(user.expire,tmp) + ,datestr(user.laston,tmp2),tm.tm_hour, tm.tm_min); bprintf(text[UserTimes] ,user.timeon,user.ttoday,cfg.level_timeperday[user.level] @@ -341,28 +341,28 @@ void sbbs_t::useredit(int usernumber) break; case 'K': /* date changes */ bputs(text[UeditLastOn]); - unixtodstr(&cfg,user.laston,str); + datestr(user.laston,str); gettmplt(str, date_template(&cfg, tmp, sizeof tmp),K_LINE|K_EDIT); if(sys_status&SS_ABORT) break; user.laston=dstrtounix(&cfg,str); putuserdatetime(user.number, USER_LASTON, user.laston); bputs(text[UeditFirstOn]); - unixtodstr(&cfg,user.firston,str); + datestr(user.firston,str); gettmplt(str, date_template(&cfg, tmp, sizeof tmp),K_LINE|K_EDIT); if(sys_status&SS_ABORT) break; user.firston=dstrtounix(&cfg,str); putuserdatetime(user.number, USER_FIRSTON, user.firston); bputs(text[UeditExpire]); - unixtodstr(&cfg,user.expire,str); + datestr(user.expire,str); gettmplt(str, date_template(&cfg, tmp, sizeof tmp),K_LINE|K_EDIT); if(sys_status&SS_ABORT) break; user.expire=dstrtounix(&cfg,str); putuserdatetime(user.number, USER_EXPIRE, user.expire); bputs(text[UeditPwModDate]); - unixtodstr(&cfg,user.pwmod,str); + datestr(user.pwmod,str); gettmplt(str, date_template(&cfg, tmp, sizeof tmp),K_LINE|K_EDIT); if(sys_status&SS_ABORT) break;