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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42581628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:44:46  来源:igfitidea点击:

Set hours minutes and seconds to 00 in ZonedDateTime or Instant

javadatejava-8zoneddatetime

提问by WitVault

I have a date string in Utc format -

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

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

And I want to convert it to below format in Java date representation in ZonedDateTime.

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

When ZonedDateTimeis printed it should show

ZonedDateTime打印出来时,它应该显示

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

I have tried following code -

我试过以下代码 -

    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);

Output:

输出:

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]

I want the start time to be normalized in ZonedDateTime. I want to achieve it using java libraries only not any third party library.

我希望在 ZonedDateTime 中标准化开始时间。我只想使用 java 库而不是任何第三方库来实现它。

回答by Basil Bourque

tl;dr

tl;博士

You are working too hard.

你工作太辛苦了。

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

2017-03-03T00:00.00Z

2017-03-03T00:00.00Z

Details

细节

What does "normalized in ZonedDateTime" mean? Please edit your Question to clarify.

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

When ZonedDateTime is printed it should show … "2017-03-03T00:00:00.000Z"

当 ZonedDateTime 打印出来时,它应该显示……“2017-03-03T00:00:00.000Z”

What you are asking is a contradiction. A ZonedDateTimehas an assigned time zone for when you want to view a moment though the wall-clock time of a particular region. So asking for a ZonedDateTimeto generate a string in UTC such as "2017-03-03T00:00:00.000Z"makes no sense. The Zis short for Zuluand means UTC.

你问的是矛盾的。AZonedDateTime具有指定的时区,供您通过特定区域的挂钟时间查看某个时刻。因此,要求 aZonedDateTime以 UTC 格式生成字符串"2017-03-03T00:00:00.000Z"是没有意义的。TheZZuluUTC 的缩写,表示 UTC。

Your input string is in standard ISO 8601 format. The java.time classes use these standard formats by default. So no need to specify a formatting pattern, no need for the DateTimeFormatterclass.

您的输入字符串采用标准 ISO 8601 格式。java.time 类默认使用这些标准格式。所以不需要指定格式模式,不需要DateTimeFormatter类。

Parse as an Instant, a point on the timeline in UTC with a resolution of nanoseconds.

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

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

If you want midnight in UTC, truncate.

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

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

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

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

No need for the ZonedDateTimeclass.

不需要ZonedDateTime上课。

If you want to work with a date-only without any time-of-day and without a time zone, use the LocalDateclass.

如果您想使用没有任何时间和时区的仅日期,请使用LocalDate该类。

By the way, do not assume the first moment of the day is always 00:00:00. That is true for UTC. But various time zones may have anomalies such as Daylight Saving Time (DST) where the day may start at another time-of-day such as 01:00:00.

顺便说一句,不要假设一天中的第一个时刻总是00:00:00。这对于 UTC 来说是正确的。但是,不同的时区可能存在异常,例如夏令时 (DST),其中一天可能从另一个时间开始,例如01:00:00



About java.time

关于 java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

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

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多

回答by hartar

   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  );

EDIT new method :

编辑新方法:

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);

You juste need to get all your necessary fields. With, for example, a dateFormat.

您只需要获取所有必需的字段。例如,使用 dateFormat。

Hope it will help you

希望它会帮助你

回答by mir

You can simply do:

你可以简单地做:

DateUtils.truncate(yourDate, Calendar.DAY_OF_MONTH);

Hope this will help you

希望能帮到你