【问题标题】:Same day prevous year (previous year, same week and day of week)上一年的同一天(上一年、同一周和星期几)
【发布时间】:2019-11-11 09:40:52
【问题描述】:

我想检索前一年的同一天。

例如今天是2019-03-30,即 2019 年,第 26 周(一年中的一周),第 7 天(一周中的一天)。

我需要构造LocalDate,即 2018 年第 26 周(一年中的一周)、第 7 天(一周中的一天)。

我无法从java.time 包中找到可以像这样构建LocalDate 的包。

【问题讨论】:

  • 请具体说明您期望的结果日期。即 2018 年是星期几 27 日是 7 的日期。
  • 2019-03-30 不是第 27 周
  • 是的,它是 26。我提取错误的方式:LocalDateTime.now().get(WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear())我已经更新了问题
  • 你假设哪个周计划?美国周,ISO(国际)周,还有什么?
  • 您说过“例如,今天是 2019 年 3 月 30 日,即 2019 年,第 26 周(一年中的一周),第 7 天(一周中的一天)”您是说 2019- 06-30?

标签: java date dayofweek week-number localdate


【解决方案1】:

如果您正在寻找与 ISO 周-年兼容的函数,这对我有用 - 到目前为止 =]。

public class FiscalDateUtil {
    
    private static Logger log = LoggerFactory.getLogger(FiscalDateUtil.class);

    static public LocalDate previousYearComparisonDate(LocalDate date) {
    
        final int weekYear = date.get(IsoFields.WEEK_BASED_YEAR);
        final int weekLastYear = weekYear-1;
        
        final DayOfWeek dayOfWeek = date.getDayOfWeek();
        final int weekOfYear = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
        final LocalDate adjustedLastYear = date
                .with(IsoFields.WEEK_BASED_YEAR, weekLastYear)
                .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekOfYear)
                .with(TemporalAdjusters.nextOrSame(dayOfWeek));

        if (log.isTraceEnabled()) {
            log.trace("starting date {}", date.toString());
            log.trace("starting date dow {}", date.getDayOfWeek());
            log.trace("lastYear {}", weekLastYear);
            log.trace("lastYear dow {}", dayOfWeek);
            log.trace("adjustedLastYear {}", adjustedLastYear.toString());
            log.trace("adjustedLastYear dow {}", adjustedLastYear.getDayOfWeek());  
        }
        return adjustedLastYear;
    }

}

【讨论】:

    【解决方案2】:

    我相信其他答案很接近,但还没有完全到位。据我了解,您想使用默认语言环境的周方案,其他答案不这样做。我的建议是:

        WeekFields wf = WeekFields.of(Locale.getDefault());
        LocalDate today = LocalDate.now(ZoneId.of("Africa/Casablanca"));
        int week = today.get(wf.weekOfYear());
        int dow = today.get(wf.dayOfWeek());
        System.out.println("Today is " + today + ", "
                + today.getDayOfWeek() + " of week " + week);
    
        LocalDate correspondingDayLastYear = today.minusYears(1)
                .with(wf.weekOfYear(), week)
                .with(wf.dayOfWeek(), dow);
        System.out.println("Last year was " + correspondingDayLastYear + ", "
                + correspondingDayLastYear.getDayOfWeek()
                + " of week " + correspondingDayLastYear.get(wf.weekOfYear()));
    

    刚才在我的电脑上运行时,输出是:

    Today is 2019-06-30, SUNDAY of week 26
    Last year was 2018-07-01, SUNDAY of week 26
    

    当我将语言环境设置为 US 时,我得到相同的日期,但周数不同,因为美国周的定义不同:

    Today is 2019-06-30, SUNDAY of week 27
    Last year was 2018-07-01, SUNDAY of week 27
    

    我相信也会有不同地区给出不同日期的情况。

    wf.dayOfWeek() 为您提供一个字段,该字段根据该特定语言环境中一周的第一天从 1 到 7 对天进行编号。重要的是不要只使用withDayOfWeek 或等效项,否则如果不使用 ISO 周,您将面临滑入不同周的风险。

    我的答案仍然不会总是有效!如果今天在一年的第 53 周内,很可能去年没有第 53 周。对此我们无能为力。另一个我们无法解决的问题:在美国周中,第 1 周从 1 月 1 日开始。如果这是星期天,则这是该周的第一天,但​​上一年的第 1 周从周五或周六开始,所以周1 没有星期天。

    【讨论】:

      【解决方案3】:

      您似乎希望上一年的日期与给定日期的年份和星期几相同。下面的代码会给你这个结果。

      LocalDate currentLocalDate = LocalDate.now();
      int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
      int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
      LocalDate resultLocalDate = currentLocalDate
          .minusYears(1)
          .with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
          .with(ChronoField.DAY_OF_WEEK, dayOfWeek);
      

      完整示例 (live copy):

      import java.time.*;
      import java.time.format.*;
      import java.time.temporal.*;
      
      class Example
      {
          private static void showDateInfo(LocalDate ld) {
              int weekOfYear = ld.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
              int dayOfWeek = ld.getDayOfWeek().getValue();
              System.out.println(ld.format(DateTimeFormatter.ISO_LOCAL_DATE) + " is week " + weekOfYear + ", day " + dayOfWeek);
          }
          public static void main (String[] args) throws java.lang.Exception
          {
              LocalDate currentLocalDate = LocalDate.of(2019, 6, 30);
              showDateInfo(currentLocalDate);
              int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
              int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
              LocalDate resultLocalDate = currentLocalDate
                  .minusYears(1)
                  .with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
                  .with(ChronoField.DAY_OF_WEEK, dayOfWeek);
              showDateInfo(resultLocalDate);
          }
      }
      

      输出:

      2019-06-30 是第 26 周第 7 天 2018-07-01 是第 26 周第 7 天

      【讨论】:

      • 很好地使用java.time bravo
      • 干得好。我认为没有要求一年中对齐周?
      • 抱歉打扰。使用2006-07-08 和你的代码我得到2006-07-08 is week 27, day 6,然后是2005-07-09 is week 28, day 6。它滑入了第 28 周而不是第 27 周。我还有其他惊喜示例。
      【解决方案4】:

      您可以将当前日期的年初以来的天数添加到前一年的年初。

      这应该可以解决问题:

      String dateStr = "2019-03-30";
      LocalDate date = LocalDate.parse(dateStr);
      LocalDate newDate = LocalDate.parse(date.getYear() + "-01-01").plusDays(date.getDayOfYear());
      System.out.println(newDate);
      

      【讨论】:

      • 有比单纯的字符串操作更好的方法。
      • 这是一个计算而不是字符串操作。使用字符串是为了创建日期
      • Year.from( LocalDate.parse( "2019-03-30" ) ).atDay( 1 )
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多