Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用T和Z将LocalDate格式化为ISO 8601?_Java_Datetime_Datetime Format_Localdate_Datetimeformatter - Fatal编程技术网

Java 如何使用T和Z将LocalDate格式化为ISO 8601?

Java 如何使用T和Z将LocalDate格式化为ISO 8601?,java,datetime,datetime-format,localdate,datetimeformatter,Java,Datetime,Datetime Format,Localdate,Datetimeformatter,我正在尝试生成一个随机日期和时间,并将其转换为格式“yyyy-MM-dd'T'HH:MM:ss'Z” 以下是我尝试过的: public static String generateRandomDateAndTimeInString() { LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70)))); System.out.println("date a

我正在尝试生成一个随机日期和时间,并将其转换为
格式“yyyy-MM-dd'T'HH:MM:ss'Z”

以下是我尝试过的:

  public static String generateRandomDateAndTimeInString() {
    LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
    System.out.println("date and time :: " + date.toString());
    return formatDate(date) ;
  }

  public static String formatDate(LocalDate date){
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    return dateFormat.format(date);
  }
但在
dateFormat.format(date)
行中,它抱怨:

java.lang.IllegalArgumentException:无法将给定对象格式化为日期

第二个问题是,打印输出不包含时间:

date :: 1998-12-24 

我不知道如何让它工作。

如果你想忽略时间部分,那么你可以像这样使用
ZoneDateTime

DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
return ZonedDateTime.of(
        date, 
        LocalTime.MIN, 
        ZoneId.of("Europe/Paris")
).format(dateFormat);
输出示例

2013-10-19T00:00:00+0200
或者更好的是,您可以使用
toString
以字符串的形式获取格式化日期,默认格式为
ZonedDateTime

return ZonedDateTime.of(
        date,
        LocalTime.MIN,
        ZoneId.of("Europe/Paris")
).toString();
输出

2013-10-19T00:00+02:00[Europe/Paris]
注意

2013-10-19T00:00:00+0200
时间部分的日期始终为
00:00:00
,因为我们使用的是
LocalTime.MIN

另外,您可以将
ZoneId
更改为预期的
区域,这只是一个示例

重要

2013-10-19T00:00+02:00[Europe/Paris]
DateFormat
SimpleDateFormat
是传统的库,因此请不要将它们与
java.time
库混用,在顶部,您使用的是
LocalDate
,这意味着您正在使用这个
java.time
库,所以在所有代码中都要使用它。

千万不要使用
SimpleDateFormat
格式化
java.time
类型 使用
SimpleDataFormat
,您应该只格式化遗留日期时间类型,例如
java.util.date
。为了格式化
java.time
date-time类型,您需要使用

切勿将
Z
括在单引号内
以一种格式将
Z
括在单引号内是一个错误。符号
Z
代表
zulu
并指定
UTC+00:00
。如果将其括在单引号内,则它仅表示字符文字,
Z
,在解析时不会起到
UTC+00:00
的作用

您不需要显式地使用格式化程序 对于此要求,您不需要显式使用格式化程序,因为
OffsetDateTime#toString
已经以您需要的格式返回字符串。但是,如果
OffsetDateTime
对象中的秒数为零,则相同和后续较小的单位将被
OffsetDateTime\toString
截断。如果您需要完整格式,而不考虑秒的值,那么当然,您必须使用
DateTimeFormatter

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        System.out.println(generateRandomDateAndTimeInString());
    }

    public static String generateRandomDateAndTimeInString() {
        LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
        System.out.println("date and time :: " + date.toString());
        return formatDate(date);
    }

    public static String formatDate(LocalDate date) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
        // return date.atStartOfDay().atOffset(ZoneOffset.UTC).toString();
        return date.atStartOfDay().atOffset(ZoneOffset.UTC).format(dtf);
    }
}
运行示例:

date and time :: 1996-09-05
1996-09-05T00:00:00Z
请注意,
java.util
的日期时间API及其格式化API
SimpleDataFormat
已经过时,并且容易出错。建议完全停止使用,并切换到

  • 无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7
  • 如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认
了解有关现代日期时间API的更多信息

如果出于任何原因仍需要使用
SimpleDataFormat
: 使用
ZoneOffset.UTC
并在一天开始时将
LocalDate
转换为
zoneDateTime
➡️ 将
zoneDateTime
转换为
Instant
➡️ 从
Instant
获取
java.util.Date
对象

public static String formatDate(LocalDate date) {
    Date utilDate = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
    return dateFormat.format(utilDate);
}
示例输出:

日期和时间:1983-08-24T00:00Z

注意事项:

  • 让java.time将年转换为天。它提供了更可读、更正确的代码(一年并不总是365天)
  • 要在字符串中包含日期时间和UTC偏移量,请转换
    ZonedDateTime
    OffsetDateTime
    ,因为此类对象包含日期时间和偏移量。一个
    LocalDate
    没有。这是一个没有时间的日期,也没有UTC的偏移量。您请求的
    Z
    表示与UTC的偏移量为0
如果你想在输出中包含小时、分钟和秒,你可以通过计算秒而不是天数来实现。在这种情况下,对整个操作使用
OffsetDateTime
(或
ZonedDateTime
如果在与UTC不同的时区)

日期和时间:1996-09-21T06:49:56Z


我使用的是
ThreadLocalRandom
,因为它可以在指定的时间间隔内生成一个随机长值。有趣的是,
ThreadLocalRandom
有很多方便的方法,
Random
没有。

这能回答你的问题吗?
LocalDate
只有一天、一个月和一年。如果您也想要一天中的时间,请考虑使用
LocalDateTime
,如果您想要偏移量或时区,请查看
OffsetDateTime
ZoneDateTime
。所有这些都可以通过合适的
DateTImeFormatter
从/到
String
进行解析和格式化。不再需要
SimpleDateFormat
了……将
Z
括在一个格式的单引号中是一个错误。请更正。谢谢@LiveandLetLive我更改它;)感谢您的回复,请您使用较新的
java.util.Calendar
来写一个答案好吗?
java.util.Calendar
java.util.Date
之上的另一个黑客程序。我建议您不要使用它,因为您已经在使用现代日期时间API。不要将容易出错的
java.util
date-time API与之混合使用。如果您坚持,我可以在几分钟内为您提供相同的内容。@杰夫-我在回答的末尾添加了一个部分,只是因为您提出了要求,但正如我反复提到的,不要对任何生产代码使用
java.util
date-time API。它们很容易出错,决不应与现代技术混为一谈