【问题标题】:java: Convert a string which represents a two digit year to four digitsjava:将表示两位数年份的字符串转换为四位数
【发布时间】:2016-05-26 12:57:29
【问题描述】:

这个问题已经被问过很多次了,但我有一个问题,我觉得这是一个独特的问题。

来了。

我有一个代表两位数年份的字符串,即写 2016 我输入 16

我需要将两位数年份转换为四位数年份,即 16 变为 2016。

在经历了一些问题和答案后,我得出了以下发现

解决方案 1

DateFormat sdfp = new SimpleDateFormat("dd.mm.yy");
Date d = sdfp.parse(input);
DateFormat sdff = new SimpleDateFormat("yyyy-MM-dd");
String date = sdff.format(d);

这很好,但在我的情况下,我没有一个月或一天,只有一年,我无法找到一种方法来创建仅包含年份的日期对象。

解决方案 2

上述问题可以用Calendar 对象解决,但它不允许在其年份字段中输入两位数年份的an。

编辑 忘了提到我不能使用 Joda-Time,因为我在 Android 平台上工作,它会增加我的项目的大小,只是为了这个小用途

【问题讨论】:

  • 如果您需要专门使用日期对象,我相信只有一年的短日期格式。如果没有,你可以让它默认为任何值,然后总是只在年份的短字符串中显示它。

标签: java android simpledateformat


【解决方案1】:

为什么不从格式中删除月份和日期的部分?

DateFormat sdfp = new SimpleDateFormat("yy");
Date d = sdfp.parse(input);
DateFormat sdff = new SimpleDateFormat("yyyy");
String date = sdff.format(d);

LIVE

Here 是关于SimpleDateFormat 如何解释缩写年份的规则。 (我加粗)

对于使用缩写年份模式(“y”或“yy”)进行解析,SimpleDateFormat 必须解释相对于某个世纪的缩写年份。它通过将日期调整为 SimpleDateFormat 实例创建时间之前的 80 年和之后的 20 年内来实现这一点。例如,使用“MM/dd/yy”模式和 1997 年 1 月 1 日创建的 SimpleDateFormat 实例,字符串“01/11/12”将被解释为 2012 年 1 月 11 日,而字符串“05/ 04/64" 将被解释为 1964 年 5 月 4 日。

【讨论】:

  • 事实证明 OP 计划使用代码超过一百年,我不认为这个解决方案是“可扩展的”它会在短时间内工作,但当它会需要处理旧数据(-20 年),这对于可以运行 80 多年的应用程序来说是有意义的,但它不会按预期工作
  • 这意味着它将给我们最多 2036,然后跳转到 1937 以获取 37 作为输入字符串。输入“100”怎么样?
  • @Scitech,不,那将是一个相对好的案例,因为你会知道会发生什么。但是根据黄色段落,这取决于 SimpleDateFormat 对象的创建时间......所以你真的什么都不知道
  • @Gavriel 对! SimpleDateFormat 的任何替代品。
  • @Gavriel Android 可能在 80 年后都不存在了。
【解决方案2】:

我认为这要简单得多:

String year = "20" + input;

但是,如果您想让用户的生活更轻松,并假设他正在输入一张有效的卡,那么这个问题很简单:如果他输入 2 位数字,则添加 (thisYear/100)。如果这似乎是过去的过去,那么如果它是过去的 90 多年,那么再加上 100(这只会在任何世纪的最后十年出现)

Date now = new Date();
int expYear = (int)(now.getYear()/100) + parseInt(input);
if (expYear < now.getYear() && expYear+90<now.getYear()) {
    expYear += 100;
}

【讨论】:

  • 是的,这是解决方案,但应用程序将在 2100 年中断:D
  • 当然会。但是,您将如何尝试用两位数表示 2116 年而不会将其与 2016 年混淆?
  • 这就是为什么现在没有理智的程序员会接受两位数的年份。
  • @ErsenOsmanm 如果您计划您的应用在 2100 年之后工作,那么请不要使用 2 位数字!!!!!!!
  • 我认为这是一个足够的解决方案,因为它适用于 Android 应用程序。到 2100 年,现在编写的任何 Android 应用程序都不会继续使用。要么 Android 已经进化,要么应用程序已经更新(如果不是功能,则用于设计),或者被新技术取代。
【解决方案3】:
  public static int adjustOneOrTwoDigitYearInput(int year) {
    return adjustOneOrTwoDigitYearInput(year, Year.now().getValue());
  }

  public static int adjustOneOrTwoDigitYearInput(int inputYear, int referenceYear) {
    if(inputYear > 99) {
      return inputYear;
    }

    int currentCentury = referenceYear / 100 * 100;
    int currentCenturyYear = currentCentury + inputYear;
    int upperLimit = referenceYear + 20;
    int lowerLimit = referenceYear - 79;

    // initially place it in current century
    int adjusted = currentCenturyYear;

    if(adjusted> upperLimit) {
      // shift a century down
      adjusted -= 100;
    }
    else if(adjusted < lowerLimit) {
      // shift a century up
      adjusted += 100;
    }

    return adjusted;
  }

一些测试:

  @Test
  public void test_adjustOneOrTwoDigitYearInput()
  {
    assertEquals(2017, adjustOneOrTwoDigitYearInput(17, 2017));
    assertEquals(2037, adjustOneOrTwoDigitYearInput(37, 2017)); // +20
    assertEquals(1938, adjustOneOrTwoDigitYearInput(38, 2017)); // +21
    assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 2017)); // 0
    assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 2017)); // 99

    assertEquals(2078, adjustOneOrTwoDigitYearInput(78, 2078)); 
    assertEquals(2098, adjustOneOrTwoDigitYearInput(98, 2078)); // + 20
    assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 2078)); // + 21 / 99
    assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 2078)); // 0

    assertEquals(1990, adjustOneOrTwoDigitYearInput(90, 1990));
    assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 1990)); // 99
    assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 1990)); // 0
    assertEquals(2010, adjustOneOrTwoDigitYearInput(10, 1990)); // +20
    assertEquals(1911, adjustOneOrTwoDigitYearInput(11, 1990)); // +21
  }

【讨论】:

    【解决方案4】:

    如果您使用的是 java 8,则可以使用 java.time 中的 Year:

    Year year = Year.parse("18", DateTimeFormatter.ofPattern("yy"));
    year.toString(); //This returns 2018
    

    【讨论】:

      【解决方案5】:

      你也可以试试这样的:

      String input = "16";
      String str = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)).substring(0, 2)+input;
      System.out.println("str = " + str);
      

      结果:

      str = 2016
      

      【讨论】:

        【解决方案6】:

        一个相当简单的。礼貌加夫里尔

         String year = "20" + input;
        if(input>99)
        {
        String year= "2"+input;
        }
        

        【讨论】:

        • 哎呀! 16 作为输入可能会与 2016 和 2116 混淆。世纪问题
        猜你喜欢
        • 2011-01-02
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多