【问题标题】:Get first date of current month in java在java中获取当前月份的第一个日期
【发布时间】:2012-12-23 21:22:51
【问题描述】:

我正在尝试获取和离开日期,ToDate 将具有上一个日期,FromDate 将具有当月的第一个日期。对于一月份,它将是1/1/2013 等等。如何正确获取当月的第一个日期?我做不到。

today.add(Calendar.DAY_OF_MONTH, -1);
java.util.Date previousDay=today.getTime();
ToDate = sdfFile1.format(newjava.sql.Date(previousDay.getTime()));
today.add(Calendar.DATE, 1);
java.util.Date nextDay=today.getTime();
FromDate = sdfFile1.format(new java.sql.Date(nextDay.getTime()));

【问题讨论】:

标签: java calendar


【解决方案1】:

试试

    Calendar c = Calendar.getInstance();   // this takes current date
    c.set(Calendar.DAY_OF_MONTH, 1);
    System.out.println(c.getTime());       // this returns java.util.Date

已更新 (Since Java 8):

import java.time.LocalDate;
LocalDate todaydate = LocalDate.now();
System.out.println("Months first date in yyyy-mm-dd: " +todaydate.withDayOfMonth(1));

【讨论】:

  • 请注意HOUR_OF_DAY、MINUTE、SECOND 和MILLISECOND 将具有它们在您创建Calendar 或Date 实例时的值。您可能希望将这些值设置为 0,例如c.set(Calendar.MINUTE, 0).
  • 另见此答案,没有时间问题:stackoverflow.com/a/37710768/1121497
【解决方案2】:

tl;博士

如何正确获取当月的第一天?

LocalDate.now()
         .with( TemporalAdjusters.firstDayOfMonth() )

或者……

LocalDate.now().withDayOfMonth( 1 )

或者……

YearMonth.now().atDay( 1 )

java.time

Java 8 及更高版本中的 java.time 框架取代了旧的 java.util.Date/.Calendar 类。旧的课程已被证明是麻烦的、令人困惑的和有缺陷的。避开他们。

java.time 框架的灵感来自高度成功的 Joda-Time 库,由 JSR 310 定义,由 ThreeTen-Extra 项目扩展,并在 Tutorial 中进行了解释。

LocalDate

对于仅日期值,没有时间,使用LocalDate 类。虽然LocalDate 没有指定时区,但我们必须指定时区才能确定日期,例如“今天”。例如,巴黎的新一天比蒙特利尔更早。

时区对于确定今天的日期至关重要。对于任何特定时刻,日期在世界各地因地区而异。省略时区意味着在确定当前日期时会自动应用 JVM 的当前时区。 JVM 中的任何代码都可以在运行时更改默认值,因此您走在流沙上。最好明确指定您想要/预期的时区,而不是隐式依赖当前默认值。

以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

在代码中,首先我们确定在特定时区看到的今天的日期。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );

然后我们将日期调整为第一天。

LocalDate firstOfCurrentMonth = today.with ( ChronoField.DAY_OF_MONTH , 1 );

或者,更简单地说:

LocalDate firstOfCurrentMonth = today.withDayOfMonth( 1 ) ;

转储到控制台。

System.out.println ( "For zoneId: " + zoneId + " today is: " + today + " and first of this month is " + firstOfCurrentMonth );

对于 zoneId:America/Montreal 今天是:2015-11-08,本月的第一天是 2015-11-01

或者,使用TemporalAdjuster。出于您的目的,您将在 TemporalAdjusters 类中找到方便的实现(注意复数 s),特别是 firstDayOfMonth。

LocalDate firstOfCurrentMonth = today.with( TemporalAdjusters.firstDayOfMonth() ) ;

ZonedDateTime

如果您需要一天中的某个时间,请记住,00:00:00.000并不总是因为夏令时 (DST) 和其他异常情况而出现在一天中的第一时刻。所以让 java.time 确定一天中第一时刻的正确时间。

ZonedDateTime zdt = firstOfCurrentMonth.atStartOfDay ( zoneId );

2015-11-01T00:00-04:00[美国/蒙特利尔]


关于java.time

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

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

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

从哪里获取 java.time 类?

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

【讨论】:

  • 我很好奇你为什么没有提到使用TemporalAdjusters.firstDayOfMonth()。
  • @DeanSchulze TemporalAdjuster 方法也很有效。如果您想要当月的结束,那么当然可以使用TemporalAdjusters.lastDayOfMonth,因为我们不会轻易地使用ChronoField.DAY_OF_MONTH 方法指定某个月份的某天数。
  • 拨打Instant.with(TemporalAdjusters.firstDayOfMonth())时收到java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfMonth
  • @tak3shi 为此使用ZonedDateTime 而不是Instant。
  • @BasilBourque 您已经有了三个正确获取当月第一个日期的示例,但也可以使用LocalDate.now().withDayOfMonth(1) 来完成。
