Android( Java )日期和时间处理完全解析

2017-05-04 09:35:37 +08:00
 tangpj

今日推荐文章: Android ( Java )日期和时间处理完全解析——使用 Gson 和 Joda-Time 优雅地处理日常开发中关于时间处理的问题

9258 次点击
所在节点    Android
11 条回复
TakWolf
2017-05-04 10:32:36 +08:00
重要的几个点,你都给忽略了。。。

1. 时间的最佳实践是统一使用标准时间格式,即 ISO 8601 标准

2.为啥在 Android 中使用 `net.danlew:android.joda` 而不直接使用 `joda:joda` ?

```
public class AppController extends Application {

@Override
public void onCreate() {
super.onCreate();
JodaTimeAndroid.init(this); // 这里是不是要解释一下?
}

}
```

3. 结合 Gson 就要结核彻底,都用了 Joda 了,就不要在用任何 Date 相关的了,TyepAdapter 你还给忽略了

```
public final class EntityUtils {

private EntityUtils() {}

public static final Gson gson = new GsonBuilder()
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
.create();

private static class DateTimeTypeAdapter implements JsonSerializer<DateTime>, JsonDeserializer<DateTime> {

@Override
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString()); // 这里自己去匹配格式,建议都用标准 ISO 8601 格式
}

@Override
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new DateTime(json.getAsString());
}

}

}
```

```
public class Weibo {

public DateTime date;

}
```

```
Weibo weobo = gson.fromJson(json,Weibo.class);
```
zhihaofans
2017-05-04 10:35:13 +08:00
还以为又是腾讯云的
ihuotui
2017-05-04 10:56:39 +08:00
想装逼,结果被打脸
WispZhan
2017-05-04 11:15:32 +08:00
基于某种原因,平时就是不喜欢看别人的 Blog 和文章。
要问为什么?因为基本上所有 Blog 都有这样或者那样的问题,包括我自己的。

