在ZonedDateTime或Instant中将小时分和秒设置为00

时间:2017-03-03 14:36:31

标签: java date java-8 zoneddatetime

我有一个Utc格式的日期字符串 -

    String dateStr = "2017-03-03T13:14:28.666Z";

我想在 ZonedDateTime 的Java日期表示中将其转换为以下格式。

打印 ZonedDateTime 时,应显示

    String dateStr = "2017-03-03T00:00:00.000Z";

我尝试过以下代码 -

    String timeZone = "America/Los_Angeles";
    DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZoneId zoneId1 = ZoneId.of(timeZone);
    String dateStr = "2017-03-03T13:14:28.666Z";
    Instant inst = Instant.parse(dateStr, dtf2);


    ZonedDateTime dateTimeInTz = ZonedDateTime.ofInstant(inst, zoneId1);

    ZonedDateTime startTime = dateTimeInTz.with(LocalTime.of(0, 0, 0, 0));
    ZonedDateTime endTime = dateTimeInTz.with(LocalTime.MAX);

    System.out.println("Start:"+startTime+", End:"+endTime);
    System.out.println("Start:"+startTime.toString()+", End:"+endTime.toString());  

    ZonedDateTime nT = ZonedDateTime.of ( LocalDate.parse(dateStr, dtf1) , LocalTime.of (0,0,0,0) , ZoneId.of ( timeZone ) );

    System.out.println("Start:"+nT);

输出:

Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles]

我希望在ZonedDateTime中对开始时间进行规范化。 我想使用java库而不是任何第三方库来实现它。

4 个答案:

答案 0 :(得分:18)

TL;博士

你工作太辛苦了。

Instant.parse( "2017-03-03T13:14:28.666Z" )
       .truncatedTo( ChronoUnit.DAYS )
       .toString()
  

2017-03-03T00:00.00Z

详细

“在ZonedDateTime中规范化”是什么意思?请编辑您的问题以澄清。

  

打印ZonedDateTime时,应显示......“2017-03-03T00:00:00.000Z”

你所问的是一个矛盾。 ZonedDateTime有一个指定的时区,用于查看特定区域的挂钟时间。因此,要求ZonedDateTime生成UTC中的字符串(例如"2017-03-03T00:00:00.000Z")是没有意义的。 ZZulu的缩写,表示UTC。

您的输入字符串采用标准ISO 8601格式。默认情况下,java.time类使用这些标准格式。因此无需指定格式化模式,不需要DateTimeFormatter类。

解析为Instant,UTC时间轴上的一个点,分辨率为纳秒。

Instant instant = Instant.parse( "2017-03-03T13:14:28.666Z" );

如果你想要UTC的午夜,请截断。

Instant instantMidnightUtc = instant.truncatedTo( ChronoUnit.DAYS );
  

instantMidnightUtc.toString():2017-03-03T00:00.00Z

不需要ZonedDateTime类。

如果您想在没有任何时间且没有时区的情况下使用仅限日期,请使用LocalDate课程。

顺便说一下,不要假设一天中的第一时刻总是00:00:00。对于UTC来说也是如此。但是,各个时区可能会出现异常情况,例如夏令时(DST),其中一天可能会在另一个时间点开始,例如01:00:00

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

   String timeZone = "America/Los_Angeles";
    DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZoneId zoneId1 = ZoneId.of(timeZone);
    String dateStr = "2017-03-03T13:14:28.666Z";
    Instant inst = Instant.parse(dateStr, dtf2);


    ZonedDateTime dateTimeInTz = ZonedDateTime.ofInstant(inst, zoneId1);

    ZonedDateTime startTime = dateTimeInTz.with(LocalTime.of(0, 0, 0, 0));
    ZonedDateTime endTime = dateTimeInTz.with(LocalTime.MAX);

    String strStart = (startTime.toString().split("T"))[0] + "T00:00:00.000Z";
    String strEnd  =  (endTime.toString().split("T"))[0] + "T00:00:00.000Z";

    System.out.println("Start:"+strStart +", End:"+strEnd  );

编辑新方法:

TimeZone timeZone = TimeZone.getTimeZone("Europe/Copenhagen");
Calendar cal = Calendar.getInstance(timeZone);
Calendar defaut = new GregorianCalendar( cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),0,0,0);

你需要获得所有必要的领域。例如,使用dateFormat。

希望它能帮到你

答案 2 :(得分:-1)

这里是:

ZonedDateTime.now().withHour(0).withMinute(0).withSecond(0)

答案 3 :(得分:-2)

您可以这样做:

DateUtils.truncate(yourDate, Calendar.DAY_OF_MONTH);

希望这会对你有所帮助