【问题标题】:how to convert milliseconds to Time of day? [duplicate]如何将毫秒转换为时间? [复制]
【发布时间】:2014-12-02 21:01:10
【问题描述】:

我有三个“长”变量:开始、结束和测试时间

long start = 1412801340000         //(means 10/8/14 4:49 PM in UTC time) 
long end= 1412808540000            //(means 10/8/14 6:49 PM in UTC time)

long testtime = 1447195740000      //(means 11/10/15 5:49 PM in UTC time)

我想测试 testtime 中的 TIME OF DAY(根本不关心日期、月份和年份)是否介于 startend 与否。我该怎么做?

基本上,我只想从每个长变量中提取时间,然后检查 testtime 是否介于 *start" 和 end 之间。

【问题讨论】:

标签: java android time milliseconds


【解决方案1】:

您可以像下面这样使用代码,只需将毫秒作为日期的输入并转换为您的日期格式

    Date date = new Date(System.currentTimeMillis()); //Input your time in milliseconds
    String yourDesiredDateValue = new SimpleDateFormat("dd MMM yyyy hh:mm a").format(date);

"dd MMM yyyy hh:mm a" ----> 你的日期格式

【讨论】:

  • 我已经以毫秒为单位给出了当前时间,所以你只需用你的毫秒时间替换
【解决方案2】:
Calendar cStart = Calendar.getInstance();
cStart.setTimeInMillis(start);
Calendar cEnd = Calendar.getInstance();
cEnd.setTimeInMillis(end);
Calendar cTest = Calendar.getInstance();
cTest.setTimeInMillis(testtime);

if(cStart.before(cTest) && cEnd.after(cTest)) {
    // testtime is between start and end
}

【讨论】:

  • 不完全是,但您的代码有所帮助,因此将其标记为答案。在我的代码中,日期和年月不同,只想比较时间(小时、分钟、秒)。非常感谢您的意见。 (也感谢其他人 - 从每个答案中学到了一些东西)
  • 我很高兴能帮上忙。您可以重置日历中的日期或将其设置为相同,以便它仅适用于时间。
  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。在ThreeTen-Backport 项目中,大部分java.time 功能都被反向移植到Java 6 和Java 7。在ThreeTenABP 项目中进一步适用于早期的Android。见How to use ThreeTenABP…
【解决方案3】:

创建java.util.Date 对象,然后使用Date.getMinutesDate.getHours 等进行比较。

请注意,这看起来是一个非常简单的任务,但也有一些陷阱,例如夏令时和闰年,当您的代码可能会遇到一些奇怪的错误时。 为避免这种情况,您需要指定时区等。日历类可以为您做到这一点。

我知道我现在让你的事情变得复杂了,但是日期和时间错误可能是一个真正的细微差别,尤其是因为它们只是偶尔出现。

【讨论】:

    【解决方案4】:

    更新:Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。这个答案原封不动地留给历史。

    LocalTime

    假设这些毫秒是自 Unix epoch(1970 年开始)以来的计数,并且假设您关心 UTC 定义的时间,那么您应该使用 Joda-Time 或 java.time Java 8 中的包。这两个框架都提供了一个 LocalTime 类来表示没有日期或时区的时间。

    乔达时间

    这是 Joda-Time 2.4 版中的代码。我们首先从您的long 号码中获取 UTC 日期时间对象,然后在丢失日期和时区信息的同时转换为仅时间值。

    long start = 1412801340000         //(means 10/8/14 4:49 PM in UTC time) 
    long end= 1412808540000            //(means 10/8/14 6:49 PM in UTC time)
    long testtime = 1447195740000      //(means 11/10/15 5:49 PM in UTC time)
    
    LocalTime startLocalTime = new DateTime( start, DateTimeZone.UTC ).toLocalTime();
    LocalTime endLocalTime = new DateTime( end, DateTimeZone.UTC ).toLocalTime();
    LocalTime testLocalTime = new DateTime( testtime, DateTimeZone.UTC ).toLocalTime();
    
    boolean isBetween = ( testLocalTime.isAfter( startLocalTime ) ) && ( testLocalTime.isBefore( endLocalTime ) );
    

    在现实生活中,我会先将DateTime 实例分配给一个变量,然后再转换为LocalTime 对象以方便调试。在这里,紧凑性有助于更好的演示。

    【讨论】:

      【解决方案5】:

      tl;博士

      Interval.of( 
          Instant.ofEpochMilli( 1_412_801_340_000L ) ,  // 2014-10-08T20:49:00Z
          Instant.ofEpochMilli( 1_412_808_540_000L )    // 2014-10-08T22:49:00Z
      ).contains(
          Instant.ofEpochMilli( 1_447_195_740_000L )    // 2015-11-10T22:49:00Z
      )
      

      java.time

      如果您希望将这些值视为 UTC 中的日期时间,那么现代方法使用 java.time 类来取代麻烦的旧 DateCalendar 类。 p>

      Instant

      Instant 类表示UTC 中时间轴上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

      样本数据错误/歧义

      顺便说一句,您对自 1970 年 UTC 开始以来的毫秒数示例的日期时间描述不正确。请参阅下面的输出。您似乎有一个影响您的数字的偏移量,前两个偏移量为 4 小时,最后一个偏移量为 5 小时,这可能是由于夏令时 (DST) 的“后备”变化。这说明了为什么将时间作为从 epoch 开始的计数是一个糟糕的想法,充满了歧义和未捕获错误的问题。我建议始终使用标准的ISO 8601 格式将这些时刻序列化为文本。

      Instant start = Instant.ofEpochMilli( 1_412_801_340_000L );  // 2014-10-08T20:49:00Z (not 10/8/14 4:49 PM in UTC time)
      Instant stop = Instant.ofEpochMilli( 1_412_808_540_000L );   // 2014-10-08T22:49:00Z (not 10/8/14 6:49 PM in UTC time)
      Instant test = Instant.ofEpochMilli( 1_447_195_740_000L );   // 2015-11-10T22:49:00Z (not 11/10/15 5:49 PM in UTC time)
      

      看到code run live at IdeOne.com

      start.toString(): 2014-10-08T20:49:00Z

      stop.toString(): 2014-10-08T22:49:00Z

      test.toString(): 2015-11-10T22:49:00Z

      比较

      Instant 对象与isBeforeisAfterequals 进行比较。

      通常,处理时间跨度的最佳方法称为半开放式,其中开头是包含,结尾是排他。因此,例如,一天从一天的第一刻开始,一直持续到但包括第二天的第一刻。

      boolean isTestWithinRange = 
          ( test.equals( start ) || test.isAfter( start ) )
          &&
          test.isBefore( stop ) 
      ;
      

      询问“等于或晚于”的更简短的方式是“不早于”。

      boolean isTestWithinRange = 
          ( ! test.isBefore( start ) )
          &&
          test.isBefore( stop ) 
      ;
      

      甚至更短,使用ThreeTen-Extra 项目中的org.threeten.extra.Interval 类,您可以将这个库添加到您的Java 项目中。不确定这是否适用于 Android。

      Interval interval = Interval.of( start , stop ) ;
      boolean isTestWithinRange = interval.contains( test ) ;
      

      关于java.time

      java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

      Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

      要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

      使用符合JDBC 4.2 或更高版本的JDBC driver,您可以直接与您的数据库交换java.time 对象。不需要字符串或 java.sql.* 类。

      从哪里获得 java.time 类?

      ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-06
        • 2016-03-04
        • 2013-03-09
        相关资源
        最近更新 更多