【问题标题】:Getting previous particular day in a week获取一周中的前一个特定日期
【发布时间】:2013-06-18 06:03:54
【问题描述】:

我正在为我的报告页面使用 java 日期 java.util.Calendar 和 java.text.SimpleDateFormat。

我希望始终将开始日期设置为上一个星期六,将结束日期设置为该星期六之后的星期五。

我编写了一个 java 代码来检查它并按如下方式执行,但我确信它的逻辑错误

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar         cal = Calendar.getInstance();
cal.add(Calendar.DATE, -7);
setToDate(sdf.format(cal.getTime()));
cal.add(Calendar.DATE, -6);
setFromDate(sdf.format(cal.getTime()));

如何获取上一个 FromDate(yyyy-mm-dd) 和 ToDate(yyyy-mm-dd),其中 FromDate 应该是上周六,ToDate 应该是上周五。

【问题讨论】:

  • 嗯,您目前没有考虑一周中的当前天。所以想想你应该怎么做。
  • previous Saturdayprevious Friday。请定义previous
  • 请阅读我更新的问题

标签: java date calendar simpledateformat


【解决方案1】:
int daysBackToSat = cal.get(Calendar.DAY_OF_WEEK );

cal.add(Calendar.DATE, daysBackToSat*-1);
System.out.println(sdf.format(cal.getTime()));

在第 1 行中,您会得到一个表示当前星期几的数字。星期天是 1,星期六是 7,星期五是 6,等等。所以说如果今天是星期三,你会得到 4。因为星期六是 7 并且 tehre 不是“第 0 天”,所以你从当前日期减去 4 天(第 2 行)。为了在星期六之后获得下一个星期五,您只需添加 6 天。

编辑:考虑到我看到的您的更新,如果是星期三,您不想在此之前有星期六,而是提前 1 周。如果已经是星期六,您将只返回 1 周。 在这种情况下,您检查“daysBackToSat”是否为 7,然后保持原样,如果小于 7,则再添加一个 7。

        if(daysBackToSat<7) {
            daysBackToSat += 7;
        }

【讨论】:

  • 2013年,你应该更清楚!当 JodaTime 已经存在时,没有任何理由使用 DateCalendar
【解决方案2】:

我试过这段代码,它似乎工作:

// Get milliseconds of 1 day
long millisecOneDay = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);

// Get actual date
Date today = new Date();

// 0 Sunday, 1 Monday...
int day = today.getDay(); // It use a deprecated method

// Previous saturday
long millisecPrevSat = today.getTime() - (day + 1) * millisecOneDay;

// Previous friday
long millisecNextFri = millisecPrevSat + (6 * millisecOneDay);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

// setToDate(sdf.format(new Date(millisecPrevSat)));
System.out.println("PREV SAT: " + sdf.format(new Date(millisecPrevSat)));

// setFromDate(sdf.format(new Date(millisecNextFri)));
System.out.println("NEXT FRID: " + sdf.format(new Date(millisecNextFri)));

您可以检查今天是否是星期五,并将两个日期再向后移动 7 天。

【讨论】:

  • 除非正确处理时区,否则不应使用毫秒。否则它将在夏令时更改时失败。
【解决方案3】:

我最近开发了Lamma Date,非常适合服务于这个用例。

    Date today = new Date(2014, 7, 1);

    Date to = today.previous(DayOfWeek.FRIDAY);  // Date(2014,6,27)
    Date from = to.previous(DayOfWeek.SATURDAY); // Date(2014,6,21)

【讨论】:

    【解决方案4】:

    我相信这个问题以及公认的答案很可能导致story in TheDailyWTF

    正如那篇文章正确指出的那样,Java 的 DateCalendar 类型是遗留笑话,最好避免。正确的解决方案是使用 Joda Time 或其继任者,Java 8 及更高版本 (Tutorial) 中内置的 java.time 框架:

    date.withDayOfWeek(DateTimeConstants.SATURDAY)
    

    另外...SimpleDateFormat 是整个标准库中线程安全性最低的类之一,是一场等待发生的灾难!

    【讨论】:

      【解决方案5】:

      java.time

      使用 Java 8 及更高版本中内置的 java.time 框架,这项工作变得更加容易和直接。大部分 java.time 功能已在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。

      请参阅Oracle Tutorial 了解更多信息。

      时间调节器

      使用Temporal AdjusterLocalDate 操作到另一个LocalDate 实例中。 TemporalAdjusters 类(注意复数)为您的目的提供预定义的调整器,利用方便的 DayOfWeek 枚举:

      时区

      请注意,时区对于确定当前日期至关重要。你的问题忽略了这个问题。对于任何给定的时刻,全球不同时区的日期。例如,在巴黎午夜过后几分钟是新的一天,而在蒙特利尔仍然是“昨天”。

      如果省略,则隐式应用 JVM 当前的默认时区。此默认值可以随时更改运行时(!),因此最好明确指定预期/期望的时区。

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

      前一个星期六,然后是星期五

      接下来我们得到上一个星期六。如果今天星期六,你的问题没有提到该怎么做。此代码使用previous,但您的业务规则可能需要previousOrSame,由您决定。

      LocalDate previousSaturday = localDate.with( TemporalAdjusters.previous( DayOfWeek.SATURDAY ) ) ;
      

      下一个要求是获得上一个星期六之后的星期五。我们可以在星期五之前添加天数,但是既然我们知道了时间调整器,为什么还要费心计算呢?

      LocalDate fridayFollowingPreviousSaturday = previousSaturday.with( TemporalAdjusters.next( DayOfWeek.FRIDAY ) ) ; 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-14
        • 1970-01-01
        • 2017-09-16
        • 2021-12-05
        • 1970-01-01
        • 1970-01-01
        • 2016-05-23
        • 1970-01-01
        相关资源
        最近更新 更多