【问题标题】:Getting the first date of next month获取下个月的第一个日期
【发布时间】:2020-01-03 14:48:03
【问题描述】:

您好,我正在尝试在下面的代码中获取当前年份,但是上个月它返回的是 1970 年而不是 2020 年,这工作正常,但由于我们在 2020 年 1 月,它现在返回的是 1970 年的日期,请协助

  public String firstDateOfNextMonth(){
      DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      Calendar today = Calendar.getInstance();
      Calendar next = Calendar.getInstance();
      today.clear();
      Date date;

      next.clear();
      next.set(Calendar.YEAR, today.get(Calendar.YEAR));
      next.set(Calendar.MONTH, today.get(Calendar.MONTH)+ 1);
      next.set(Calendar.DAY_OF_MONTH, 1);


      date = next.getTime();

      Log.d(TAG, "The Date: " + dateFormat.format(date));
      return  dateFormat.format(date);

  }

【问题讨论】:

  • 假设您正在为 Android 编写代码,考虑扔掉早已过时且臭名昭著的麻烦 SimpleDateFormat 和朋友,并将 ThreeTenABP 添加到您的 Android 项目中,以便使用现代的 java.time Java 日期和时间 API。使用起来感觉好多了。

标签: java calendar date


【解决方案1】:

如果你有 Java 8 或更高版本,那么你有 java.time,你不必依赖过时的日期时间实现,你可以这样做:

public static String getFirstOfNextMonth() {
    // get a reference to today
    LocalDate today = LocalDate.now();
    // having today, 
    LocalDate firstOfNextMonth = today
            // add one to the month
            .withMonth(today.getMonthValue() + 1)
            // and take the first day of that month
            .withDayOfMonth(1);
    // then return it as formatted String
    return firstOfNextMonth.format(DateTimeFormatter.ISO_LOCAL_DATE);
}

今天(2020-01-03)调用时会打印以下内容,例如System.out.println(getFirstOfNextMonth());:

2020-02-01

如果您希望它在低于 API 级别 26 的 Android 中工作,您可能必须让 an external library, the ThreeTenAbp 参与其中。in this question 解释了它的使用。

【讨论】:

  • 它不仅短了很多,而且首先比问题中的代码更清晰。谢谢。在细节部分,我的版本可能是YearMonth.now(ZoneId.systemDefault()).plusMonths(1).atDay(1).toString(),
【解决方案2】:

不确定为什么今天的日期会被清除,请在第 4 行删除 today.clear()

【讨论】:

    【解决方案3】:

    today.clear(); 用值 0 初始化日期的所有元素 删除这条线会给你正确的答案

    【讨论】:

      【解决方案4】:

      tl;博士

      LocalDate                             // Represent a date-only value without a time-of-day and without a time zone.
      .now(                                 // Determine the current date as seen through the wall-clock time used by people in certain region (a time zone).
          ZoneId.of( "America/Montreal" )   // Real time zone names have names in the format of `Continent/Region`. Never use 2-4 letter pseudo-zones such as `IST`, `PST`, or `CST`, which are neither standardized nor unique.
      )                                     // Return a `LocalDate`.
      .with(                                // Move from one date another by passing a `TemporalAdjuster` implementation.
          TemporalAdjusters                 // Class providing several implementations of `TemporalAdjuster`.
          .firstDayOfNextMonth()            // This adjuster finds the date of the first of next month, as its name suggests.
      )                                     // Returns another `LocalDate` object. The original `LocalDate` object is unaltered.
      .toString()                           // Generate text in standard ISO 8601 format of YYYY-MM-DD.
      

      看到这个code run live at IdeOne.com。

      2020-02-01

      详情

      您正在使用糟糕的日期时间类,几年前一致通过定义 java.time 类的JSR 310 使这些类过时。

      Answer by deHaar 是正确的。这是一个更短的解决方案。

      TemporalAdjuster

      为了从一个日期移动到另一个日期,java.time 类包括TemporalAdjuster 接口。将这些对象之一传递给许多其他 java.time 类中的with 方法。

      TemporalAdjusters.firstDayOfNextMonth()

      在类TemporalAdjusters 中可以找到该接口的几个实现(注意s 的复数形式)。其中之一是firstDayOfNextMonth(),正是您所需要的。

      获取今天的日期。时区是必需的,因为对于任何给定的时刻,日期在全球范围内因时区而异。如果省略,则隐式应用 JVM 的当前默认时区。最好是明确的。

      ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
      LocalDate today = LocalDate.now( z ) ;
      

      获取您的 TemporalAdjuster 对象。

      TemporalAdjuster ta = TemporalAdjusters.firstDayOfNextMonth() ;
      

      应用该调整器以获取另一个 LocalDate 对象。请注意,java.time 类在设计上是不可变的。所以我们得到一个新对象而不是改变原来的对象。

      LocalDate firstOfNextMonth = today.with( ta ) ;
      

      如果需要,我们可以将此代码缩短为单行代码。

      LocalDate firstOfNextMonth = 
              LocalDate
              .now( 
                  ZoneId.of( "Africa/Tunis" ) 
              )
              .with(
                  TemporalAdjusters.firstDayOfNextMonth()
              )
      ;
      

      文字

      您想要的 YYYY-MM-DD 输出格式符合解析/生成文本时 java.time 类默认使用的ISO 8601 标准。所以不需要指定格式化模式。

      String output = firstOfNextMonth.toString() ;
      

      2020-02-01


      关于java.time

      java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。

      要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

      Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

      您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

      从哪里获得 java.time 类?

      ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。

      【讨论】:

        【解决方案5】:

        您正在使用 Calendar.clear(),它会清除日历的所有字段,并基本上将其还原为 1970 年 1 月 1 日(纪元时间 0)。

        删除today.clear(),你会得到正确答案

        查看更多here

        【讨论】:

          【解决方案6】:

          删除next.clear();。正如Calendar next= Calendar.getInstance(); 以当前日期开始下一步,在您的情况下为Fri Jan 03 2020 15:07:53。当您执行next.clear() 时,它会设置为初始时期。

          Epoch,也称为 Unix 时间戳,是秒数(不是 毫秒!)自 1970 年 1 月 1 日 00:00:00 GMT 以来已过去 (格林威治标准时间 1970-01-01 00:00:00)。

          【讨论】:

            猜你喜欢
            • 2012-05-29
            • 2019-03-09
            • 1970-01-01
            • 1970-01-01
            • 2013-06-23
            • 2020-01-17
            • 1970-01-01
            • 2021-03-22
            • 1970-01-01
            相关资源
            最近更新 更多