android - 日历返回错误的星期
问题描述
所以我需要获得本周星期一的毫秒时间和本周星期日的毫秒时间,并且下面的代码工作正常,直到我在模拟器上安装应用程序,如果我将时间设置为星期日,它会返回Jun 18 - Jun 24
,但在三星 Galaxy s5 上它返回Jun 11 - Jun 17 <- this is how it should show
我做错了吗?
getMondayTime
方法以毫秒为单位返回星期一的时间
private fun getMondayTime(): Long{
val calendar = Calendar.getInstance()
calendar.timeInMillis = System.currentTimeMillis()
calendar.firstDayOfWeek = Calendar.MONDAY
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
calendar.set(Calendar.HOUR_OF_DAY, 0)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, 0)
return calendar.timeInMillis
}
getSundayTime
以毫秒为单位返回星期日的时间
private fun getSundayTime(): Long {
val calendar = Calendar.getInstance()
calendar.timeInMillis = System.currentTimeMillis()
calendar.firstDayOfWeek = Calendar.MONDAY
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
calendar.set(Calendar.HOUR_OF_DAY, 22)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, 0)
return calendar.timeInMillis
}
在这里,我把所有的时间都放在了地方
fun generateWeek(): Week{
val format = SimpleDateFormat("MMM d", Locale.ENGLISH)
val mondayTime = getMondayTime()
val sundayTime = getSundayTime()
val label = "${format.format(mondayTime)} - ${format.format(sundayTime)}"
return Week(label, mondayTime, sundayTime)
}
解决方案
java.time
很抱歉我不会写 Kotlin(如果那是你的语言?)所以我必须相信你会从 Java 翻译。现代解决方案是:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMM d", Locale.ENGLISH);
// Time zone is crucial for controlling which week we get.
ZoneId zone = ZoneId.of("America/Lower_Princes");
WeekFields wf = WeekFields.ISO; // Monday is first day of week
LocalDate today = LocalDate.now(zone);
ZonedDateTime mondayTime = today.with(wf.dayOfWeek(), 1).atStartOfDay(zone);
ZonedDateTime sundayTime = today.with(wf.dayOfWeek(), 7)
.atTime(LocalTime.of(22, 0))
.atZone(zone);
String label = mondayTime.format(dateFormatter) + " - " + sundayTime.format(dateFormatter);
System.out.println("Label: " + label);
System.out.println("Monday time in millis: " + mondayTime.toInstant().toEpochMilli());
System.out.println("Sunday time in millis: " + sundayTime.toInstant().toEpochMilli());
刚刚运行(星期一)这个打印:
Label: Jun 18 - Jun 24
Monday time in millis: 1529294400000
Sunday time in millis: 1529892000000
在撰写本文时,太平洋极少数时区仍然是星期天。所以我也尝试了其中之一:
ZoneId zone = ZoneId.of("Pacific/Niue");
然后我上周得到:
Label: Jun 11 - Jun 17
Monday time in millis: 1528714800000
Sunday time in millis: 1529312400000
因此,指定正确的时区对于获得所需的一周至关重要。我怀疑这是您问题中的问题:如果您的模拟器设置为使用运行代码时已经是星期一的时区,那么正如您所观察到的,它将给您下一周。
我正在使用并推荐java.time
现代 Java 日期和时间 API。
问题:我可以在 Android 上使用 java.time 吗?
是的,java.time
在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6。
- 在 Java 8 及更高版本以及较新的 Android 设备(据我所知,从 API 级别 26 开始)中,现代 API 是内置的。
- 在 Java 6 和 7 中获得 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
- 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从
org.threeten.bp
子包中导入日期和时间类。
如果你反对依赖外部库,即使是像 ThreeTenABP 这样面向未来的库——我的意思是,它是由java.time
为 Java 开发的同一个人开发的,并且它只包含一旦升级到核心 Java 也将包含的功能API 级别 26 或更高 - 在这种情况下,您可能可以通过将正确的TimeZone
对象传递给Calendar.getInstance(TimeZone)
方法来解决您的问题(我没有尝试过)。TimeZone
是另一种过时的日期和时间类。
链接
- Oracle 教程:日期时间解释如何使用
java.time
. - Java 规范请求 (JSR) 310,
java.time
第一次描述的地方。 - ThreeTen Backport 项目,
java.time
Java 6 和 7 的反向移植(ThreeTen for JSR-310)。 - ThreeTenABP , ThreeTen Backport 的 Android 版
- 问题:如何在Android项目中使用ThreeTenABP,有非常详尽的解释。
Calendar.getInstance(TimeZone)
方法文档
推荐阅读
- python - 无法识别 Udemy-dl 访问令牌
- scala - GitHub 操作错误:发布 Scala 库
- c++ - 模板朋友错误,错误:“类 LinkedList”需要模板参数
- node.js - 使用 $inc 将数据保存和递增到 MongoDB
- android - firebase 身份验证中的无效 SafetyNetToken
- python - 从csv文件导入mysql时不断出错
- wordpress - 在控制台上发布 /wp-admin/admin-ajax.php 403
- python - 无法使用 pipx 安装
- r - 我的函数有效,但是当我运行它时 R 崩溃
- python - 如何使用熊猫计算累积加权平均值