在Android中生成两个日期之间的日期

15

如何在Android中获取两个日期之间的所有日期。

例如,我有两个字符串。

String first="2012-07-15";  
String second="2012-07-21"; 

我进行字符串转换并获取日期信息。

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");                                    
DateFormat df2 = new SimpleDateFormat("MMM dd");
String mydate = df2.format(df1.parse(first));

这样我可以从第一个和第二个字符串中获取两个日期。

现在,我还要显示这两个日期之间的所有日期。


3
可能是重复问题:如何在Java中将日期增加一天? - 您可以在循环中运行增量以创建日期系列。 - assylias
也许在Android中还不可用,但在常规Java中使用LocalDate::datesUntilLocalDate.parse( "2012-07-15" ).datesUntil( "2012-07-21" )会产生一个Stream<LocalDate> - Basil Bourque
对于新读者,我建议不要使用SimpleDateFormatDate。这些类设计得很差,而且已经过时了,前者尤其令人头疼。相反,使用来自java.time,现代Java日期和时间APILocalDateDateTimeFormatter - Ole V.V.
5个回答

51

在日期计算中最好不要使用硬编码的值。我们可以依赖于Java Calendar类的方法来完成这个任务。

查看代码:

private static List<Date> getDates(String dateString1, String dateString2)
{
    ArrayList<Date> dates = new ArrayList<Date>();
    DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");

    Date date1 = null;
    Date date2 = null;

    try {
        date1 = df1 .parse(dateString1);
        date2 = df1 .parse(dateString2);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);


    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);

    while(!cal1.after(cal2))
    {
        dates.add(cal1.getTime());
        cal1.add(Calendar.DATE, 1);
    }
    return dates;
}

然后按以下方式使用它

    List<Date> dates = getDates("2012-02-01", "2012-03-01");
    for(Date date:dates)
        System.out.println(date);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd"); 这行代码对我来说是不兼容的。当我将其更改为 SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd"); 时,它就可以正常工作了。 - Akhila
@AkhilaMadari,你需要使用java.text.DateFormatjava.text.SimpleDateFormat这两个类。请检查你是否从正确的包中导入了这些类。 - sunil
1
完美解决方案 - Mohd Sakib Syed

2
public class DummyWorks extends Activity 
{
static final long ONE_DAY = 24 * 60 * 60 * 1000L;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    getDatesBetween("03/23/2011","03/28/2011");
}

public static void getDatesBetween(String startDate,String endDate) {


    long  from=Date.parse(startDate);  

    long to=Date.parse(endDate);  

    int x=0;

    while(from <= to) {
          x=x+1;
          System.out.println ("Dates  : "+new Date(from));
          from += ONE_DAY;
    }
    System.out.println ("No of Dates  :"+ x);


 }
}

将毫秒添加到日期中会带来高风险,因为夏令时和其他奇怪的时区更改可能导致失败。 - assylias
谢谢@assylias,我现在测试了一下。在更改“long ONE_DAY”后,它得到了正确的结果。 - Ram kiran Pachigolla
你好,@Ramkiran,感谢您的回复。但是我在long from = Date.parse(startDate);处出现了错误,它说java.illegalArgumentException在java.util.Date.parse处。 - Hardik Joshi
我的日期格式是2012-07-15。我需要按照你的日期格式进行格式化,我需要在这个函数中添加什么? - Hardik Joshi
是的,我认为这就是我出错的原因。getDatesBetween()函数有什么变化? - Hardik Joshi

1

通过解糖使用java.time

考虑使用现代Java日期和时间API的java.time来处理日期。 LocalDate是用于日期(不包括时间)的类。我假设您想要包括给定的两个日期。

    String first = "2012-07-15";
    String second = "2012-07-21";
    
    List<LocalDate> dates = LocalDate.parse(first)
            .datesUntil(LocalDate.parse(second).plusDays(1))
            .collect(Collectors.toList());
    
    System.out.println(dates);

输出:

[2012-07-15, 2012-07-16, 2012-07-17, 2012-07-18, 2012-07-19, 2012-07-20, 2012-07-21]