每个人的 Blog 的侧重点都不一样,一般都是写给自己看的,而不是写给别人。
包括国内的一些书也是一样。写给别人看的东西要严谨,写给自己的东西可以随意。
domty
2017-05-04 11:26:06 +08:00
@WispZhan #4
+1
blog 这东西我都是当个人 wiki 用的
tangpj
2017-05-04 11:58:09 +08:00
@TakWolf
这里我回复下你的问题
1、我在关于 DateTime 的介绍中有有一句话:其中 String 的格式需要是 ISO8601 格式,详见:ISODateTimeFormat.dateTimeParser()。你可以点击下这个链接,这个链接就是您说的 IOSO8601 标准的官方网站。而我在文章的最末尾也有一个详细介绍了 IOSO8601 标准的一个表格,你可以详细看看。
2、为什么使用 net.danlew:android.joda 呢?因为这个是为 Android 设计的一个库,原因是 Android 上的 JAR 设置有个特殊的问题:由于使用了 ClassLoader.getResourceAsStream(),大大增加了它在应用程序上的内存占用。这个库通过从资源而不是从 JAR 家在来避免在 Android 上内存占用的问题(至于为什么要减少内存占用,我相信您是知道的)。同样,在 Android 上用 Rx-Android 的原因不单单是因为要增加支持切换到 UI Thread 的方式哦。也有减少内存占用的原因。解析清楚这点对读者确实是很有必要的。
3、这篇文章主要是要介绍时间处理的,不是介绍 GSON 也不是介绍 Joda-Time,而介绍时间处理的话就逃不过 Date 这个类。如果想更加简单的话,的确可以通过使用 Gson 的 TypeAdapter 来实现,我在文章中也有提及到了。我之前一直有考虑是不是把您所说的内容加上去的,但是考虑到如果深入探讨的话,就涉及到 Gson 的内容了,我认为没必要。而您的评论恰好是一个比较好的补充。
最好,感谢您的提醒与指点
tangpj
2017-05-04 11:59:00 +08:00
打错了,是最后
TakWolf
2017-05-04 14:05:09 +08:00
关于 `为啥在 Android 中使用 net.danlew:android.joda 而不直接使用 joda-time:joda-time 的问题:

如果你在 Android 使用 android.joda,你必须要在 Application.onCreate()中初始化 JodaAndroid,像这样:

public class AppController extends Application {

@Override
public void onCreate() {
super.onCreate();
JodaTimeAndroid.init(this);
}

}

不初始化,不会报错,但是这样就没有任何优势。

这个就写在 joda-android 的 Readme 中,


!!!!!但是全文没有任何地方说明这个问题!!!!!


为什么这里要初始化?

1. Joda-Time 需要时区的配置(使用 Provider 接口实现),而时区标准是在不断变更和扩充的,经常性更新。
原版 joda 把它设计为资源数据库,放到 classpath 中加载,joda-android 将其改为 android-resources,对 andorid 更友好。
joda-android 引用的 joda 为 :joda-time-xxx-no-tzdb,这里不包含时区资源配置。
初始化这句,就是替换默认的 Provider:

```
DateTimeZone.setProvider(new ResourceZoneInfoProvider(context));
```

这里你不初始化,会走一个默认的。提供的外置时区资源根本不会加载。

2. Android 手机是可以调时间修改时区的,如果你动态改了时区,joda 的默认时区就不同了,因此需要注册一个 BroadcastReceiver 监听时区变化,来动态修改默认时区。

================================================================

Android Studio 2.4 已经开始支持 Java 8 了,但是却没有 java.time 包,这个不是 BUG!!

虽然开发需要安装 JDK,但是 java-se 环境跟 Android 环境,使用的核心库跟标准库并不是一个。
你可以理解为,他们只是使用了相同的接口签名,Android 用的并不是 Java 的核心库。(这就是为啥甲骨文跟谷歌撕逼了好几年) Andorid 的核心库实现在这里:

%ANDROID_HOME%\sources\android-25

因此,没有 java.time 包,不是 BUG,单纯是因为这部分包谷歌没有移植!!如果你仔细看,很多核心库的实现都是不一样的!

================================================================

最后,

文章的标题叫做《 Android ( Java )日期和时间处理完全解析——使用 Gson 和 Joda-Time 优雅地处理日常开发中关于时间处理的问题》

读完后,没看到完全解析,也没看到优雅,同时提到的 gson 和 joda 也没结合
tangpj
2017-05-04 15:43:36 +08:00
@TakWolf
关于 joda-time 与 joda-android 的问题的确像您所说的一样,我没有写清楚。像您所说的 joda-android 的 readme 文件上已经有了,可能因为我的惯性思维所以没有说明为何这样写,因为我觉得感兴趣的朋友应该会上去 github 上看的。

========================================================================

时区改变的确是一个问题,但是我写 blog 的时候主要考虑是如何让别人能够看懂,所以就没有深入细节了。

========================================================================

blog 上面的代码不是完整的代码,为了方便理解,我只留下了关键的部分。迟点我会把完整的代码上传上去,至于是否优雅,是否完全,是否和 gson 有所结合到时候再下结论吧。

========================================================================

至于第四点,我已经说过了,我不知道为什么 AS 2.4 不能使用 java.time 包。我在 Android O 的官方 API 文档上是看到关于 java.time 包的说明的,API 网址是: https://developer.android.com/reference/java/time/package-summary.html 。所以我就推测是 AS 2.4 还没提供支持的原因。
至于您说的 Android 用的并不是 Java 的核心库这个问题,我并没有深入了解过。我迟点会加深理解的。

这里我要说明我写博客的原因。一个是,我怕做过的东西不记录下来的话,很容易会遗忘。第二个就是我希望有人能指出我理解不到位的地方,所以您能指出我的不足之处我是十分感谢的。
29995270
2017-05-05 00:16:11 +08:00
楼主态度这么好,不知道为啥回复不是阴阳怪气就是跟吃了枪药似的,写得不错,支持。
tangpj
2017-05-05 09:32:57 +08:00
@29995270 十分感谢哦😊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/358995

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX