我正在尝试确定一周的哪一天是该月的第一天,但出于某种原因,它并没有让我回到正确的一周。
以下是我的代码:
CalendarMonth[] months = CalendarUtils.constructMonthViewArray(new GregorianCalendar());
public static CalendarMonth[] constructMonthViewArray(Calendar cal) {
CalendarMonth[] months = new CalendarMonth[CALENDAR_GRID_SIZE];
int year = cal.get(cal.YEAR);
int month = cal.get(cal.MONTH);;
// calculate how many days in the month
int numOfDays = getNumOfDaysInMonth(cal);
// calculate what day(mon-sunday) is the 1st of the month
int firstDayOfMonth = getFirstDayOfMonth(cal);
private static int getFirstDayOfMonth(Calendar cal) {
int firstDay = cal.get(Calendar.DAY_OF_WEEK);
Log.d(TAG, "");
// decrement it because our array deals with values 0-6(indexes)
firstDay--;
if (firstDay == 0) {
firstDay = 6;
} else {
// decrement again so that the days start from 0.
firstDay--;
}
return firstDay;
}
来自“int firstDay = cal.get(Calendar.DAY_OF_WEEK);”的行没有给我正确的一周中的每一天,并返回值2,以获得本月的第一天(2011年1月),当月的第一天是星期六(7)。
我错过了什么吗?我已经调试并检查了cal变量设置的月份,年份和日期,它确实表明今天的日期已更正,但是当我得到星期几时它没有得到值7。
答案 0 :(得分:11)
我无法重现您所看到的问题。正如迈克尔所说,有很多代码没有向我们展示,但Calendar.getDayOfWeek绝对有效:
import java.util.*;
public class Test {
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar();
calendar.set(2011, 0, 1); // 0 = January
System.out.println(calendar.get(Calendar.DAY_OF_WEEK)); // Prints 7
}
}
您是否忘记java.util.Calendar
中的月份是0?
如果您可以制作类似的简短但完整的节目,以显示一周的错误日期,请发布。
你在firstDay
内递减getFirstDayOfMonth
两次的事实似乎有点奇怪,以及它并没有真正反映方法名称的事实(正如迈克尔所说)。
最后,我不断推荐Java日期/时间处理:如果您可能使用Joda Time而不是java.util.Calendar
,请执行此操作。这是一个更好,更好的API。
答案 1 :(得分:0)
getFirstDayOfMonth()的代码似乎没有按照方法名称的说明去做 - 但要真正理解发生了什么,我们需要查看所涉及的所有代码,尤其是日历初始化的方式和getNumOfDaysInMonth的代码()
要记住的一件事:根据getFirstDayOfWeek()
答案 2 :(得分:0)
从可怕的遗留类(Calendar
,GregorianCalendar
等)转换为现代 java.time 类(ZonedDateTime
,LocalDate
,等等。)。然后获取星期几的对象,并要求它自动本地化当天的那一天的名称。
(GregorianCalendar) myJavaUtilCalendar // Cast your `Calendar` to `GregorianCalendar` assuming it actually is one.
.toZonedDateTime() // Convert from legacy class to modern class.
.toLocalDate() // Extract date-only object, without time-of-day and without time zone.
.with( // Adjust to another date by calling `TemporalAdjuster` implementation such as are found in `TemporalAdjusters` class.
TemporalAdjusters.firstDayOfMonth() // Adjust to the first day of the month.
) // Returns another `LocalDate` object, for the first of the month.
.getDayOfWeek() // Obtain a `DayOfWeek` enum object, one of seven pre-defined objects representing each day of the week.
.getDisplayName( // Automatically localize.
TextStyle.FULL , // Specify how long or abbreviated.
Locale.CANADA_FRENCH // Or `Locale.US` etc. to specify the human language and cultural norms to use in localizing.
) // Returns text in a `String` such as “Monday” or “lundi”.
java.util.Calendar / .Date和相关的类是一个令人困惑的混乱,因为你已经学到了很多东西。
现代方法使用 java.time 类。
如果以java.util.Calendar对象开头,请转换为java.time。
Instant
是UTC中时间轴上的一个时刻。
Instant instant = myJavaUtilCalendarObject.toInstant();
申请时区以获取日期以获得星期几。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
请注意,时区对于确定日期(以及因此星期几)至关重要。 “今天”与世界各地同时发生的日期不同。例如,在巴黎,新的一天比蒙特利尔更早出现。
让我们通过拨打withDayOfMonth
来转到本月的第一天。
ZonedDateTime zdtFirstOfMonth = zdt.withDayOfMonth(1);
请注意,将日期时间移至月初是有问题的。夏令时(DST)等异常可能产生惊人的效果。阅读文档,以便了解行为。
DayOfWeek
DayOfWeek dayOfWeek = zdtFirstOfMonth.getDayOfWeek();
我建议传递此枚举的实例而不是2
,例如7
,int dayOfWeekNumber = dayOfWeek.getValue();
等。但如果您坚持,则可以提取整数。
String output = dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.ENGLISH
要获取星期几名称的字符串,让java.time通过magic number方法生成本地化的字符串。
java.sql.*
getDisplayName
框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacy,java.util.Date
和& Calendar
现在位于SimpleDateFormat
的Joda-Time项目建议迁移到maintenance mode类。
要了解详情,请参阅java.time。并搜索Stack Overflow以获取许多示例和解释。规范是Oracle Tutorial。
您可以直接与数据库交换 java.time 对象。使用符合JSR 310或更高版本的JDBC driver。不需要字符串,不需要where
类。
从哪里获取java.time类?
How to use ThreeTenABP…项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如ThreeTen-Extra,Interval
,YearWeek
和YearQuarter
。