Java 如何将天数添加到DateTime zone

Java 如何将天数添加到DateTime zone,java,Java,我的输入日期为“2020-09-08T20:06:19-0400”;我按照下面的方法添加90天,最终格式应为“yyyy-MM-dd” 使用java.timepackage可以使它更简单 import java.time.LocalDate; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; 下面的代码是自我解释的: DateTimeFormatter formatter = DateTimeF

我的输入日期为“2020-09-08T20:06:19-0400”;我按照下面的方法添加90天,最终格式应为“yyyy-MM-dd”


使用
java.time
package可以使它更简单

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
下面的代码是自我解释的:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
OffsetDateTime offsetDateTime = OffsetDateTime.parse("2020-09-08T20:06:19-0400", formatter);
OffsetDateTime later = offsetDateTime.plusDays(90);
LocalDate localDate = later.toLocalDate();
String output = localDate.format(DateTimeFormatter.ISO_DATE);
System.out.println(output);

我建议您使用现代日期时间API来完成这项工作

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

public class Main {
    public static void main(String[] args) {
        String dateTimeStr = "2020-09-08T20:06:19-0400";
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        OffsetDateTime odt = OffsetDateTime.parse(dateTimeStr, inputFormatter);
        System.out.println("Given date time: " + odt);

        // 90 days later
        OffsetDateTime odt90DaysLater = odt.plusDays(90);
        System.out.println("90 days later (default format): " + odt90DaysLater);
        // In ISO_LOCAL_DATE format
        System.out.println("90 days later (yyyy-MM-dd): " + odt90DaysLater.toLocalDate());
        // Or this
        System.out.println("90 days later (yyyy-MM-dd): " + odt90DaysLater.format(DateTimeFormatter.ISO_LOCAL_DATE));
    }
}
输出:

Given date time: 2020-09-08T20:06:19-04:00
90 days later (default format): 2020-12-07T20:06:19-04:00
90 days later (yyyy-MM-dd): 2020-12-07
90 days later (yyyy-MM-dd): 2020-12-07
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        String dateTimeStr = "2020-09-08T20:06:19-0400";
        DateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ", Locale.ENGLISH);
        sdfInput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        Date date = sdfInput.parse(dateTimeStr);
        System.out.println("Given date time: " + sdfInput.format(date));

        // 90 days later
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 90);
        DateFormat sdfOutput = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
        sdfOutput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        System.out.println("90 days later: " + sdfOutput.format(calendar.getTime()));
    }
}
Given date time: 2020-09-08T20:06:19-0400
90 days later: 2020-12-07
有关现代日期时间API的更多信息,请访问

如果您是为您的Android项目执行此操作,并且您的Android API级别仍然不符合Java-8,请检查并重试

使用传统API:

Given date time: 2020-09-08T20:06:19-04:00
90 days later (default format): 2020-12-07T20:06:19-04:00
90 days later (yyyy-MM-dd): 2020-12-07
90 days later (yyyy-MM-dd): 2020-12-07
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        String dateTimeStr = "2020-09-08T20:06:19-0400";
        DateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ", Locale.ENGLISH);
        sdfInput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        Date date = sdfInput.parse(dateTimeStr);
        System.out.println("Given date time: " + sdfInput.format(date));

        // 90 days later
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 90);
        DateFormat sdfOutput = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
        sdfOutput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        System.out.println("90 days later: " + sdfOutput.format(calendar.getTime()));
    }
}
Given date time: 2020-09-08T20:06:19-0400
90 days later: 2020-12-07
输出:

Given date time: 2020-09-08T20:06:19-04:00
90 days later (default format): 2020-12-07T20:06:19-04:00
90 days later (yyyy-MM-dd): 2020-12-07
90 days later (yyyy-MM-dd): 2020-12-07
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        String dateTimeStr = "2020-09-08T20:06:19-0400";
        DateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ", Locale.ENGLISH);
        sdfInput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        Date date = sdfInput.parse(dateTimeStr);
        System.out.println("Given date time: " + sdfInput.format(date));

        // 90 days later
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 90);
        DateFormat sdfOutput = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
        sdfOutput.setTimeZone(TimeZone.getTimeZone("GMT-4"));
        System.out.println("90 days later: " + sdfOutput.format(calendar.getTime()));
    }
}
Given date time: 2020-09-08T20:06:19-0400
90 days later: 2020-12-07
建议:java.util的日期时间API及其格式化API
SimpleDateFormat
已经过时且容易出错。我建议您完全停止使用它们,并切换到。

您必须指定所需的时区 输出与您从其他答案中获得的结果相同,并且适用于北美时间:

2020-12-07

不要介意我的格式化程序。它比其他答案中的格式化程序长,因为我更喜欢重用内置的格式化程序。一个潜在的优势是我也可以接受几分之一秒,否则我的格式化程序的工作原理和其他的一样

