C#中DateTime月份小于10时格式化显示异常求助
我正在尝试将日、月、年传入DateTime对象,但当月份值小于10时,打印月份会出现问题。我的代码中存在一个初始日期,通过算术运算计算清洁月(mesLimpeza)和通知月(mesNotifica),同时处理了月份最后一天为30或31的情况,以及2月的特殊情况。在最后一行,我尝试将日期以yyyy-MM-dd格式显示在textBox中。模拟初始日、月、年时,当结果月份大于等于10时一切正常,但月份小于10时会出现异常。我注意到月份格式不接受不带前置零的小于10的数字(如"6"),必须改为"06"才能得到正确格式。我使用的是Visual Studio中的C#,请问该如何解决这个问题?
我的代码:
int day = (int)DateTime.Now.Day; int month = (int)DateTime.Now.Month; int year = (int)DateTime.Now.Year; int diaLimpeza, mesLimpeza, anoLimpeza; int diaNotifica, mesNotifica, anoNotifica; public void mes6() { DateTime dataInicial = new DateTime(); DateTime dataLimpeza = new DateTime(); DateTime dataNotifica = new DateTime(); day = 31; month = 12; year = 2019; mesLimpeza= month + 6; if (mesLimpeza > 12) { mesLimpeza = mesLimpeza - 12; anoLimpeza = year + 1; diaLimpeza = day; } else { mesLimpeza = month + 6; anoLimpeza = year; diaLimpeza = day; } int soma = diaLimpeza + 2; diaNotifica = soma; if (mesLimpeza == 01 || mesLimpeza == 03 || mesLimpeza == 05 || mesLimpeza == 07 || mesLimpeza == 08 || mesLimpeza == 10) //mesLimpeza == 12 excepçao { if (diaLimpeza == 30 || diaLimpeza == 31) { diaNotifica = diaNotifica - 31; mesNotifica = mesLimpeza + 1; anoNotifica = anoLimpeza; //int a = diaNotifica; } else if ((diaLimpeza == 30 || diaLimpeza == 31) && mesLimpeza == 12) { diaNotifica = diaNotifica - 31; mesNotifica = (mesLimpeza + 1) - 12; anoNotifica = anoLimpeza + 1; } else { diaNotifica = diaLimpeza + 2; mesNotifica = mesLimpeza; anoNotifica = anoLimpeza; } } else if (mesLimpeza == 04 || mesLimpeza == 06 || mesLimpeza == 09 || mesLimpeza == 11) { if (diaLimpeza == 29 || diaLimpeza == 30) { diaNotifica = diaLimpeza - 30; mesNotifica = mesLimpeza + 1; anoNotifica = anoLimpeza; } else { diaNotifica = diaLimpeza + 2; mesNotifica = mesLimpeza; anoNotifica = anoLimpeza; } } else if (mesLimpeza == 02) { if (anoLimpeza % 4 == 0) { if (diaLimpeza == 28 || diaLimpeza == 29) { diaNotifica = diaLimpeza - 29; mesNotifica = mesLimpeza + 1; anoNotifica = anoLimpeza; } } else { if (diaLimpeza == 27 || diaLimpeza == 28) { diaNotifica = diaLimpeza - 28; mesNotifica = mesLimpeza + 1; anoNotifica = anoLimpeza; } else { diaNotifica = diaLimpeza + 2; mesNotifica = mesLimpeza; anoNotifica = anoLimpeza; } } } dataLimpeza = new DateTime(anoLimpeza, mesLimpeza, diaLimpeza); textBoxData.Text = dataLimpeza.ToShortDateString(); }
解决方案
其实你完全不用纠结手动给月份补零的问题,问题的核心出在日期的格式化输出上,而不是DateTime对象本身的存储。
快速解决格式问题
你当前用的ToShortDateString()会跟随系统的区域设置生成日期字符串,没办法保证固定的yyyy-MM-dd格式。只要把最后一行的代码改成下面这样,就能直接输出带前置零的月份:
textBoxData.Text = dataLimpeza.ToString("yyyy-MM-dd");
ToString()方法接受自定义格式字符串,其中MM代表两位数字的月份(1-9会自动补零变成01-09),dd是两位数字的日期,yyyy是四位数字的年份,这样不管你的月份数值是6还是12,输出都会符合你想要的格式。
简化日期计算逻辑(额外建议)
看你的代码里手动处理了很多日期加减、月份进位、不同月份天数的判断,其实C#的DateTime已经内置了这些功能,能帮你省去大量冗余代码:
public void mes6() { // 直接创建初始日期对象 DateTime initialDate = new DateTime(2019, 12, 31); // 计算6个月后的清洁日期,自动处理跨年、月份天数差异 DateTime dataLimpeza = initialDate.AddMonths(6); // 计算通知日期(清洁日期加2天),自动处理跨月情况 DateTime dataNotifica = dataLimpeza.AddDays(2); // 格式化输出到文本框 textBoxData.Text = dataLimpeza.ToString("yyyy-MM-dd"); }
用AddMonths()和AddDays()方法,系统会自动处理闰年2月、30/31天月份的跨月逻辑,比手动写判断要可靠得多,代码也简洁很多。
补充说明
DateTime的构造函数接受的月份参数是1-12的整数,整数本身不存在前导零的概念(比如06在代码里就是6),所以你手动计算出来的月份数值不管是6还是12,传入构造函数都是没问题的,问题只出在显示时的格式化步骤,所以用自定义格式字符串就能完美解决你的问题。
内容的提问来源于stack exchange,提问作者Joelson26

