【问题标题】:Java Calendar get Xº day of the week of monthJava Calendar 获取每月一周中的 Xº 天
【发布时间】:2017-05-05 17:48:12
【问题描述】:

我需要做一个返回下个月实际日期位置的方法。

for today (20/12/2016)
  I need to call this method whit today date
  The return given must to be (17/01/2016)
  This method must return the third Tuesday of the next month
  Is the 4 week of this month, but I need the Third Tuesday.

我尝试使用 Calendar.MONTH、Calendar.WEEK_OF_MONTH、Calendar.DAY_OF_WEEK,但我无法获得第三个,我总是获得第四个。

类似这样的事情:

public static Date getNextMonthDayOfWeel(Date d) {
    Calendar c = Calendar.getInstance();
    c.setTime(d);

    int week = c.get(Calendar.WEEK_OF_MONTH);
    int day = c.get(Calendar.DAY_OF_WEEK);

    //// this block
    if(!firstWeekOfMonthHad(day)){
        week++;
    }
    //// this block

    c.setFirstDayOfWeek(Calendar.SUNDAY);

    c.add(Calendar.MONTH, 1);
    c.set(Calendar.WEEK_OF_MONTH, week);
    c.set(Calendar.DAY_OF_WEEK, day);

    return c.getTime();
}

如果一个月的第一周有具体的星期几,我怎么能得到?

【问题讨论】:

  • 请向我们展示您的尝试并提供minimal reproducible example
  • 那么,是第三个星期二还是他 X 星期一。这些是不同的日期。

标签: java weekday


【解决方案1】:

如果你使用 Java 8 或更高版本,那么简单如下:

LocalDate.now()
.plusMonths(1)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.TUESDAY))
.plusWeeks(3);

【讨论】:

  • 我的项目在 java 7 =/
  • 好的,如果你添加为依赖项,joda-time 可以做同样的事情
  • @gFontaniva java.time 的大部分功能都在ThreeTen-Backport 项目中向后移植到Java 6 和7。在 ThreeTenABP 项目中进一步适配 Android。 Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time 类(或反向移植)。
【解决方案2】:

tl;博士

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )                         // Get current date in this particular time zone.
    .plusMonths( 1 )                                                 // Move to equivalent date in the month after.
    .with( 
        TemporalAdjusters.dayOfWeekInMonth​( 3 , DayOfWeek.TUESDAY )  // Move to the ordinal number occurrence of a day-of-week within this month.
    )                                                                

详情

您似乎要求下个月的第三个星期二。

Answer by Mellgren 很好,但这里使用更合适的TemporalAdjuster 来改变这个想法。

避免遗留类

您正在使用麻烦的旧日期时间类,它们现在是遗留的,被 java.time 类所取代。

LocalDate

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

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

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

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

移到下个月。

LocalDate monthLater = today.plusMonths( 1 );

TemporalAdjuster

要移到每月的第三个星期二,请使用在 TemporalAdjusters 类中找到的 TemporalAdjuster 的实现。

对于像“每月第三个星期二”或“每月第一个星期四”这样的一个月内的第一个星期,Java 提供了一个特定的调整器:TemporalAdjusters.dayOfWeekInMonth。传递序数,例如 3 代表“第三”,以及 DayOfWeek 枚举对象常量,例如 DayOfWeek.TUESDAY

TemporalAdjuster ta = TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.TUESDAY );  // Pass ordinal number and `DayOfWeek`. 
LocalDate thirdTuesdayOfNextMonth = monthLater.with( ta );

转储到控制台。

System.out.println( "today is " + today + " in zone " + z );
System.out.println( "Third Tuesday of next month is " + thirdTuesdayOfNextMonth );

看到这个code run live at IdeOne.com

今天是 2018-01-20 在美国/蒙特利尔地区

下个月的第三个星期二是 2018-02-20


关于java.time

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

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

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

从哪里获得 java.time 类?

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

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 1970-01-01
    • 2017-09-26
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多