LocalDate.datesUntil() 给我们提供了一个日期流,不包括指定的结束日期,因此我们需要加一天来包含它。

我利用了你的字符串符合 ISO 8601 格式这一事实,而且 LocalDate 默认解析该格式,即不需要任何显式格式化器。

或通过 ThreeTenABP

如果由于某种原因您正在使用 ThreeTenABP 库而不是 desugaring,则在这种情况下请使用循环。

    List<LocalDate> dates = new ArrayList<>();
    LocalDate currentDate = LocalDate.parse(first);
    LocalDate lastDate = LocalDate.parse(second);
    while (! currentDate.isAfter(lastDate )) {
        dates.add(currentDate);
        currentDate = currentDate.plusDays(1);
    }

[2012年7月15日,2012年7月16日,2012年7月17日,2012年7月18日,2012年7月19日, 2012年7月20日,2012年7月21日]

问题:Java.time需要Android API级别26吗?

Java.time在旧版和新版的Android设备上都可以很好地运行。它只需要至少Java 6

  • 在Java 8及更高版本以及API级别为26或更高版本的较新的Android设备上,现代API已内置。
  • 在非Android Java 6和7中,使用ThreeTen Backport,即现代类的后移版本(JSR 310的ThreeTen;请参见底部链接)。
  • 在旧版的Android上,可以使用desugaring或ThreeTen Backport的Android版本。后者称为ThreeTenABP。在这种情况下,请确保从org.threeten.bp导入日期和时间类以及子包。

链接


1
在 Kotlin 中的解决方案: 它将返回两个日期之间的日期列表。
 fun getDatesBetween(dateString1:String, dateString2:String):List<String> {
        val dates = ArrayList<String>()
        val input = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        var date1:Date? = null
        var date2:Date? = null
        try
        {
            date1 = input.parse(dateString1)
            date2 = input.parse(dateString2)
        }
        catch (e:ParseException) {
            e.printStackTrace()
        }
        val cal1 = Calendar.getInstance()
        cal1.time = date1
        val cal2 = Calendar.getInstance()
        cal2.time = date2
        while (!cal1.after(cal2))
        {
            val output = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            dates.add(output.format(cal1.time))
            cal1.add(Calendar.DATE, 1)
        }
        return dates
    }

0
        val currentDateCalendar = Calendar.getInstance()
        val mCurrentDate = getDateChanger(currentDateCalendar.time, "yyyy-MM-dd")
        currentDateCalendar.add(Calendar.MONTH, 1)
        val oneMonthNextCalendar = currentDateCalendar
        val mNextDate = getDateChanger(oneMonthNextCalendar.time, "yyyy-MM-dd")

        val mDates = datesBetween(
            mCurrentDate,
            mNextDate,
            "yyyy-MM-dd"
        )
        for (date in mDates)
            Log.i("DatesBetween",date)





 @SuppressLint("SimpleDateFormat")
    fun getDateChanger(mDate:Date,formatter: String): String {
        val dateFormat = SimpleDateFormat(formatter)
        return dateFormat.format(mDate)
    }

    @SuppressLint("SimpleDateFormat")
    fun datesBetween(startDate: String, endDate: String,formatter: String): List<String> {
        val dates = ArrayList<String>()
        val dateFormat: DateFormat = SimpleDateFormat(formatter)
        var sDate: Date? = null
        var eDate: Date? = null
        try {
            sDate = dateFormat.parse(startDate)
            eDate = dateFormat.parse(endDate)
        } catch (e: ParseException) {
            e.printStackTrace()
        }
        val sCalendarDate = Calendar.getInstance()
        sCalendarDate.time = sDate!!
        val eCalendarDate = Calendar.getInstance()
        eCalendarDate.time = eDate!!
        while (!sCalendarDate.after(eCalendarDate)) {
            dates.add(dateFormat.format(sCalendarDate.time))
            sCalendarDate.add(Calendar.DATE, 1)
        }
        return dates
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接