java8中的datetime解析器格式

4sup72z8  于 2021-07-12  发布在  Java
关注(0)|答案(3)|浏览(305)

我试图解析一个datetimestamp,如下所示,但我找不到正确的解析器。有人能告诉我如何解析这些日期吗:

import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
public class HelloWorld{

     public static void main(String []args){
          int DAYS = 30;
         String date ="2021-04-23T12:09:56.123-07:00";
            DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
      .ofPattern("YYYY-MM-DD'T'hh:mm:ss.SSS±hh:mm");

        LocalDateTime localDateTime = LocalDateTime.parse(date, DATE_TIME_FORMATTER);
        System.out.println("Local Date" + localDateTime);
      LocalDateTime now = LocalDateTime.now();
      if (localDateTime.isBefore(now) && localDateTime.isAfter(now.plusDays(DAYS)))
        {
             System.out.println("Date is incorrect");
        }else{
             System.out.println("Success");
        }
     }
}

下面还有一些额外的细节:必须用ISO8601扩展格式表示为以下格式之一-yyyy-mm-ddthh:mm:ss[.sss]z,yyyy-mm-ddthh:mm:ss[.sss]±hh:嗯。其中,[.sss]是可选的,可以是1到3位数字。必须是未来不超过30天的值。万事达卡建议使用值(当前时间+30分钟)。最大长度-29。类型-字符串。示例:“2015-07-04t12:09:56.123-07:00”
请帮助我指定日期的正确格式。

pkbketx9

pkbketx91#

这里有3个不同的问题: ±hh:mm -根据 DateTimeFormatter (记住,阅读是基础!在提问之前一定要阅读javadoc!), ± 不是什么事。 hh 以及 mm 是事物,但不是“抵消时间”。表示tz偏移量的“模式”是一个字母;你很可能在找 Z . 但这通常不包括 : . LocalDateTime 不能表示偏移量,也不知道时区。如果你想要的话,你要找哪一个 ZonedDateTime 或者最有可能 OffsetDateTime .
您的模式不包括区域设置,这意味着它的输出,它可以解析什么,取决于运行此代码的计算机的区域设置,这听起来很糟糕。始终使用 .ofPattern("someString", Locale.ENGLISH) (或其他语言环境)除非您确实希望应用程序依赖于运行它的服务器的配置,这应该是非常罕见的。

8yoxcaq7

8yoxcaq72#

摆脱这种错误的模式(以及 DateTimeFormatter )使用一个 OffsetDateTime 而不是 LocalDateTime 无法存储有关偏移量的信息。
这是代码的转换(稍加调整和注解):

public static void main(String[] args) {
    String date = "2021-04-23T12:09:56.123-07:00";

    /*
     * no DateTimeFormatter needed due to default format of the String
     */

    // use an OffsetDateTime to parse a String with an offset
    OffsetDateTime odtParsed = OffsetDateTime.parse(date);
    // print it
    System.out.println("Parsed OffsetDateTime is " + odtParsed);
    // take the current instant as an OffsetDateTime at an offset of -7 hours
    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.ofHours(-7));

    // run your check and get a success
    if (odtParsed.isBefore(now) && odtParsed.isAfter(now.plusDays(DAYS))) {
        System.out.println("Date is incorrect");
    } else {
        System.out.println("Success");
    }
}

它打印出来了

Parsed OffsetDateTime is 2021-04-23T12:09:56.123-07:00
Success

提示:对于不同的格式,这将失败 String s。如果格式只有一点不同,您可以创建一个 DateTimeFormatter (通过 DateTimeFormatterBuilder )可以处理可选部件等。

编辑

如果只有一天的毫秒是可选的,并且偏移量的格式总是由加号或减号后跟两位数字表示小时、冒号和两位数字表示分钟组成,那么下面的示例可能显示了一种使其通用的足够方法:

