【问题标题】:Retrieve current week's Monday's date检索本周的星期一的日期
【发布时间】:2012-02-16 08:33:56
【问题描述】:

我们有一个实用程序,可以在周一至周五之间的任何一天运行。它将更新内容管理工具中的一些文件。与该文件关联的最后修改日期应该是该周的星期一日期。我编写了以下程序来检索本周的星期一日期。但我仍然不确定这是否适用于所有场景。有人有更好的解决方案吗?

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_WEEK));
int mondayNo = c.get(Calendar.DAY_OF_MONTH)-c.get(Calendar.DAY_OF_WEEK)+2;
c.set(Calendar.DAY_OF_MONTH,mondayNo);
System.out.println("Date "+c.getTime());

【问题讨论】:

  • 仅供参考,您正在使用麻烦的旧日期时间类,这些类现在已经遗留,已被 java.time 类所取代。

标签: java date calendar dayofweek


【解决方案1】:

我强烈建议您改用Joda Time(对于您所有的日期/时间工作,而不仅仅是这个):

// TODO: Consider time zones, calendars etc
LocalDate now = new LocalDate();
LocalDate monday = now.withDayOfWeek(DateTimeConstants.MONDAY);
System.out.println(monday);

请注意,由于您在这里使用了 Monday,它是 Joda 时间一周的第一天,这将始终返回更早的一天(或同一天)。如果您选择星期三(例如),那么它将从星期一或星期二提前到星期三。如果您需要“下周三”或“上周三”,您可以随时加减一周。

编辑:如果你真的想使用 java.util.Date/Calendar,你可以使用:

Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());

您可以使用Calendar.setFirstDayOfWeek 表示一周是周一-周日还是周日-周六;我相信设置星期几将保持在当前周内 - 但要测试一下。

【讨论】:

  • 仅使用 Java api 是不可能的吗?我们使用 CMS 工具,其中添加新 jar 需要更改部署。
  • @ShashankKadne:这可能,当然 - 但它可怕。如果您进行大量基于日期的工作,使用 Joda Time 的好处将远远超过短暂的成本。
  • @ShashankKadne:我已经用 java.util.Calendar 代码编辑了我的答案......但我仍然建议改用 Joda Time。
  • @jon Skeet:(+1)此代码有效!但是,如果我们选择任何一个星期天,它就会给我们下周的星期一日期,这个日期还没有到来。我们不能每次都得到前一个星期一吗?
  • 星期天不上班。它将给出下周的星期一。
【解决方案2】:

tl;博士

LocalDate previousMonday = 
    LocalDate.now( ZoneId.of( "America/Montreal" ) )
             .with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );

java.time

java.util.Calendar 类和 Joda-Time 库都已被 Java 8 及更高版本中内置的 java.time 框架所取代。见Oracle Tutorial。大部分 java.time 功能已在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。借助现代 Android 工具及其“API 脱糖”,您无需添加任何库。

java.time.LocalDate 类表示没有时间和时区的仅日期值。

确定今天的日期需要一个时区,ZoneId

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

TemporalAdjuster 接口(参见Tutorial)是一种操作日期时间值的强大而简单的方法。 TemporalAdjusters 类(注意复数)实现了一些非常有用的调整。这里我们使用previous( DayOfWeek)

方便的 DayOfWeek 枚举可以轻松指定星期几。

LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );

如果今天星期一,并且您想使用今天而不是一周前,请致电previousOrSame


关于java.time

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

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

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

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

从哪里获取 java.time 类?

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

【讨论】:

  • Java 8 可用时的最佳答案。
  • @peceps 重读第一段。可用作 Java 6、Java 7 和 Android 的后向端口。所以 java.time 是使用 Java 的最佳方法。
【解决方案3】:

以下将起作用,包括包装月份:

Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setTime(new Date());
int today = c.get(Calendar.DAY_OF_WEEK);
c.add(Calendar.DAY_OF_WEEK, -today+Calendar.MONDAY);
System.out.println("Date "+c.getTime());

但是,如果您在周日(例如 2 月 12 日周日)编辑您的申请,则日期将是下周一。根据您的要求(该应用仅在周一至周五运行),这应该不会造成问题。

【讨论】:

  • (+1) 使其适用于极端条件。但我会选择@Jon 的解决方案,因为他的代码比我的小。 ;)
  • 仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
【解决方案4】:

如果当前周星期一是前一个月,它将不起作用...例如,如果今天是 6 月 1 日星期五...您可能应该使用 roll 方法...

