【问题标题】:Is there a good way to get the date of the coming Wednesday?有没有什么好的方法可以获取下周三的日期?
【发布时间】:2011-03-28 16:26:03
【问题描述】:

有没有什么好的方法可以获取下周三的日期? 即如果今天是星期二,我想得到这周星期三的日期;如果今天是星期三,我想得到下星期三的日期;如果今天是星期四,我想得到下周星期三的日期。

谢谢。

【问题讨论】:

    标签: java date calendar


    【解决方案1】:

    使用 java.util.Calendar。您可以像这样获得当前日期/时间:

    Calendar date = Calendar.getInstance();
    

    从那里获取date.get(Calendar.DAY_OF_WEEK) 以获取当前星期几,并将差值传递给Calendar.WEDNESDAY 并添加它。

    【讨论】:

    • 更新:这个Calendar 类现在是遗留的,被java.time.ZonedDateTime 类取代。并且不适合这个问题,LocalDate 应该在现代 Java 中使用。
    【解决方案2】:

    使用 JodaTime:

        LocalDate date = new LocalDate(System.currentTimeMillis());
        Period period = Period.fieldDifference(date, date.withDayOfWeek(DateTimeConstants.WEDNESDAY));
        int days = period.getDays();
        if (days < 1) {
            days = days + 7;
        }
        System.out.println(date.plusDays(days));
    

    【讨论】:

    【解决方案3】:

    基本算法如下:

    • 获取当前日期
    • 获取星期几
    • 找出与星期三的区别
    • 如果差值不是正数,则加 7(即坚持下一个/未来日期)
    • 添加差异

    这里有一个 sn-p 来展示如何使用 java.util.Calendar 执行此操作:

    import java.util.Calendar;
    
    public class NextWednesday {
        public static Calendar nextDayOfWeek(int dow) {
            Calendar date = Calendar.getInstance();
            int diff = dow - date.get(Calendar.DAY_OF_WEEK);
            if (diff <= 0) {
                diff += 7;
            }
            date.add(Calendar.DAY_OF_MONTH, diff);
            return date;
        }
        public static void main(String[] args) {
            System.out.printf(
                "%ta, %<tb %<te, %<tY",
                nextDayOfWeek(Calendar.WEDNESDAY)
            );
        }
    }
    

    相对于我的此时此地,上面sn-p的输出是"Wed, Aug 18, 2010"

    API 链接

    【讨论】:

    • 添加DAY_OF_YEAR 代替DAY_OF_MONTH 不安全吗?如果添加 5 天后月份不同怎么办? DAY_OF_MONTH 会处理吗?
    • 仅供参考,诸如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等非常麻烦的日期时间类现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle
    【解决方案4】:
    Calendar c= Calendar.getInstance();
    c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
    c.add(Calendar.DAY_OF_MONTH, 7);
    c.getTime();
    

    【讨论】:

    【解决方案5】:

    tl;博士

    LocalDate                        // Represent a date-only value, without time-of-day and without time zone.
    .now()                           // Capture the current date as seen in the wall-clock time used by the people of a specific region (a time zone). The JVM’s current default time zone is used here. Better to specify explicitly your desired/expected time zone by passing a `ZoneId` argument. Returns a `LocalDate` object.
    .with(                           // Generate a new `LocalDate` object based on values of the original but with some adjustment. 
        TemporalAdjusters            // A class that provides some handy pre-defined implementations of `TemporalAdjuster` (note the singular) interface.
        .next(                       // An implementation of `TemporalAdjuster` that jumps to another date on the specified day-of-week.
            DayOfWeek.WEDNESDAY      // Pass one of the seven predefined enum objects, Monday-Sunday.
        )                            // Returns an object implementing `TemporalAdjuster` interface.
    )                                // Returns a `LocalDate` object.
    

    详情

    使用Java8 Date time API,您可以轻松找到即将到来的星期三。

    LocalDate nextWed = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
    

    next(DayOfWeek dayOfWeek) - 返回下一个星期调整器,它调整日期 到日期之后指定星期几的第一次出现 正在调整中。

    假设如果你想得到上周三,那么,

    LocalDate prevWed = LocalDate.now().with(TemporalAdjusters.previous(DayOfWeek.WEDNESDAY));
    

    previous(DayOfWeek dayOfWeek) - 返回上一个星期调整器,它调整 到第一次出现指定星期几的日期之前 正在调整的日期。

    假设如果你想得到下一个或当前的星期三,那么

    LocalDate nextOrSameWed = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.WEDNESDAY));
    

    nextOrSame(DayOfWeek dayOfWeek) - 返回下一个或相同的星期几 调整器,它将日期调整为第一次出现的 在被调整的日期之后指定的星期几,除非它是 已经在那天,在这种情况下返回相同的对象。

    编辑: 您也可以通过 ZoneId 从指定时区的系统时钟中获取当前日期。

    ZoneId zoneId = ZoneId.of("UTC");
    LocalDate nextWed = LocalDate.now(zoneId).with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
    

    更多信息请参考TemporalAdjusters

    【讨论】:

    • 正确。如果您想今天加入,请致电nextOrSame
    • 我建议始终将ZoneId 传递给LocalDate.now。如果省略,则应用 JVM 当前的默认时区。最好明确指定。
    • 这正是我想要的,非常感谢
    【解决方案6】:
    public static void nextWednesday() throws ParseException 
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            int weekday = calendar.get(Calendar.DAY_OF_WEEK);
            int days = Calendar.WEDNESDAY - weekday;
            if (days < 0)
            {
                days += 7;
            }
            calendar.add(Calendar.DAY_OF_YEAR, days);
    
            System.out.println(sdf.format(calendar.getTime()));
        }
    

    【讨论】:

    • 仅供参考,诸如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等非常麻烦的日期时间类现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle
    • 您正在使用 date-with-time 类型来表示仅日期;方钉,圆孔。此外,您忽略了时区的关键问题,因此您的结果会有所不同。
    • 对于使用LocalDate 的现代解决方案,请参阅this Answer
    猜你喜欢
    • 2011-01-25
    • 2018-12-25
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2016-08-30
    • 2020-04-11
    相关资源
    最近更新 更多