[英]SetDate() to Calendar object to change time, changes the date back to 1970
因此,我开始在名为startTime的Calendar对象中获取当前时间。
Calendar startTime = Calendar.getInstance();
Log.w(TAG, "CALENDAR BEFORE: " + startTime.getTime());
这很有效,因为我的日志显示时间是当前时间(即TST Nov 07 12:50:10 CST 2017)。 但是,我需要从“首选项”选项中抽出时间,该选项会向我返回类似“ 15:00”的信息。 这被存储在String alarmPref中
String alarmPref = preferences.getString(keyAlarm, "12:00");
Log.w(TAG, "AlarmReceiver: Alarm going to be set at: " + alarmPref);
这是棘手的地方,我使用仅数小时和数分钟的SimpleDateFormat将此字符串更改为Date(添加日期崩溃)。
SimpleDateFormat format = new SimpleDateFormat("HH:mm", Locale.getDefault());
当我尝试将此时间添加到我首先创建的Calendar对象中(startTime)时,它将时间更改为“ Thu Jan 01 15:00:00 CST 1970”,此处我具有正确的时间,但没有日期。
Date newDate = format.parse(alarmPref);
startTime.setTime(newDate);
Log.w(TAG, "CALENDAR AFTER SET: " + startTime.getTime());
我一直在尝试解决此问题,但没有找到解决方案,也没有类似的问题。
如果您的目标是通过设置特定的时间来更改日期时间...
ZonedDateTime.of(
LocalDate.now( ZoneId.of( "America/Chicago" ) ) , // Get the current date for a particular place on Earth.
LocalTime.parse( "15:00" ) , // Specify the time-of-day.
ZoneId.of( "America/Chicago" ) // Assign the intended zone to the resulting `ZonedDateTime` object.
)
您正在解析一个表示日期时间值的字符串。 该分析方法假定您要自纪元参考日期 1970-01-01T00:00:00Z开始的第一天。 因此您在1970年1月1日下午3点。这是所有正确记录的行为。 但不是您想要的。
避免与最早的Java版本(例如Calendar
捆绑在一起的麻烦的旧日期时间类。 这些在几年前被Java.time类替换为Java 8和Java 9。 对于较早的Android,请参阅下面的最新项目符号。
指定您想要的时区。 如果省略,则隐式应用JVM的当前默认时区。 该默认值可能会在运行时随时更改,因此不可靠。
以continent/region
的格式指定正确的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用3-4个字母的缩写,例如CST
或EST
或IST
因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Chicago" ) ;
时区对于确定日期和时间至关重要。 在任何给定时刻,日期都会在全球范围内变化。 例如, 法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。
ZonedDateTime zdtNow = ZonedDateTime.now( z ) ;
对于一天中唯一的值,没有任何日期,没有时区,请使用LocalTime
类。
LocalTime lt = LocalTime.parse( "15:00" ) ;
您想要相同的日期,但又需要另一个时间。 因此,提取仅日期部分,并与所需的日期时间结合,同时应用预期的时区以获得新的ZonedDateTime
对象。
LocalDate ld = zdtNow.toLocalDate() ;
ZonedDateTime zdtTodayAtThreePm = ZonedDateTime.of( ld , lt , z ) ;
提示:通常最好在UTC而不是特定时区中进行日志记录,序列化和数据交换。 为此,请使用Instant
类。 您可以从ZonedDateTime
提取Instant
ZonedDateTime
。
Instant instant = zdtTodayAtThreePm.toInstant() ; // Always in UTC.
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程 。 并在Stack Overflow中搜索许多示例和说明。 规格为JSR 310 。
您可以直接与数据库交换java.time对象。 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
通过这样做,我设法解决了问题:
String alarmPref = preferences.getString(keyAlarm, "12:00");
Log.w(TAG, "AlarmReceiver: Alarm going to be set at: " + alarmPref);
SimpleDateFormat format = new SimpleDateFormat("HH:mm", Locale.getDefault());
Date newDate = format.parse(alarmPref);
//startTime.setTime(newDate);
startTime.set(Calendar.HOUR_OF_DAY, newDate.getHours());
startTime.set(Calendar.MINUTE, newDate..getHours());
startTime.set(Calendar.SECOND, 0);
Log.w(TAG, "CALENDAR AFTER SET: " + startTime.getTime());
在这里,我仅将HOURS和MINUTES设置为0(将秒设置为0),并且日期保持不变。 但是,不赞成使用方法.getHours()和.getHours(),是否有更理想的方法呢?
我在这里看不到任何问题。 您要求SimpleDateFormat通过仅提供小时和分钟来解析日期。 它会将输入中缺少的其他字段默认为时间的开头,这不是您期望的。 显然,实现SimpleDateFormat的开发人员认为此行为是合理的。
仅设置HOUR_OF_DAY和MINUTE的解决方法看起来不错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.