android|记录JAVA中Calendar类的一个问题

记录一些不难但是需要费些劲的小需求,以备忘记时可以查询,避免浪费时间,也希望能帮助到其他人
一、需求
展示每个月涉及周的周头尾时间
android|记录JAVA中Calendar类的一个问题
文章图片

二、实现过程
1、获取某一日期所在周的周一和周日
这里产品要求的是周一算一周的起点,和java默认的实现不同,所以实现的方法如下:

//获取周第一天 public static String getFirstDayOfWeek(Calendar calold) { Calendar cal = (Calendar) calold.clone(); cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); Date date = cal.getTime(); return Tools.getTimeByFormat(date, "yyyy-MM-dd"); } //获取周最后一天 public static String getEndDayOfWeek(Calendar calold) { Calendar cal = (Calendar) calold.clone(); cal.add(Calendar.DAY_OF_YEAR, 7); cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); Date date = cal.getTime(); return Tools.getTimeByFormat(date, "yyyy-MM-dd"); }

2、获取月第一天传到第一步的方法里,获取展示所需的字符串,下面就举例:
public static String getMonthFirstDayWeekStr(@NotNull Calendar calold, int f) { Calendar cale = (Calendar) calold.clone(); cale.add(Calendar.MONTH, 0); cale.set(Calendar.DAY_OF_MONTH, 1); Date date = cale.getTime(); //LogUtil.v("datestr", Tools.getTimeByFormat(date, "MM-dd")); if (f >= 1) cale.add(Calendar.DAY\_OF\_YEAR, f \* 7); return getFirstDayOfWeek(cale); }

运行之后发现,获取日期有误,
cale.set(Calendar.DAY_OF_MONTH, 1)
这一步始终无效,几番尝试无果之后,添加了上面注释中的打印日志的代码,之后运行成功。
随后我用java代码尝试了下,验证了getTime这个方法使对Calendar的设置生效了;进一步看源码发现,是因为调用了Calendar中的updatetime方法,进一步调用了computeTime方法;随后到实现类GregorianCalendar中看了相关的代码,computeTime方法中有这样一句代码。
// Set this calendar's time in milliseconds time = millis;

再结合calendar中updatetime和fileds字段的注释发现Calendar中有两套字段记录时间,一个是long型的time记录毫秒数;一个是int数组fields记录着各种时间的字段。这里贴一段注释
// Calendar contains two kinds of time representations: current "time" in // milliseconds, and a set of calendar "fields" representing the current time. // The two representations are usually in sync, but can get out of sync // as follows. // 1. Initially, no fields are set, and the time is invalid. // 2. If the time is set, all fields are computed and in sync. // 3. If a single field is set, the time is invalid. // Recomputation of the time and fields happens when the object needs // to return a result to the user, or use a result for a computation.

【android|记录JAVA中Calendar类的一个问题】可见,Calendar中真正记录时间的time字段,而在我们用设置field也就是年月日等字段时,并没有立刻同步到time,而只是改变了field;当调用add、gettime等方法时,在updatetime方法中会进行同步,将field的改变同步到time字段,此时才真正改变了时间。
三、延申
1、通过研究代码,解决的几个工具上的小问题
a、在AndroidStudio中运行Java程序
add右键new moudle->选择java libarary->在Class中添加main函数->运行键左侧下拉 edit configurations->添加Application->分别配置main class为main函数所在类,working directory为mainclass所在目录,useclasspathofmoudle为添加的moudle,完成后就可以运行

b、在Android studio中关联java源码,可以查看代码
File -> OtherSettings -> Default Project Structure或者
File -> Default Project Structure->将JDK Location选择为自己下载的jdk的位置;
备用方法:如果上面的方法遇到问题,可将jdk目录中的src.zipjavafx-src.zip拷贝到AS默认的jre目录下
四、参考链接
As中运行java程序
Java-Calendar“陷阱”
Android Studio关联JDKJava 源码

    推荐阅读