将两位数年份转换为四位数年份

这是最佳实践的问题。 我有一个实用程序,以字符串forms将两位数作为年份,我需要将其转换为四位数年份作为字符串。 现在我做

//DOB's format is "MMM (D)D YY" that first digit of the day is not there for numbers 1-9 string tmpYear = rowIn.DOB.Substring(rowIn.DOB.Length - 3, 2); //-3 because it is 0 indexed if (Convert.ToInt16(tmpYear) > 50) tmpYear = String.Format("19{0}", tmpYear); else tmpYear = String.Format("20{0}", tmpYear); 

我确信我做错了,任何指针?

.NET框架有一个方法可以完全满足您的需求:

 int fourDigitYear = CultureInfo.CurrentCulture.Calendar.ToFourDigitYear(twoDigitYear) 

这样,您将正确遵循控制面板(或组策略)中定义的当前区域设置:

区域设置

鉴于现在有人在1950年之前出生,但没有人在2010年之后出生,你使用50作为翻转点似乎被打破了。

对于出生日期,您是否可以在应用程序中将翻转点设置为“现在的年份”(即10)? 即使这样,你也会遇到1911年以前出生的人的问题……

没有完美的方法可以做到这一点 – 你是凭空创造信息的。

我假设DOB =出生日期。 对于其他数据(例如,金融工具的到期日),选择可能会有所不同,但同样不完美。

一旦你把关于何时将你的世纪假设从19变为20的其他建议,所有可能的世界中最好的包括一次性更新你的数据源4年数,所以你可以停止做所有的假设时间。

您还可以使用DateTime.TryParse方法转换日期。 它使用当前文化设置来定义透视年份(在我的情况下是2029)

 DateTime resultDate; Console.WriteLine("CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax : {0}", System.Globalization.CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax); DateTime.TryParse("01/01/28", out resultDate); Console.WriteLine("Generated date with year=28 - {0}",resultDate); DateTime.TryParse("01/02/29",out resultDate); Console.WriteLine("Generated date with year=29 - {0}", resultDate); DateTime.TryParse("01/03/30", out resultDate); Console.WriteLine("Generated date with year=30 - {0}", resultDate); 

输出是:

CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax:2029

生成日期,年份为28 – 01/01/2028 00:00:00

生成日期年份= 29 – 01/02/2029 00:00:00

生成日期年份为30 – 01/03/1930 00:00:00

如果要更改行为,可以使用要作为数据透视的年份创建文化。 这个post显示了一个例子

DateTime.TryParse世纪控件C#

但正如马丁所说,如果你想管理一个超过100年的时间段,那么只有2位数就无法做到。

我认为Java有一个很好的实现:

http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#year

人们很少使用两位数代码指定未来几年。 Java实现通过假设落后80年和比当年提前20年来处理这个问题。 所以现在,30将是2030年,而31将是1931年。此外,这种实现是灵活的,随着时间的推移修改其范围,因此您不必每十年左右更改一次代码。

我刚刚测试过,Excel也使用这些相同的规则进行2位数年份转换。 1/1/29变成1/1/2029。 1/1/30变成1/1/1930。