【讨论】:

    【解决方案5】:

    正如 Jon 建议的那样,calendar.set 方法有效... 我已经使用以下 sn-p 在同一个月的星期一和另一个月的情况下对其进行了测试:

    Calendar c = Calendar.getInstance();
    //ensure the method works within current month
    c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    System.out.println("Date " + c.getTime());
    //go to the 1st week of february, in which monday was in january
    c.set(Calendar.DAY_OF_MONTH, 1);
    System.out.println("Date " + c.getTime());
    //test that setting day_of_week to monday gives a date in january
    c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    System.out.println("Date " + c.getTime());
    //same for tuesday
    c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
    System.out.println("Date " + c.getTime());
    

    结果:

    Date Mon Feb 13 10:29:41 CET 2012
    Date Wed Feb 01 10:29:41 CET 2012
    Date Mon Jan 30 10:29:41 CET 2012
    Date Tue Jan 31 10:29:41 CET 2012
    

    【讨论】:

      【解决方案6】:

      使用Joda Time库怎么样...看看这个answer...

      【讨论】:

      • 仅使用 Java api 是不可能的吗?我们使用 CMS 工具,其中添加新 jar 需要更改部署。
      • 试试看 Joda Time source.. 也许你能找到用 Java api 实现这样一个功能的最佳方法......
      【解决方案7】:

      如果您不想使用 Joda Time,您可以这样做来查找星期 ->(适用于 Android)

      public static ArrayList<String> getWeeks(int month) {
      
      ArrayList<String> arrayListValues = new ArrayList<>();
      SimpleDateFormat sdf = new SimpleDateFormat("MMMM d");
      
      Calendar calendar = Calendar.getInstance();
      
      calendar.set(Calendar.MONTH, month);
      
      int day = calendar.get(Calendar.DAY_OF_WEEK);
      while (day != 1) {
        calendar.add(Calendar.DATE, 1);
        day = calendar.get(Calendar.DAY_OF_WEEK);
      }
      
      calendar.add(Calendar.DATE, -14);
      String y1 = sdf.format(calendar.getTime());
      calendar.add(Calendar.DATE, 6);
      String y2 = sdf.format(calendar.getTime());
      calendar.add(Calendar.DATE, 1);
      arrayListValues.add(y1 + " - " + y2);
      
       y1 = sdf.format(calendar.getTime());
      calendar.add(Calendar.DATE, 6);
       y2 = sdf.format(calendar.getTime());
      calendar.add(Calendar.DATE, 1);
      arrayListValues.add(y1 + " - " + y2);
      
      
      
      for (int i = 0; i < 10; i++) {
      
        y1 = sdf.format(calendar.getTime());
        calendar.add(Calendar.DATE, 6);
        y2 = sdf.format(calendar.getTime());
        calendar.add(Calendar.DATE, 1);
        arrayListValues.add(y1 + " - " + y2);
      }
      
      return arrayListValues;
      }
      

      【讨论】:

        【解决方案8】:

        适用于 Android 6.0 或更高版本:

        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        int day = 1, month = 7, year = 2018;
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.set(year, month, day);
        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);  //change de day to monday
        String dateMonday= sdf.format(c.getTime());
        

        对于 Android 5.1 或更低版本,它无法正常工作,我创建了自己的方法。

        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        int day = 1, month = 7, year = 2018;
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        //set the date with your date or the current date c.set(new Date());
        c.set(year, month, day);
        
        int diaSemana = c.get(Calendar.DAY_OF_WEEK);
        for (int i = 0; i < 7; i++) {
         if (diaSemana != Calendar.MONDAY) {
             day--;
             c.set(year, month, day);
             diaSemana = c.get(Calendar.DAY_OF_WEEK);
             if (diaSemana == Calendar.MONDAY) break;
          } else {
            break;
         }
        }
        String dateMonday= sdf.format(c.getTime());
        

        【讨论】:

        • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…
        • 对于 Android 版本 8 和 9(API 级别 26 及更高),java.time 是内置的,没有任何理由使用其他任何东西。对于版本 5、6 和 7,我加入 @BasilBourque 推荐 ThreeTenABP,这样您仍然可以使用 java.time。并不是这个问题专门针对 Android 提出的。
        【解决方案9】:

        Kotlin 代码。适用于较旧的 android 版本

            val c = Calendar.getInstance()
            c.time = Date()
            
            while (c.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
                c.add(Calendar.DAY_OF_WEEK, -1)
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多