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

Jef*_*eff 4 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 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);
  }
Run Code Online (Sandbox Code Playgroud)

但在该行中dateFormat.format(date),它抱怨:

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

第二个问题是,print的输出不包含时间:

date :: 1998-12-24 
Run Code Online (Sandbox Code Playgroud)

我不知道如何让它工作。

Arv*_*ash 8

永远不要java.time使用格式化类型SimpleDateFormat

使用SimpleDateFormat,您应该只格式化旧的日期时间类型,例如java.util.Date. 为了格式化java.time日期时间类型,您需要使用DateTimeFormatter.

切勿用Z单引号括起来

Z以某种格式将单引号括起来是一个错误。符号Z代表zulu并指定UTC+00:00。如果将其括在单引号中,则它仅表示字符文字,Z并且不会像UTC+00:00解析那样起作用。

您不需要显式使用格式化程序

对于此要求,您不需要显式使用格式化程序,因为OffsetDateTime#toString已经以您需要的格式返回字符串。然而,如果数目在一个OffsetDateTime目的是零,相同的和随后的更小的单位通过截断OffsetDateTime#toString。如果您需要完整格式而不考虑seconds的值,那么当然,您将不得不使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

示例运行:

date and time :: 1996-09-05
1996-09-05T00:00:00Z
Run Code Online (Sandbox Code Playgroud)

请注意,日期时间 APIjava.util及其格式化 APISimpleDateFormat已过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API

Trail: Date Time 中了解有关现代日期时间 API 的更多信息。

如果您SimpleDateFormat出于任何原因仍需要使用:

在一天开始时转换LocalDateZonedDateTimewithZoneOffset.UTC和 ?? 转换ZonedDateTimeInstant?? 获取java.util.Date对象Instant

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);
}
Run Code Online (Sandbox Code Playgroud)