实施

 System.Globalization.CultureInfo.CurrentCulture.Calendar.ToFourDigitYear 

 public virtual int ToFourDigitYear(int year) { if (year < 0) throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (year < 100) return (this.TwoDigitYearMax / 100 - (year > this.TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year; else return year; } 

希望这可以帮助!

检查tmpYear> currentYear%100可能更聪明。 如果是,则为19XX,否则为20XX。

出于好奇,你从哪里获得这些数据? 从forms? 在这种情况下; 我只是要求用户填写(或以某种方式选择)四位数的年份或获得用户的年龄和出生月份/日,并使用该数据来确定他们出生的年份。 这样,你根本不用担心这个问题:)

编辑:使用DateTime处理此类数据。

试试这个简单的代码

//使用date作为参数调用TextBoxDateFormat方法。

方法

 public void TextBoxDateFormat(string str1) { // Takes the current date format if MM/DD/YY or MM/DD/YYYY DateTime dt = Convert.ToDateTime(str1); //Converts the requested date into MM/DD/YYYY and assign it to textbox field TextBox = String.Format("{0:MM/dd/yyyy}", dt.ToShortDateString()); //include your validation code if required } 

有一个类似的问题,并想出了这个…… HTH!

 value = this.GetDate() if (value.Length >= 6)//ensure that the date is mmddyy { int year = 0; if (int.TryParse(value.Substring(4, 2), out year)) { int pastMillenium = int.Parse(DateTime.Now.ToString("yyyy").Substring(0, 2)) - 1; if (year > int.Parse(DateTime.Now.ToString("yy")))//if its a future year it's most likely 19XX { value = string.Format("{0}{1}{2}", value.Substring(0, 4), pastMillenium, year.ToString().PadLeft(2, '0')); } else { value = string.Format("{0}{1}{2}", value.Substring(0, 4), pastMillenium + 1, year.ToString().PadLeft(2, '0')); } } else { value = string.Empty; } } else { value = string.Empty; } 

我的答案与您的问题不符,但对于信用卡,我只添加当前年份的2位数

  private int UpconvertTwoDigitYearToFour(int yearTwoOrFour) { try { if (yearTwoOrFour.ToString().Length <= 2) { DateTime yearOnly = DateTime.ParseExact(yearTwoOrFour.ToString("D2"), "yy", null); return yearOnly.Year; } } catch { } return yearTwoOrFour; } 

如果你算一个人,他可能不会超过100年……

例如:7512​​12

 var nr = "751212"; var century = DateTime.Now.AddYears(-100).Year.ToString().Substring(0, 2); var days = (DateTime.Now - DateTime.Parse(century + nr)).Days; decimal years = days / 365.25m; if(years>=99) century = DateTime.Now.Year.ToString().Substring(0, 2); var fullnr = century+nr; 

要将2位数年份更改为4位数或更早 –

 year = year + (DateTime.Today.Year - DateTime.Today.Year%100); if (year > DateTime.Today.Year) year = year - 100; 

我们用于到期日期的解决方案,用户将MM和YY输入到单独的字段中。 这导致2月份的日期分别为31或30日,28日或29日。

 ///  /// Creates datetime for current century and sets days to end of month ///  ///  ///  ///  public static DateTime GetEndOfMonth(string MM, string YY) { // YY -> YYYY #RipVanWinkle // Gets Current century and adds YY to it. // Minus 5 to allow dates that may be expired to be entered. // eg. today is 2017, 12 = 2012 and 11 = 2111 int currentYear = DateTime.Now.Year; string thisYear = currentYear.ToString().Substring(0, 2) + YY; int month = Int32.Parse(MM); int year = Int32.Parse(thisYear); if ((currentYear - 5) > year) year += 100; return new DateTime(year, month, DateTime.DaysInMonth(year, month)); } 

我的两分钱,

鉴于年龄范围= [18,100 +],两位数年份= 90,我可以做到

current year - twoDigitsYear = 2018 - 90 = 1928 ,我得到current year - twoDigitsYear

因此19是出生年份的前两位数,28是年龄,即
年= 1990年,年龄= 28岁

但是当年龄0和100都包含在范围内时,它将不起作用,这与其他一些答案相同。

此方法可将信用卡最近两年的数字转换为四年


 private static int ToFourDigitYear(int year) { string stringYear = year.ToString("00"); if (stringYear.Length == 2) { int currentYear = DateTime.Now.Year; string firstTwoDigitsOfCurrentYear = currentYear.ToString().Substring(0, 2); year = Convert.ToInt32(firstTwoDigitsOfCurrentYear + stringYear); if (year < currentYear) year = year + 100; } return year; }