【问题标题】:Need help converting a UTC date string in Java需要帮助在 Java 中转换 UTC 日期字符串
【发布时间】:2014-03-14 03:15:44
【问题描述】:

我有一个游戏客户端 Google App Engine 服务器。我的服务器向客户端发送了一个 UTC 时间日期字符串,该字符串是自纪元以来的毫秒数,表示上次播放的日期戳。我希望我的客户报告自上次播放以来的天数/小时/分钟。我在我的 iOS 客户端中有这个工作,但无法让它在 Android 中工作。我尝试了很多选项,一些使用Joda-Time 一些纯 Java 的 Date 对象,时间总是偏移几个小时。奇怪的是时间不在整点时间.. 可能是 2 小时 34 分钟.. 所以我不认为我的问题只是时区问题,或者它会在整点时间不?

基本上我需要获取这个 UTC 时间,然后也获取 UTC 中的当前时间。比较差异以获得天/小时/分钟

这就是我所拥有的,我正在使用Joda-Time 库:

例如,我的服务器向我发送了这个字符串“1392392591.0”(恰好是太平洋标准时间上午 7:45 左右的 UTC 时间)

public String convertDateString ( String date ) {

        Float gameEpoch = Float.parseFloat( date ); 

        DateTime now = new DateTime();
        DateTime gameTime = new DateTime(gameEpoch.longValue() * 1000 );

        Period p = new Period(gameTime, now, PeriodType.dayTime());

        String dateString = "";
        if(p.getDays() > 0)
            dateString =  (p.getDays() + " days " + p.getHours() + " hours ago");
        else if(p.getHours() > 0)
            dateString =  (p.getHours() + " hours " + p.getMinutes() + " minutes ago");
        else if(p.getMinutes() > 0)
            dateString =  (p.getMinutes() + " minutes ago");
        else
            dateString = "Just Now";

        return dateString;
    }

【问题讨论】:

  • My server sends the client a UTC timedate string which is milliseconds since epoch。没有。自 Unix [epoch][1] 以来,您的客户端正在接收 ,而不是 毫秒。显然你知道这一点,而且一定是打错了,因为你的示例代码正确地乘以 1000。我正在为其他读者做这个笔记。
  • 我建议将L 添加到1000 以成为1000L。在使用“long”原始类型进行数学运算以避免数据丢失时,这是一个好习惯。添加L 还有助于使代码自记录,提醒我们处理的是长整数而不是更常见的整数。
  • 会的,谢谢 Basil

标签: java android google-app-engine datetime jodatime


【解决方案1】:

不要将String 转换为Float。浮点数只有 7 位有效数字,因此 gameEpoch 总是不精确的。使用double,或者更好的是long

【讨论】:

  • 我已经调整了我的代码,但仍然与我期望看到的结果相差 2 小时 2 分钟(我有一个 javascript 和 ObjectiveC 客户端在做同样的事情,并且它们正在工作)。这是我转换为 Long 的更新:long gameEpoch = Long.parseLong( date ); 有趣的是..如果我只是检查 UTC 中的“现在”时间,它会比我的笔记本电脑时钟少几个小时,这是可以预料的,但它也少了 2 分钟,我没想到。在将本地时间转换为 UTC 时,我是否应该期望不仅仅是天数的变化......分钟也会变化吗?没想到
  • 啊!找到我被扔的地方。我在 android 模拟器中运行它.. 结果模拟器时钟关闭了 2 分钟,并且时区设置为 GMT。那让我失望了。我认为上面带有 Long 调整的代码正在工作。谢谢你的帮助。我觉得自己很笨。
【解决方案2】:

answer by Tony the Pony 是正确的。

顺便说一句,在示例代码的后半部分,您工作得太辛苦了。 Joda-Time 提供了一个 PeriodFormatterBuilder 类来帮助您生成这些描述性字符串。

这个示例代码需要一些技巧,但会让你朝着正确的方向前进。

// Period(int years, int months, int weeks, int days, int hours, int minutes, int seconds, int millis)
Period period = new Period( 0, 0, 0, 2, 3, 4, 0, 0 );

PeriodFormatter formatter = new PeriodFormatterBuilder()
        .printZeroAlways()
        .appendYears()
        .appendSuffix( " year", " years" )
        .appendSeparator( ", " )
        .printZeroRarelyLast()
        .appendMonths()
        .appendSuffix( " month", " months" )
        .appendSeparator( ", " )
        .appendWeeks()
        .appendSuffix( " week", " weeks" )
        .appendSeparator( ", " )
        .appendDays()
        .appendSuffix( " day", " days" )
        .appendSeparator( ", " )
        .appendHours()
        .appendSuffix( " hour", " hours" )
        .appendSeparator( ", and " )
        .appendMinutes()
        .appendSuffix( " minute", " minutes" )
        .toFormatter();

String timeSpanDescription = formatter.print( period );

转储到控制台...

System.out.println( "period: " + period );
System.out.println( "timeSpanDescription: " + timeSpanDescription );

运行时……

period: P2DT3H4M
timeSpanDescription: 0 years, 2 days, 3 hours, and 4 minutes

【讨论】:

  • 感谢您的示例!自发布此消息以来,我已经改进了我所拥有的内容。但我没有利用 PeriodFormatterBuilder。
猜你喜欢
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 2021-04-19
  • 1970-01-01
  • 2021-01-24
  • 2011-08-23
相关资源
最近更新 更多