角落案例:夏季过渡 虽然其他答案确实给出了正确的输出,但它们通过一条不太正确的路径到达那里。假设您的字符串在一天中的第一个小时:

    String inputDateTimeString = "2020-09-08T00:06:19-0400";

现在,东部时间90天后的夏季时间(DST)已经结束。我们从东部夏令时到东部夏令时。所以日期和时间是
2020-12-07T00:06:19-05:00
。如果忽略时区,您将得到
2020-12-07T00:06:19-04:00
,而在美国/多伦多的时区是
2020-12-06T23:06:19-05:00
,即前一天。因此,其他答案通过不正确的时区和不正确的时间组合来打印正确的日期。

其他一些带有分区Java时间的选项,加上天数

替代分区日期时间:

ZonedDateTime.parse("2020-09-08T20:06:19-0400", dtfInput).plusDays(90).format(DateTimeFormatter.ISO_LOCAL_DATE);
替代OffsetDateTime:

OffsetDateTime.parse("2020-09-08T20:06:19-0400", dtfInput).plusDays(90).format(DateTimeFormatter.ISO_LOCAL_DATE);
其中变量“dtfInput”是:

DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
测试台中的备选方案:

public static void main(String[] args) {
    String input = "2020-09-08T20:06:19-0400";
    DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);;
    String dateStampFromZoned = ZonedDateTime.parse(input, dtfInput).plusDays(90).format(DateTimeFormatter.ISO_LOCAL_DATE);
    String dateStampFromOffset = OffsetDateTime.parse(input, dtfInput).plusDays(90).format(DateTimeFormatter.ISO_LOCAL_DATE);
    System.out.printf("90 days later starting from date time '%s', %nprinted as only date in format 'yyyy-MM-dd':%n%n", input);
    System.out.println("Date stamp from ZonedDateTime: " + dateStampFromZoned);
    System.out.println("Date stamp from OffsetDateTime: " + dateStampFromOffset);
}
输出:

90 days later starting from date time '2020-09-08T20:06:19-0400',
printed as only date in format 'yyyy-MM-dd':

Date stamp from ZonedDateTime: 2020-12-07
Date stamp from OffsetDateTime: 2020-12-07
注意:java.time是在Java8中引入的

有关DateTimeFormatter.ISO_LOCAL_DATE和其他“预定义格式化程序”的更多信息,请访问:

另请注意:如果inputDateTime“2020-09-08T20:06:19-0400”被编写为ISO_OFFSET_DATE_TIME(预定义的格式化程序),那么我们不需要指定inputDateTime的格式,请参见下面的示例:

ZonedDateTime.parse("2020-09-08T20:06:19-04:00").plusDays(90).format(DateTimeFormatter.ISO_LOCAL_DATE);

区域偏移格式中只有分号不同,其中inputDateTime写为“2020-09-08T20:06:19-0400”,ISO_offset_DATE_TIME写为“2020-09-08T20:06:19-04:00”.

请解释更多关于您在这里遇到的问题。有没有更好的方法来编写代码?我投票结束这个问题,因为OP忘了问问题。另外,如果加上90天,您将得到12月8日,而两个答案似乎都是12月7日。哪个是正确的?或者更准确地说:您想要哪一个?为什么?如果您使用的是
以后的.toLocalDate()
,则不需要使用
DateTimeFormatter.ISO\u DATE
。默认情况下,
LocalDate#toString
会给出
yyyy-MM-dd
的结果。@ArvindKumarAvinash是正确的。或者反过来说:您不需要首先转换为
LocalDate
。只需稍后执行
即可。格式化(DateTimeFormatter.ISO_LOCAL_DATE)
以获得所需的
2020-12-07
。我没有。我不能使用现代日期时间API吗?@user739115-你应该努力使用现代日期时间API。正如回答中提到的,传统日期-时间API容易出错,因此您应该尽量避免使用传统日期-时间API。我对Ole的这句话感到困惑:“当添加90天时,您也会得到12月8日,而这两个答案似乎都得到12月7日。哪一个是正确的?或者更准确地说:您想要哪一个以及为什么?”你在这个答案中看到的结果是正确的,但是Ole提到了你在问题中的评论。您已经提到,
//获取新输入日期为2020年12月8日星期二05:36:19,因此我必须将其更改为您问题中所需的格式,即“yyyy-MM-dd”
,他的评论指向它。简言之,他想知道你是想在IST中得到结果,还是想在区域偏移量-0400`处得到结果。我的问题是一个伪装的时区问题(很抱歉,不清楚)。在字符串表示的时间点之后的90天,它是印度的12月8日(IST)和12月7日的偏移量-04:00,即字符串中的偏移量。您想要哪个时区或偏移量作为结果@用户739115