代码之家  ›  专栏  ›  技术社区  ›  Baracus

需要查询日历实例以使日历设置生效

  •  0
  • Baracus  · 技术社区  · 7 年前

    我有一个日历实例,它从12月的第一天开始。我正在尝试将该日历实例设置为一年中的最后一个星期二。在设置一年中的最后一天和一周中的某一天之间,日历实例将恢复到原始时间:

    Calendar cal = ....;
    Log.d(TAG, String.format("Starting here %d-%d-%d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)));
    
    cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
    cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
    
    Log.d(TAG, String.format("Ending here %d-%d-%d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)));
    /* Other stuff */
    

    2017:

    Starting here 2017-12-1 
    Ending here 2017-11-28 
    

    2018:

    Starting here 2018-12-1 
    Ending here 2018-11-27 
    

    令人不满意的解决办法

    Calendar cal = ....;
    Log.d(TAG, String.format("Starting here %d-%d-%d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)));
    
    cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
    
    // Ask the Calendar instance for information
    long dummyValue = cal.getTimeInMillis();
    
    cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
    
    Log.d(TAG, String.format("Ending here %d-%d-%d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)));
    /* Other stuff */
    

    给我2017年和2018年的产量:

    2017:

    Starting here 2017-12-1 
    Ending here 2018-1-2 
    

    Starting here 2018-12-1
    Ending here 2019-1-1 
    

    /* Other stuff */ 这是给你的。

    0 回复  |  直到 7 年前
        1
  •  1
  •   Anonymous    7 年前

    JAVA时间和时间

        LocalDate myLocalDate = LocalDate.of(2017, Month.DECEMBER, 1);
    
        System.out.format("Starting here: %s%n", myLocalDate);
        LocalDate lastTuesdayOfYear = myLocalDate
                .with(TemporalAdjusters.lastDayOfYear())
                .with(TemporalAdjusters.previousOrSame(DayOfWeek.TUESDAY));
        System.out.format("Ending here:   %s%n", lastTuesdayOfYear);
    

    2017年产量:

    Starting here: 2017-12-01
    Ending here:   2017-12-26
    

    Starting here: 2018-12-01
    Ending here:   2018-12-25
    

    这 给你一年中的最后一个星期二。这不需要更多的东西。

    问题:我可以使用java吗。Android上的时间?

    爪哇6

    • 在Java8和更高版本以及更新的Android设备上(API级别26),现代API是内置的。
    • 在Java6和Java7中,获取三个后端口,即现代类的后端口(三个十用于JSR310;参见底部的链接)。
    • 在(较旧的)Android上使用Android版本的ThreeTen Backport。它叫ThreeTenABP。并确保从导入日期和时间类 org.threeten.bp

    这个 Calendar 课堂很混乱。在您的情况下,它的行为符合文档要求。请允许我引述:

    日历字段分辨率

    (例如1996年7月15日星期二(公历)--1996年7月15日是 实际上是星期一)。 日历

    如果日历字段值存在任何冲突, 日历 最近设置的日历字段的优先级。这个 以下是日历字段的默认组合。这个 最近的组合,由最近设置的单个 字段,将使用。

    对于日期字段:

     YEAR + MONTH + DAY_OF_MONTH
     YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
     YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
     YEAR + DAY_OF_YEAR
     YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
    

    就你而言 DAY_OF_WEEK 一周中的第二天 DAY_OF_YEAR ,您设置的另一个字段,因此 没有被使用。这就解释了你看到的行为。如果你坚持使用 日历 ,你应该可以用 cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1); 因为负值从月底开始倒数。

    然而 日历 它不仅设计拙劣、令人困惑,而且早已过时。所以考虑使用java。而是时间。

    链接