Java calendar.month返回星期日和#x27;月份

Java calendar.month返回星期日和#x27;月份,java,calendar,Java,Calendar,我有一个SQL数据库,它有一个year和week字段,我需要获取月份数据。当我试图找回它时,它会给我一个月后的一周,也就是月底。例如,从2019.01.28到2019.02.01周,我得到了第2个月 有什么问题 (加上信息:我也尝试了一周中的第二天) 代码如下: rs = stmt.executeQuery("SELECT * FROM " + sqlDatabase.beosztas() + " WHERE id = \'" + id + "\'");` ResultSetMe

我有一个SQL数据库,它有一个year和week字段,我需要获取月份数据。当我试图找回它时,它会给我一个月后的一周,也就是月底。例如,从2019.01.28到2019.02.01周,我得到了第2个月

有什么问题

(加上信息:我也尝试了一周中的第二天)

代码如下:

rs = stmt.executeQuery("SELECT * FROM " + sqlDatabase.beosztas() + " WHERE id = \'" + id + "\'");`
        ResultSetMetaData md = rs.getMetaData();
        while (rs.next()) {
            year = rs.getInt(2);
            week = rs.getInt(3);
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.WEEK_OF_YEAR, week);
            cal.set(Calendar.DAY_OF_WEEK, 1);
            if (count == 0) {
                month = cal.get(Calendar.MONTH) + 1;
            }
            count++;
        }

Calendar.DAY一周从星期天开始,而不是星期一。所以在你的情况下,它返回周日的月份是正常的。如果要将日期定为周一,只需使用:

cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
使用日历时要小心。Calendar.MONTH是基于0的索引,Calendar.DAY是基于1的索引

因此,您应该使用Calendar.MONDAY或Calendar.JUNE等Calendar中定义的常量,以确保您使用的月份或日期正确无误

要友好地使用日历,常量更好。 想要确定2018年2月18日的日期:

Calendar cal = Calendar.getInstance();
cal.set(2018, 2, 18); // wrong. here the date will be 2018-03-18
cal.set(2018, Calendar.FEBRUARY, 18); // correct

Calendar.DAY一周从星期天开始,而不是星期一。所以在你的情况下,它返回周日的月份是正常的。如果要将日期定为周一,只需使用:

cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
使用日历时要小心。Calendar.MONTH是基于0的索引,Calendar.DAY是基于1的索引

因此,您应该使用Calendar.MONDAY或Calendar.JUNE等Calendar中定义的常量,以确保您使用的月份或日期正确无误

要友好地使用日历,常量更好。 想要确定2018年2月18日的日期:

Calendar cal = Calendar.getInstance();
cal.set(2018, 2, 18); // wrong. here the date will be 2018-03-18
cal.set(2018, Calendar.FEBRUARY, 18); // correct

一周中的第一天
1并不表示一周中的第一天

正如javadoc for所说:

get和set的字段号,指示一周中的哪一天。此字段取值为
星期日
星期一
星期二
星期三
星期四
星期五
星期六

SUNDAY
常量的值为1,因此
DAY\u OF u WEEK
1表示星期天

要指定一周的第一天,您需要调用:

获取一周的第一天是什么;e、 例如,美国的
周日
,法国的
周一

因此:

输出

美国东部时间2019年1月27日星期日00:00:00
2019年东部时间1月28日星期一00:00:00
在这两种情况下,你都会得到一月份

第14周的产出

2019年3月31日星期日美国东部夏令时00:00:00
2019年美国东部时间4月1日星期一00:00:00

这里的区域设置很重要。

一周中的第几天
1并不意味着一周中的第一天

正如javadoc for所说:

get和set的字段号,指示一周中的哪一天。此字段取值为
星期日
星期一
星期二
星期三
星期四
星期五
星期六

SUNDAY
常量的值为1,因此
DAY\u OF u WEEK
1表示星期天

要指定一周的第一天,您需要调用:

获取一周的第一天是什么;e、 例如,美国的
周日
,法国的
周一

因此:

输出

美国东部时间2019年1月27日星期日00:00:00
2019年东部时间1月28日星期一00:00:00
在这两种情况下,你都会得到一月份

第14周的产出

2019年3月31日星期日美国东部夏令时00:00:00
2019年美国东部时间4月1日星期一00:00:00
这里的地区设置决定了您的月份。

tl;博士 2019年第5周确实包括1月和2月的天数,具体取决于您对周的定义

YearWeek.parse( "2019-W05" ).atDay( DayOfWeek.MONDAY ).toString()
2019-01-28

……还有

YearWeek.parse( "2019-W05" ).atDay( DayOfWeek.SUNDAY ).toString()
2019-02-03

你忘了解释你对一周的定义。以上使用标准。几个星期跨越几个月,甚至跨越日历年

星期? 你对一周的定义是什么?第一周从1月1日开始吗?或者这一周是从1月1日之前的某一天开始的?或者第一周是从新年开始的第一周吗?或者,根据,一周是否从周一开始,第一周包含新日历年的第一个星期四,一年包含52或53个完整的周,并且日历年的最后几天或前几天可能在下一个/前一周结束

我将在一周内假设ISO 8601。看这个

2018-W52 2018年12月24日2018年12月30日
2019-W01 2018年12月31日2019年1月6日
2019-W02 2019年1月7日2019年1月13日
2019-W03 2019年1月14日2019年1月20日
2019-W04 2019年1月21日2019年1月27日
2019-W05 2019年1月28日2019年2月3日
2019-W06 2019年2月4日2019年2月10日
避免遗留日期时间类
您使用的
Calendar
类很糟糕,是由不了解日期时间处理的复杂性和微妙性的人设计的。与Java捆绑在一起的旧日期时间类是新的遗留类,由JSR310中定义的Java.time取代

日历的诸多问题之一是,一周的定义因地区而异。您的代码忽略了区域设置这一关键问题。因此JVM当前的默认语言环境是隐式应用的。这意味着您的结果在运行时可能会有所不同。不使用此类的众多原因之一

java.time 现代解决方案包括:

  • java 8及更高版本中内置的java.time类
  • 来自图书馆的
    YearWeek
  • 将日期时间值表示为文本的标准
具有年和周字段的SQL数据库

我建议您使用单个文本字段。将标准ISO 8601格式同时用于年度和周:yyyy Www,如2010-W01。请注意,这种格式如何使字母排序也按时间顺序进行

使用类解析这些值

如果坚持将基于周的年数与周数分开,请使用此工厂方法获取
YearWeek
对象

YearWeek yearWeek = YearWeek.of( 2019 , 5 ) ;  // Pass number of the week-based-year and of the week. 
生成ISO 8601字符串

String output = yearWeek.toString() ;
LocalDate start = yearWeek.atDay( DayOfWeek.MONDAY ) ;
LocalDate stop = yearWeek.atDay( DayOfWeek.SUNDAY ) ;
String report = "Week " + yearWeek + " = " + start + "/" + stop ;