4

我的问题看起来非常简单。我从一个 GregorianCalendar 对象制作了一个日历图形用户界面,并使用它的方法来计算不同月份的正确天数,以及不同日期对应的工作日。

但是平日是一致的一天休息。日历声称 2013 年 7 月 1 日是“2”,在我所在的地区,这意味着星期二。星期一应该是“1”。“简单的!” 我想,然后输入:c.setFirstDayOfWeek(Calendar.MONDAY); 但没有给出任何反应。

所以我在stackoverflow上搜索答案,但每个有我问题的人似乎都忘记了1月是0,而不是1。我没有。所以现在我被卡住了。

作为一个简化的代码,我做了一个非常短的代码片段,它有相应的输出:

    GregorianCalendar c = new GregorianCalendar();
    c.setFirstDayOfWeek(Calendar.MONDAY);
    c.set(Calendar.MONTH, 6);
    c.set(Calendar.DAY_OF_MONTH, 1);
    c.set(Calendar.YEAR, 2013);

    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-YYYY");
    System.out.println(sdf.format(c.getTime()));
    System.out.println(c.get(Calendar.DAY_OF_WEEK));

输出是:

01-07-2013

2

我拒绝在我的代码中输入“-1”,以错误地纠正明显错误的症状。帮助表示赞赏。

4

5 回答 5

13

是的,Java 中的日期处理是有问题的......

  • 月份从 0(一月)开始
  • 一周中的天数从SUNDAY1SATURDAY到 7 开始(Ideone fiddle
  • c.setFirstDayOfWeek(Calendar.MONDAY); 与名字所暗示的有点不同

    一个月或一年的第一周定义为从 getFirstDayOfWeek() 开始并至少包含该月或该年的 getMinimalDaysInFirstWeek() 天的最早 7 天时间段

您可以通过始终使用 Calendar 类中定义的常量来摆脱麻烦,甚至不尝试从这些常量的数字表示或Calendar.get(int)方法返回的结果中推断出任何含义......

于 2013-10-02T11:59:13.647 回答
11

我拒绝在我的代码中输入“-1”,以错误地纠正明显错误的症状。

错误是您的假设Calendar.get(Calendar.DAY_OF_WEEK)是本地化的。它不是。星期几和数字之间的映射是固定的;如果需要,用于Calendar.getFirstDayOfWeek()确定人类对“一周的第一天”的理解;如果您真的想向用户显示“2”,我会感到惊讶……您肯定想向他们显示星期几的名称。

任何涉及一周开始的计算getFirstDayOfWeek都应该使用。

于 2013-10-02T12:00:08.087 回答
2

java.time

java.util日期时间 API 及其格式化 API已SimpleDateFormat过时且容易出错。建议完全停止使用它们并切换到现代 Date-Time API *

一周的第一天Locale取决于

演示:

import java.time.format.TextStyle;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // ############## First day of week ##############
        System.out.println(WeekFields.of(Locale.UK).getFirstDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        System.out.println(WeekFields.of(Locale.US).getFirstDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
    }
}

输出:

Monday
Sunday

ONLINE DEMO

如何获得星期几?

import java.time.LocalDate;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2013, Month.JULY, 1);
        System.out.println(date);

        // ############ Day of week ############
        System.out.println(date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        // Alternatively,
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE", Locale.ENGLISH);
        System.out.println(date.format(dtf));
    }
}

我在欧洲/伦敦时区的系统上的输出:

2013-07-01
Monday
Monday

ONLINE DEMO

Trail: Date Time了解有关现代日期时间 API *的更多信息。

您的代码和期望出了什么问题?

  • 你的期望出了问题的是你假设c.get(Calendar.DAY_OF_WEEK)会给你一周的第一天,而它返回代表 MONDAY 的值,因为它是 2013 年 7 月 1 日的星期一。

  • 您的代码有问题的是使用Y( Week year ) 而不是y( Year )。检查此讨论以了解有关此差异的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

于 2021-08-14T16:48:49.147 回答
2

java.time

我建议您使用现代 Java 日期和时间 API java.time 进行日期工作。Arvind Kumar Avinash 已经在一个答案中展示了它的一个很好的应用(+1)。

我理解您的问题的方式是您希望星期一成为一周的第一天,并且您想知道某个日期是一周中的哪一天(例如,2013 年 7 月 1 日)。星期一 = 1,星期二 = 2,依此类推,直到星期日 = 7。

    LocalDate ld = LocalDate.of(2013, Month.JULY, 1);
    
    // Monday is first day of week; which number day of the week is ld then?
    int numberDayOfTheWeek = ld.get(WeekFields.ISO.dayOfWeek()); // 1 through 7
    System.out.println(numberDayOfTheWeek);

输出是:

1

将星期一作为一周的第一天符合 ISO 8601(日期和时间的国际标准)。所以内置WeekFields.ISO使用这个编号。WeekFields.ISO.dayOfWeek()给了我们一个TemporalField,然后我们用它来查询LocalDate对象的星期几。

而不是WeekFields.ISO我们可以使用WeekFields.of(DayOfWeek.MONDAY, 1)来指定星期一是一周的第一天。的第二个参数of()是从 1 到 7 的第一周(一年或一个月)中的最小天数,我们在这里不使用它,所以我们使用哪个数字并不重要。

关联

于 2021-08-14T18:27:22.010 回答
1

这是Java中的警告之一,

DAY_OF_WEEK,

此字段采用 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY 值。

当您的程序打印 2 时,它告诉您星期几是星期一。这个常数值与一周的开始无关。如果一周的第一天是星期天,它恰好与一周中的某一天相同 - 但如果一周的第一天被重新定义,它不会改变。

于 2013-10-02T12:00:06.123 回答