【问题标题】:Convert a two digit year to a four digit year将两位数年份转换为四位数年份
【发布时间】:2011-01-02 17:10:00
【问题描述】:

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

//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);

我确定我做错了,有什么建议吗?

【问题讨论】:

  • 我认为你应该在 19-- 和 20-- 之间随机选择。没有人从 Y2K 中学到不要使用 2 位数的年份吗?
  • 一些客户太自以为是了要求使用两位数的年份。
  • 数据库中还有其他日期信息可以提供帮助吗?年龄?最后一次去看兽医?最新图片?活着?死亡?希望您可以推动更新数据库。

标签: c# string date


【解决方案1】:
 int fYear = Convert.ToInt32(txtYear.Value.ToString().Substring(2, 2));

【讨论】:

    【解决方案2】:

    基于上述解决方案,这是我的,我在使用java时在android中使用

    以两位数格式获取当前年份,然后检查是否输入 年份长度等于 2,如果是,则获取当前年份和从 今年它拆分了世纪的前两位数,然后添加了这个 世纪与年份用户输入。使其成为 4 位数的年份。

    public static int getConvertedYearFromTwoToFourDigits(String year) {
            if (year.length() == 2) {
                int currentYear = Calendar.getInstance().get(Calendar.YEAR);
                String firstTwoDigitsOfCurrentYear = String.valueOf(currentYear).substring(0, 2);
                year = firstTwoDigitsOfCurrentYear + year;
            }
            return Integer.parseInt(year);
        }
    

    【讨论】:

      【解决方案3】:

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


      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;
      }
      

      【讨论】:

      • 欢迎来到 SO!不鼓励仅使用代码的答案,因为它们没有提供有关如何解决手头问题的任何见解。请更新您的解决方案以解释您的代码如何解决 OP 的问题 :)
      【解决方案4】:

      我的两分钱,

      给定一个年龄范围=[18, 100+],两位数年份=90,我可以做到

      current year - twoDigitsYear = 2018 - 90 = 1928,我得到了 19、28

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

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

      【讨论】:

        【解决方案5】:

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

        /// <summary>
        /// Creates datetime for current century and sets days to end of month
        /// </summary>
        /// <param name="MM"></param>
        /// <param name="YY"></param>
        /// <returns></returns>
        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));
        }
        

        【讨论】:

          【解决方案6】:

          将 2 位数年份更改为 4 位数当前或更早 -

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

          【讨论】:

            【解决方案7】:

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

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

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

            【讨论】:

            • 是否存在影响 2 到 4 位数年份转换的区域差异?
            • 或 System.Globalization.CultureInfo.CurrentCulture 或 CultureInfo.CurrentUICulture 或 CultureInfo.DefaultThreadCurrentCulture 等
            • 我在当前的一些代码上遇到了这个问题。使用泰国文化设置,就是2000年,存储为00,在佛教时代被解释为3100,或者在系统中被解释为3100-543=2557!非常令人困惑的错误,直到您意识到发生了什么。
            • @Sinaesthetic 没有情节转折;它按照区域设置中的定义工作。
            • 如果我使用CultureInfo.InvariantCulture 执行此操作,范围会永远固定为 1930-2029,还是会随着时间的推移而调整?
            【解决方案8】:

            如果你计算一个人,他可能不会超过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;
            

            【讨论】:

              【解决方案9】:

              实现

              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;
              }
              

              希望这会有所帮助!

              【讨论】:

              • 您还应该展示 TwoDigitYearMax 是如何填写的。
              【解决方案10】:

              我的回答与您的问题不符,但对于信用卡,我只需添加当前年份的 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;
                  }
              

              【讨论】:

              • 异常:字符串未被识别为有效的日期时间。
              【解决方案11】:

              遇到了类似的问题,想出了这个……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;
              }
              

              【讨论】:

                【解决方案12】:

                试试这个简单的代码

                //调用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
                
                }
                

                【讨论】:

                  【解决方案13】:

                  您还可以使用 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 的生成日期

                  如果您想改变行为,您可以创建一种文化,并以您想使用的年份为轴心。该线程显示了一个示例

                  DateTime.TryParse century control C#

                  但正如马丁所说,如果你想管理一个跨越 100 年以上的时间段,只有 2 位数字是没有办法的。

                  【讨论】:

                  • 仅供参考,在控制面板中设置了 TwoDigitYearMax。在区域和语言选项下。
                  【解决方案14】:

                  我认为 Java 对此有很好的实现:

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

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

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

                  【讨论】:

                  • JFYI,6 年后,Excel 和 Google 电子表格仍然使用 30 作为分水岭年,所以虽然 Java 可能有浮动窗口,但 Excel 和 GS 可能没有那么智能。
                  • @ChrisB 好吧,Excel 的原始实现并不是那么聪明,现在出于兼容性原因,他们都坚持这些规则:)
                  【解决方案15】:

                  出于好奇,您从哪里获得这些数据?从表格?在这种情况下;我会简单地要求用户用四位数填写(或以某种方式选择)年份,或者获取用户的年龄和出生月份/日期,并使用该数据来确定他们出生的年份。这样你就完全不用担心这个问题了:)

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

                  【讨论】:

                  • 如果你问一只狗它的出生年份,你不想等到它一直吠到 2003 年! 3 快速 yaps 更有效...
                  【解决方案16】:

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

                  对于出生日期,您能否在您的应用中将翻转点设置为“现在的年份”(即 10 年)?即便如此,1911 年之前出生的人也会有问题……

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

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

                  【讨论】:

                  • 你对 DOB 的看法是对的,但它们是针对动物而非人类的,它们的寿命最多为 40 年。但是您使用移动目标是对的。我现在将使用if (Convert.ToInt16(String.Format("20{0}", tmpYear[2])) &gt; DateTime.Today.Year + 3) // Causes Y2.1K problem, but I will be retired by then.
                  • 像动物一样Logan's Run 嗯?有了一个移动的阈值年,并且没有 100 年以上的寿命,你应该没问题。我显然假设了人类。您可以通过使 Century 部分也源自 Today 来解决 Y2K1 问题...
                  【解决方案17】:

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

                  【讨论】:

                    猜你喜欢
                    • 2010-12-11
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-07-27
                    • 2016-05-26
                    • 1970-01-01
                    相关资源
                    最近更新 更多