乔达时间plusDays错误的日期

问题描述

我正在使用以下代码

 DateTime(date)//Thu Aug 06 00:00:00 GMT+03:00 2020
                .plusDays(days) // 103
                .toDate()

结果是Fri Dec 18 23:00:00 GMT+02:00 2020而不是Dec 19。 在某些日期上它可以很好地工作,而在其他日期上则可以得到日期-1,我想问题出在一个月中的天数,但是plusDays()不考虑吗?

解决方法

您可以使用java.time,并且较低的Android API也支持它,因为现在有API desugaring in Android

有一个可识别区域的类(java.time.ZonedDateTime)和一个可识别偏移的类(java.time.OffsetDateTime),但是您的示例String仅包含GMT / UTC的偏移量。这就是为什么我要使用OffsetDateTime来解析确切的时间并添加一天的原因。

这是一个简单的示例,它定义了一个格式化程序,该格式化程序将解析给定的String并将其用于输出:

public static void main(String[] args) {
    // example String
    String date = "Fri Dec 18 23:00:00 GMT+02:00 2020";
    // create a formatter that is able to parse and output the String
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss OOOO uuuu",Locale.ENGLISH);
    // parse the String using the formatter defined above
    OffsetDateTime odt = OffsetDateTime.parse(date,dtf);
    System.out.println("OffsetDateTime parsed is\t" + odt.format(dtf));
    
    // add a day to the date part
    OffsetDateTime dayLater = odt.plusDays(1);
    System.out.println("Adding a day results in\t\t" + dayLater.format(dtf));
}

此输出

OffsetDateTime parsed is    Fri Dec 18 23:00:00 GMT+02:00 2020
Adding a day results in     Sat Dec 19 23:00:00 GMT+02:00 2020

如果您只想输出日期(没有时间部分或偏移量),那么在这些类中还有另外一件方便的事情,那就是容易提取日期或时间部分。例如,您可以使用OffsetDateTime进行以下操作:

// extract the part that only holds information about day of month,month of year and year
LocalDate dateOnly = odt.toLocalDate();
// print the default format (ISO standard)
System.out.println(dateOnly);
// or define and use a totally custom format
System.out.println(dateOnly.format(
                        DateTimeFormatter.ofPattern("EEEE,'the' dd. 'of' MMMM uuuu",Locale.ENGLISH)
                    )
);

那会输出

2020-12-18
Friday,the 18. of December 2020

如果您要处理的是DatePicker datePicker,则可以通过getYear()getMonth()getDayOfMonth()接收选定的值,然后创建一个

LocalDate localDate = LocalDate.of(datePicker.getYear(),datePicker.getMonth(),datePicker.getDayOfMonth());

,然后只需在localDate.plusDays(1);之前添加一天

,

我猜有些日期可以很好地工作,而其他日期可以是日期1 问题是一个月中的天数,但是plusDays()没有 考虑吗?

它会考虑。您提到的两个日期时间字符串的问题在于它们属于不同的Zone-Offset(第一个是UTC + 3,第二个是UTC + 2)。下面给出了如何在相同的Zone-Offset下进行操作。

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
        DateTime dateTime = DateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020",formatter);
        System.out.println(dateTime);
        // With Zone-Offset of UTC+2
        System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));

        // Add 103 days
        DateTime dateTimeAfter103Days = dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);
        System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));
    }
}

输出:

2020-08-05T21:00:00.000Z
2020-08-05T23:00:00.000+02:00
2020-11-16T21:00:00.000Z
2020-08-05T23:00:00.000+02:00

我建议您使用modern java.time日期时间API和相应的格式API(软件包java.time.format)。从 Trail: Date Time 了解有关现代日期时间API的更多信息。如果您的Android API级别仍不兼容Java8,请检查How to use ThreeTenABP in Android ProjectJava 8+ APIs available through desugaring

下表显示了overview of modern date-time classesenter image description here

使用现代的日期时间API:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Define formatter for your date-time string
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O u");

        // Parse the given date0-time string into OffsetDateTime object
        OffsetDateTime dateTime = OffsetDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020",formatter);
        System.out.println(dateTime);

        // Add 103 days to the OffsetDateTime object
        OffsetDateTime dateTimeAfter103Days = dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);
    }
}

输出:

2020-08-06T00:00+03:00
2020-11-17T00:00+03:00

或者,

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Define formatter for your date-time string
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");

        // If you do not need Zone Id or Zone Offset information,you can go for
        // LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020",formatter);
        System.out.println(dateTime);

        // You can convert LocalDateTime object into an OffsetDateTime by applying the
        // Zone-Offset e.g. the following line applies UTC+03:00 hours to LocalDateTime
        OffsetDateTime odt = dateTime.atOffset(ZoneOffset.ofHours(3));
        System.out.println(odt);

        // Add 103 days to the LocalDateTime object
        LocalDateTime dateTimeAfter103Days = dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);

        odt = dateTimeAfter103Days.atOffset(ZoneOffset.ofHours(3));
        System.out.println(odt);
    }
}

输出:

2020-08-06T00:00
2020-08-06T00:00+03:00
2020-11-17T00:00
2020-11-17T00:00+03:00

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...