【解决方案3】:
Calendar date = Calendar.getInstance();
date.set(Calendar.DAY_OF_MONTH, 1);

【讨论】:

    【解决方案4】:

    乔达时间

    如果我对问题的理解正确,可以使用 joda time 轻松完成

    LocalDate fromDate = new LocalDate().withDayOfMonth(1);
    LocalDate toDate = new LocalDate().minusDays(1);
    

    【讨论】:

    • 这是我的首选答案,因为它将时间设置为 0。它从每月的第一天(0:00h)到前一天(0:00h)。有时您可能想要设置toDate = new LocalDate(),使其一直持续到最后一个午夜(今天的0:00)。
    【解决方案5】:

    您可以使用 java8 中的withDayOfMonth(int dayOfMonth) 方法返回每月的第一天:

    LocalDate firstDay = LocalDate.now().withDayOfMonth(1);
    System.out.println(firstDay);   // 2019-09-01
    

    【讨论】:

      【解决方案6】:

      如果您还想将时间设置为 0,代码为:

      import java.util.*;
      import java.text.*;
      
      public class DateCalculations {
        public static void main(String[] args) {
      
          Calendar aCalendar = Calendar.getInstance();
      
          aCalendar.set(Calendar.DATE, 1);
          aCalendar.set(Calendar.HOUR_OF_DAY, 0);
          aCalendar.set(Calendar.MINUTE, 0);
          aCalendar.set(Calendar.SECOND, 0);
      
          Date firstDateOfCurrentMonth = aCalendar.getTime();
      
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zZ");
          sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
      
          String dayFirst = sdf.format(firstDateOfCurrentMonth);
          System.out.println(dayFirst);
        }
      }
      

      您可以通过以下方式轻松在线检查,而无需编译: http://www.browxy.com/

      【讨论】:

        【解决方案7】:

        像魅力一样工作!

        public static String  getCurrentMonthFirstDate(){
            Calendar c = Calendar.getInstance();   
            c.set(Calendar.DAY_OF_MONTH, 1);
            DateFormat df = new SimpleDateFormat("MM-dd-yyyy");
            //System.out.println(df.format(c.getTime())); 
            return df.format(c.getTime());
        }
        

        //更正:输出=02-01-2018

        【讨论】:

        • 02-07-2018 几乎不是本月的第一天?您正在使用的SimpleDateFormat 类不仅早已过时(如Calendar),而且出了名的麻烦。请不要教年轻人使用它。今天我们在java.time, the modern Java date and time API 的表现要好得多。
        • 正如 Ole VV 所指出的,麻烦的旧日期时间类,如 java.util.Date、java.util.Calendar 和 java.text.SimpleDateFormat 现在是 legacy,被内置的 java.time 类所取代Java 8 和 Java 9。请参阅 Tutorial by Oracle。
        • 我们中的一些人仍在使用旧版,你知道 :)
        【解决方案8】:
        import java.util.Date;
        import java.text.SimpleDateFormat;
        
        ...
        Date currentMonth = new Date();
        String yyyyMM = new SimpleDateFormat("yyyyMM").format(currentMonth);
        Date firstDateOfMonth = new SimpleDateFormat("yyyyMM").parse(yyyyMM);
        ...
        

        我的愚蠢解决方案。但这对我有用:D

        【讨论】:

        • 这很愚蠢。 (1) 使用麻烦的SimpleDateFormat 和Date 类。 (2) 不必要地格式化日期并将其解析回来。我相信它有效,但我建议不要这样做。
        【解决方案9】:

        为了得到一个日期(以后可以在 JPA 中使用),我做了

        Date startOfMonth = Date.from(LocalDate.now().withDayOfMonth(1).atStartOfDay().toInstant(ZoneOffset.UTC));
        
        • 我取当前日期 LocalDate.now()
        • 使用DayOfMonth(1) 将其移至该月的第一天
        • 在StartOfDay() 将其移至当天的sart,以摆脱小时和分钟
        • 并通过将 TimeZone 更改为具有“正确”ZoneOffset 的 Instant 来处理 TimeZone 问题。

        【讨论】:

        • 我建议您停止使用过时且容易出错的java.util date-time API。
        【解决方案10】:

        在 Java 8 中,您可以使用:

        LocalDate date = LocalDate.now(); //2020-01-12
        date.withDayOfMonth(1); //2020-01-01
        

        【讨论】:

          【解决方案11】:

          某个日期的一个月的第一天:

          public static Date firstDayOfMonth(Date d) {
              
              Calendar calendar = new GregorianCalendar();
              calendar.setTime(d);
              calendar.set(Calendar.DAY_OF_MONTH, 1);
              
              return calendar.getTime();  
          }
          

          【讨论】:

            猜你喜欢
            • 2020-01-17
            • 2021-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-14
            • 1970-01-01
            相关资源
            最近更新 更多