SimpleDateFormat无法格式化日期间隔?

时间:2013-01-05 12:01:45

标签: java date timezone

我尝试使用SimpleDateFormat格式化时间间隔。

import java.text.*;
import java.util.*;

public class DateFormatTest {
  public static void main(String[] args) {
    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
    long interval = 1000;
    System.out.println("Interval in millis: " + interval);
    System.out.println("Expected result: 00:00:01");
    System.out.println("Result using Date and SimpleDateFormat: " +
      sdf.format(new Date(interval)));
  }
}

我得到以下结果:

Interval in millis: 1000
Expected result: 00:00:01
Result using Date and SimpleDateFormat: 01:00:01

我在GMT + 1时区。但它不应该反映在结果中。

当然可以使用System.out.printf解决,但我正在搜索的是原因。

3 个答案:

答案 0 :(得分:4)

  

我在GMT + 1时区。但不应该反映在结果中。

是什么让你这么认为? new Date(0)是格林威治标准时间1970年1月1日上午00:00。如果您的默认时区是GMT + 1,那么它是在凌晨01:00。

答案 1 :(得分:3)

  

我在GMT + 1时区。但它不应该反映在结果中。

然后你应该在SimpleDateFormat中设置时区。 SimpleDateFormat正在完全正确的事情 - 它正在及时格式化(在午夜 UTC 1970年之后)它所在的时区。

要更改时区,只需使用:

sdf.setTimeZone(TimeZone.getTimeZone("etc/UTC"));

目前尚不清楚是否确实正在使用SimpleDateFormat。您没有尝试格式化日期/时间 - 您尝试格式化间隔,给定您的变量名称。

我建议你使用Joda Time,它有一个很多更丰富的类型系统,并允许你表达你真正想要的东西。

此外,如果确实想要使用SimpleDateFormat,您可能希望在格式字符串中使用HH而不是hh。 (hh是一个12小时的值,1-12。你想要00:00:01,而不是12:00:01。)当你不时,hh很少适用在你的模式中有一个am / pm指示符。

答案 2 :(得分:1)

数据类型错误

您使用了错误的类。您正在尝试表示毫秒的持续时间和一天中的时间。都不适合Date类。该类表示一个时刻(在UTC中为日期和时间)。

Table of all date-time types in Java, both modern and legacy

另外,java.util.Date是一个糟糕的类,由不了解日期时间处理的人员设计。现在已过时。

java.time

现代解决方案使用 java.time 类。

LocalTime

具体来说,LocalTime使用一天中的24小时通用日期,没有日期,并且没有时区或UTC偏移量。

一般天的开始时间为00:00:00。为此,我们有一个常数:LocalTime.MIN。但是请注意,在不同的时区,不同的日期,一天可能会在另一个时间开始,例如01:00:00。

LocalTime lt = LocalTime.of( 15 , 30 ) ;  // 3:30 PM.

Duration

要表示未附加到时间轴上的时间跨度,请使用Duration类。

Duration d = Duration.ofMilliseconds( 1_000 ) ;

我们可以对日期时间对象进行数学运算。

LocalTime lt = LocalTime.MIN.plus( d ) ;

您应该知道 java.time 类使用的nanoseconds分辨率,比传统日期时间类使用的milliseconds更好。


关于 java.time

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

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

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

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容打下了基础。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore