Android( Java )日期和时间处理完全解析 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tangpj
V2EX    Android

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

  •  
  •   tangpj 2017-05-04 09:35:37 +08:00 12545 次点击
    这是一个创建于 3113 天前的主题,其中的信息可能已经有所发展或是发生改变。
    11 条回复    2017-05-05 09:32:57 +08:00
    TakWolf
        1
    TakWolf  
       2017-05-04 10:32:36 +08:00   2
    重要的几个点,你都给忽略了。。。

    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
        2
    zhihaofans  
       2017-05-04 10:35:13 +08:00 via iPhone
    还以为又是腾讯云的
    ihuotui
        3
    ihuotui  
       2017-05-04 10:56:39 +08:00 via iPhone
    想装逼,结果被打脸
    WispZhan
        4
    WispZhan  
       2017-05-04 11:15:32 +08:00
    基于某种原因,平时就是不喜欢看别人的 Blog 和文章。
    要问为什么?因为基本上所有 Blog 都有这样或者那样的问题,包括我自己的。

    每个人的 Blog 的侧重点都不一样,一般都是写给自己看的,而不是写给别人。
    包括国内的一些书也是一样。写给别人看的东西要严谨,写给自己的东西可以随意。
    domty
        5
    domty  
       2017-05-04 11:26:06 +08:00
    @WispZhan #4
    +1
    blog 这东西我都是当个人 wiki 用的
    tangpj
        6
    tangpj  
    OP
       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
        7
    tangpj  
    OP
       2017-05-04 11:59:00 +08:00
    打错了,是最后
    TakWolf
        8
    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
        9
    tangpj  
    OP
       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
        10
    29995270  
       2017-05-05 00:16:11 +08:00 via Android   1
    楼主态度这么好,不知道为啥回复不是阴阳怪气就是跟吃了枪药似的,写得不错,支持。
    tangpj
        11
    tangpj  
    OP
       2017-05-05 09:32:57 +08:00
    @29995270 十分感谢哦
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5189 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:03 PVG 17:03 LAX 01:03 JFK 04:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86