使用可选部件格式化日期

时间:2016-09-29 05:53:56

标签: java date-format

我正在寻找一个干净的解决方案来格式化带有可选部分的Date个对象。我的日期对象可以是时间戳值,仅时间值或仅日期值。

预期输出

我想像这样显示日期值:

如果日期的ms value小于(86400 * 1000),则表示该值实际上是一个仅限时间的值。如果是这样显示:

HH:mm:ss.SSS

如果日期的值恰好是午夜,则表示它是仅限日期的值。如果是这样显示:

yyyy-MM-dd

否则显示如下:

yyyy-MM-dd HH:mm:ss.SSS

解决方案约束

不幸的是我正在使用Date作为输入。无法改变。我只对格式化/渲染感兴趣,而不是解析。外部图书馆在我的组织中很难卖。

为了格式化,当然可以接受首先转换为新的Java 8日期/时间对象之一,如果这样可以使解决方案更简单。

平台:Java 8 SE

4 个答案:

答案 0 :(得分:3)

第一步

Date转换为Java 8等效结构:

private static TemporalAccessor toJava8Time(Date date) {
    Instant instant = date.toInstant();

    if (instant.isBefore(Instant.ofEpochSecond(86400))) {
        return instant.atZone(ZoneId.systemDefault()).toLocalTime();
    } else if (instant.equals(instant.truncatedTo(ChronoUnit.HOURS))) {
        return instant.atZone(ZoneId.systemDefault()).toLocalDate();
    } else {
        return instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
    }
}

第二步

创建一个足够通用的格式化程序,以根据需要对LocalTimeLocalDateLocalDateTime进行字符串化:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd] [HH:mm:ss]");

用法

Date time = new Date(39733000L); // 1970-01-01T12:02:13
Date date = new Date(1462399200000L); // 2016-05-05T00:00:00
Date dateTime = new Date(1462442533000L); // 2016-05-05T12:02:13

Stream.of(time, date, dateTime)
        .map(d -> toJava8Time(d))
        .map(t -> formatter.format(t).trim())
        .forEach(System.out::println);

//Outputs "12:02:13", "2016-05-05", "2016-05-05 12:02:13"

注意:我必须拨打trim(),否则时间会以空格开头。

答案 1 :(得分:1)

而不是java.util.Date使用java.time包中的相应类。这意味着您可以为LocalDateLocalTimeLocalDateTime明确地设置单独的方法,并使代码更清晰。

现在,如果你遇到java.util.Date并且你无能为力,你应该使用getTime()方法(你已经知道的)来决定{{3}每种输出类型的实现。

答案 2 :(得分:0)

您可以尝试导入并使用与此类似的SimpleDateFormat

import java.sql.Time;

public class Example {
    public static void main(String[] args) {
        Time ex = new Time( Date.getTime() ); //param: long
        System.out.println(ex.toString()); // prints 00:05:28
    }
}

编辑:Joe C的解决这个问题的方法可以说比我的实现更好。

答案 3 :(得分:0)

我认为你需要多个SimpleDateFormat对象。您的代码可能如下所示:

SimpleDateFormat timeOnlySdf = new SimpleDateFormat( "HH:mm:ss.SSS");
SimpleDateFormat dateOnlySdf = new SimpleDateFormat( "yyyy-MM-dd");
SimpleDateFormat dateAndTimeSdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS");

Date epochPlusOne = new Date( 86400 * 1000);
Calendar cal = Calendar.getInstance();
cal.setTime( myDate);

if( myDate.before( epochPlusOne))
{
    System.out.println( timeOnlySdf.format( myDate));
}
else if( cal.get( Calendar.HOUR) == 0 && 
        cal.get( Calendar.MINUTE) == 0 && 
        cal.get( Calendar.SECOND) == 0 && 
        cal.get( Calendar.MILLISECOND) == 0)
{
    System.out.println( dateOnlySdf.format( myDate));
}
else
{
    System.out.println( dateAndTimeSdf.format( myDate));
}