如何保存和检索SharedPreferences日期(How to save and retriev

2019-06-28 01:59发布

我需要保存在几个日期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/MontrealAfrica/Casablanca ,或Pacific/Auckland 。 切勿使用3-4个字母的缩写,如ESTIST ,因为它们不是真正的时区,不规范,甚至不是唯一的(!)。

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.DateCalendar ,和SimpleDateFormat

乔达-时间的项目,现在在维护模式 ,建议迁移到java.time类。

要了解更多信息,请参阅甲骨文教程 。 和搜索堆栈溢出了很多例子和解释。 规范是JSR 310 。

您可以直接与数据库交换java.time对象。 使用JDBC驱动程序与兼容JDBC 4.2或更高版本。 无需串,没有必要java.sql.*类。

从哪里获取java.time类?

  • 的Java SE 8Java SE的9Java SE的10Java 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试验场。 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多 。



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();
                               }

希望它能帮助。



文章来源: How to save and retrieve Date in SharedPreferences