public static void main(String[] args) {
    String date = "2021-04-23T12:09:56.123-07:00";
    String date1 = "2021-04-23T12:09:56.123+02:00";
    String date2 = "2021-04-23T12:09:56.123+00:00";
    String date3 = "2021-04-23T12:09:56-07:00";
    String date4 = "2021-04-23T12:09:56+02:00";
    String date5 = "2021-04-23T12:09:56+00:00";

    // DateTimeFormatter using optional millis of second
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[.SSS]xxx");

    // use an OffsetDateTime to parse a String with an offset
    OffsetDateTime odtParsed = OffsetDateTime.parse(date, dtf);
    OffsetDateTime odtParsed1 = OffsetDateTime.parse(date1, dtf);
    OffsetDateTime odtParsed2 = OffsetDateTime.parse(date2, dtf);
    OffsetDateTime odtParsed3 = OffsetDateTime.parse(date3, dtf);
    OffsetDateTime odtParsed4 = OffsetDateTime.parse(date4, dtf);
    OffsetDateTime odtParsed5 = OffsetDateTime.parse(date5, dtf);
    // print it
    System.out.println("Parsed OffsetDateTime is " + odtParsed);
    System.out.println("Parsed OffsetDateTime is " + odtParsed1);
    System.out.println("Parsed OffsetDateTime is " + odtParsed2);
    System.out.println("Parsed OffsetDateTime is " + odtParsed3);
    System.out.println("Parsed OffsetDateTime is " + odtParsed4);
    System.out.println("Parsed OffsetDateTime is " + odtParsed5);
}

输出:

Parsed OffsetDateTime is 2021-04-23T12:09:56.123-07:00
Parsed OffsetDateTime is 2021-04-23T12:09:56.123+02:00
Parsed OffsetDateTime is 2021-04-23T12:09:56.123Z
Parsed OffsetDateTime is 2021-04-23T12:09:56-07:00
Parsed OffsetDateTime is 2021-04-23T12:09:56+02:00
Parsed OffsetDateTime is 2021-04-23T12:09:56Z

如果你不想把零小时零分钟的偏移量作为 Z ,然后使用 DateTimeFormatter 对于这样的输出:

OffsetDateTime odtParsed5 = OffsetDateTime.parse(date5, dtf);

输出如下所示:

Parsed OffsetDateTime is 2021-04-23T12:09:56.000+00:00

即使它们都是零,也会打印出一天的毫秒数。

另一个编辑:

要检查日期是否在过去30天到将来30天的范围内,最好只使用日期部分:

public static void main(String[] args) {
    // the first part is already known from the examples above...
    String date = "2021-04-23T12:09:56.123-07:00";
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[.SSS]xxx");
    OffsetDateTime odtParsed = OffsetDateTime.parse(date, dtf);

    // get the current instant as an OffsetDateTime (in UTC == +00:00)
    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);

    /*
     * might be smart to keep time of day out of the calculation, so...
     */

    // get the date only out of the OffsetDateTime
    LocalDate today = now.toLocalDate();
    // create one for 30 days before
    LocalDate thirtyDaysBeforeToday = today.minusDays(30);
    // and one 30 days in the future
    LocalDate thirtyDaysInTheFuture = today.plusDays(30);
    // finally extract the date part from the parsed date time
    LocalDate d = odtParsed.toLocalDate();

    // make your checks using the LocalDates, maybe separate the two cases of an invalid date
    if (d.isBefore(thirtyDaysBeforeToday)) {
        System.err.println("Invalid date: too far in the past");
    } else if (d.isAfter(thirtyDaysInTheFuture)) {
        System.err.println("Invalid date: too far in the future");
    } else {
        System.out.println("Valid date");
    }
}

尝试不同的有效日期和无效日期。。。

pjngdqdw

pjngdqdw3#

您的文档使用± 也就是说 + 或者 - ,其占位符不是java占位符。只是使用 DateTimeFormatter.ISO_OFFSET_DATE_TIME .

相关问题