我需要保存在几个日期SharedPreferences
在Android和检索。 我建立使用提醒应用AlarmManager
,我需要节省将来的日期列表。 它必须能够检索为毫秒。 首先,我认为今天的计算时间,现在和未来的时间和存储在共享的偏好之间的时间。 但该方法是不工作,因为我需要用它来AlarmManager
。
Answer 1:
为了保存和加载准确的日期,你可以使用long
一(数)表示Date
的对象。
例:
//getting the current time in milliseconds, and creating a Date object from it:
Date date = new Date(System.currentTimeMillis()); //or simply new Date();
//converting it back to a milliseconds representation:
long millis = date.getTime();
您可以用它来保存或检索Date
/ Time
从数据SharedPreferences
这样
保存:
SharedPreferences prefs = ...;
prefs.edit().putLong("time", date.getTime()).apply();
读回:
Date myDate = new Date(prefs.getLong("time", 0));
编辑
如果你想存储的TimeZone
additionaly,你可以写为此一些辅助方法,这样的事情(我没有测试过,随时纠正它,如果事情是错的):
public static Date getDate(final SharedPreferences prefs, final String key, final Date defValue) {
if (!prefs.contains(key + "_value") || !prefs.contains(key + "_zone")) {
return defValue;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(prefs.getLong(key + "_value", 0));
calendar.setTimeZone(TimeZone.getTimeZone(prefs.getString(key + "_zone", TimeZone.getDefault().getID())));
return calendar.getTime();
}
public static void putDate(final SharedPreferences prefs, final String key, final Date date, final TimeZone zone) {
prefs.edit().putLong(key + "_value", date.getTime()).apply();
prefs.edit().putString(key + "_zone", zone.getID()).apply();
}
Answer 2:
TL;博士
现代的方法使用java.time类和ISO 8601名的字符串。
读。
Instant // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochMilli(
Long.getLong( incomingText )
) // Returns a `Instant` object.
.atZone( // Adjust from UTC to some time zone. Same moment, same point on the timeline, different wall-clock time.
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
写作。
ZonedDateTime
.of(
LocalDate.of( 2018 , Month.JANUARY , 23 ) ,
LocalTime.of( 15 , 35 ) ,
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
.toInstant() // Returns an `Instant`. Adjust from a time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
.toEpochMilli() // Returns a `long` integer number primitive. Any microseconds or nanoseconds are ignored, of course.
如果您的报警管理器仍未改进处理java.time对象,传统及使用添加到老班新方法现代类之间的转换。
java.util.Date d = java.util.Date.from( instant ) ;
…和…
Instant instant = d.toInstant() ;
java.time
麻烦的旧日期时类是由java.time类取代。
对于UTC片刻,用纳秒的分辨率,使用Instant
。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
你想只为您的需求毫秒,所以截断任何微秒和纳秒。
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;
要确定日期和时间的天瞬间需要一个时区。 时区是在确定的日期是至关重要的。 对于任何给定的时刻,日期由区全球各地的变化。 例如,在午夜后几分钟法国巴黎是新的一天,同时还“昨天”在蒙特利尔魁北克 。
如果没有指定时区,JVM的隐式应用当前默认时区。 该默认可以在任何时刻改变运行时(!)期间,因此您的结果可能会有所不同。 最好指定您希望的/预期的时区明确作为参数。
指定适当的时区名称 ,格式为continent/region
,如America/Montreal
, Africa/Casablanca
,或Pacific/Auckland
。 切勿使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,不规范,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果你想使用JVM当前的默认时区,要求它和作为参数传递。 如果省略,JVM的当前默认是隐式应用。 更好的是明确的,作为默认可以在任何时刻运行过程中的任何代码在JVM中的任何应用程序的任何线程改变。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
或指定的日期。 您可以通过多种设置月,与健全的编号1-12一月至十二月。
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
或者,更好,使用Month
枚举对象预先定义的,一个是一年中每个月。 提示:使用这些Month
整个代码库,而不是一个单纯的整数对象,使你的代码更自我记录,确保有效的值,并提供类型安全 。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
有时间的日,联合收割机LocalTime
。
LocalTime lt = LocalTime.of( 14 , 0 ) ;
总结这一切一起作为一个ZonedDateTime
对象。
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
通过提取调整为UTC Instant
。
Instant instant = zdt.toInstant() ;
自1970年第一刻在UTC时代参考提取所需计数的-毫秒。 再次,要知道,在你的任何万分之一/毫微Instant
将提取毫秒时被忽略。
long milliseconds = instant.toEpochMilli() ; // Be aware of potential data loss, ignoring any microseconds or nanoseconds.
为文本使用阅读那些毫秒从存储回Long
类。
long milliseconds = Long.getLong( incomingText ) ;
Instant instant = Instant.ofEpochMilli( milliseconds ) ;
识破的由一个特定的区域(时区)的人使用的挂钟时间的镜头那一刻,应用ZoneId
获得ZonedDateTime
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
要生成表示值文本,使用DateTimeFormatter.ofLocalizedDateTime
自动定位。
提示:考虑在标准编写日期时间值来存储ISO 8601格式,而不是作为一个计数的-毫秒。 该毫秒不能被人类有意义的阅读,从而使调试和监控棘手。
String output = instant.toString() ;
2018-10-05T20:28:48.584Z
Instant instant = Instant.parse( 2018-10-05T20:28:48.584Z ) ;
关于java.time
该java.time框架是建立在Java 8和更高版本。 这些类取代麻烦的老传统日期时间类,如java.util.Date
, Calendar
,和SimpleDateFormat
。
该乔达-时间的项目,现在在维护模式 ,建议迁移到java.time类。
要了解更多信息,请参阅甲骨文教程 。 和搜索堆栈溢出了很多例子和解释。 规范是JSR 310 。
您可以直接与数据库交换java.time对象。 使用JDBC驱动程序与兼容JDBC 4.2或更高版本。 无需串,没有必要java.sql.*
类。
从哪里获取java.time类?
- 的Java SE 8 , Java SE的9 , Java SE的10 , Java SE的11 ,后来-具有捆绑实现标准Java API的一部分。
- Java的9增加了一些小的功能和修复。
- Java SE 6中和Java SE 7中
- 大多数java.time功能后移植到Java 6和7 ThreeTen,反向移植 。
- Android的
- 后来版本的java.time类的Android束实现的。
- 对于较早的Android(<26),则ThreeTenABP项目适应ThreeTen-反向移植 (上面提到的)。 请参阅如何使用ThreeTenABP ... 。
该ThreeTen-额外项目与其他类扩展java.time。 该项目是为将来可能增加的java.time试验场。 您可以在这里找到一些有用的类,比如Interval
, YearWeek
, YearQuarter
,和更多 。
Answer 3:
你可以这样做:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.US);
要保存日期:
preferences .edit().putString("mydate", sdf.format(date)).apply();
要检索:
try{
Date date = sdf.parse(preferences.getString("myDate", "defaultValue"));
} catch (ParseException e) {
e.printStackTrace();
}
希望它能帮助。