如何在 Kotlin 中生成一个 Date 对象数组?

huangapple go评论83阅读模式
英文:

How to generate an array of Date objects in Kotlin?

问题

private fun dateArray(): List<Date> {
    val currentDate = Date()
    val dateList = ArrayList<Date>()

    for (i in 0..9) {
        val daysAgo = i * 5
        val newDate = Date(currentDate.time - daysAgo * 24 * 60 * 60 * 1000)
        dateList.add(newDate)
    }

    return dateList
}

这种方式太繁琐了。我敢打赌 Kotlin 能提供更优雅的方式。

英文:

I want to generate an array of date objects Kotlin style, from current day descending each 5 days programmatically:

> {now, 5_days_ago, 10_days_ago, etc..}

private fun dateArray() : ArrayList&lt;Date&gt; {
    val date = Date()
    val date2 = Date(date.time - 432000000)
    val date3 = Date(date2.time - 432000000)
    val date4 = Date(date3.time - 432000000)
    val date5 = Date(date4.time - 432000000)
    val date6 = Date(date5.time - 432000000)
    val date7 = Date(date6.time - 432000000)
    val date8 = Date(date7.time - 432000000)
    val date9 = Date(date8.time - 432000000)
    val dateA = Date(date9.time - 432000000)
    return arrayListOf(date, date2, date3, date4, date5, date6, date7, date8, date9, dateA)
}

This way is to much overheaded. I bet Kotlin offers an elegant way?

答案1

得分: 1

import java.time.LocalDate
import java.time.Period
import java.time.ZoneId
import java.util.stream.Collectors

fun main() {
    val step: Period = Period.ofDays(-5)
    val numberOfDates = 10

    val totalPeriod: Period = step.multipliedBy(numberOfDates)

    val today: LocalDate = LocalDate.now(ZoneId.of("America/Rosario"))
    val dates: List<LocalDate> = today.datesUntil(today.plus(totalPeriod), step)
        .collect(Collectors.toList())

    println(dates)
}

Output:

[2020-09-14, 2020-09-09, 2020-09-04, 2020-08-30, 2020-08-25, 2020-08-20, 2020-08-15, 2020-08-10, 2020-08-05, 2020-07-31]

不好意思,我知道你只想要代码翻译,但是由于代码中的某些字符需要转义,所以我还是在某些地方添加了一些额外的解释性内容。如果你有任何问题,或者需要进一步的帮助,请随时问我。

英文:

java.time

Here’s a simple pure Java solution. Like others I am recommending that you use java.time, the modern Java date and time API, for your date work.

	Period step = Period.ofDays(-5);
	int numberOfDates = 10;
	
	Period totalPeriod = step.multipliedBy(numberOfDates);
	
	LocalDate today = LocalDate.now(ZoneId.of(&quot;America/Rosario&quot;));
	List&lt;LocalDate&gt; dates = today.datesUntil(today.plus(totalPeriod), step)
			.collect(Collectors.toList());
	
	System.out.println(dates);

Output:

> [2020-09-14, 2020-09-09, 2020-09-04, 2020-08-30, 2020-08-25,
> 2020-08-20, 2020-08-15, 2020-08-10, 2020-08-05, 2020-07-31]

I trust that you can translate to Kotlin and maybe even refine it further in Kotlin.

It’s not well documented that you may use the two-arg LocalDate.datesUntil() with a negative period, but at least it works on my Java 11.

Sorry to say, your solution in the question not only has more code than needed, it is also incorrect. Subtracting 432 000 000 milliseconds each time assumes that a day is always 24 hours. Because of summer time (DST) and other time anomalies a day may be 23 or 25 hours or something in between. By using LocalDate we are free of such issues. You may also use for example ZonedDateTime of LocalDateTime instead if you want to include time of day, they work fine across summer time transitions too.

Link: Oracle tutorial: Date Time explaining how to use java.time.

答案2

得分: 0

我建议您从过时且容易出错的java.util日期时间 API 切换到现代的java.time日期时间 API。您可以从**教程: 日期时间**了解有关现代日期时间 API 的更多信息。如果您的 Android API 级别仍不符合 Java 8,请查看 https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project通过 desugaring 支持的 Java 8+ API

使用 Java 现代日期时间 API,可以按以下方式完成:

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(getPastDaysOnIntervalOf(10, 5));// 10 days in the past at an interval of 5 days
        System.out.println(getPastDaysOnIntervalOf(5, 10));// 5 days in the past at an interval of 10 days
    }

    static List<LocalDate> getPastDaysOnIntervalOf(int times, int interval) {
        // The list to be populated with the desired dates
        List<LocalDate> list = new ArrayList<>();

        // Today
        LocalDate date = LocalDate.now();

        for (int i = 1; i <= times; i++) {
            list.add(date);
            date = date.minusDays(interval);
        }

        // Return the populated list
        return list;
    }
}

输出:

[2020-09-14, 2020-09-09, 2020-09-04, 2020-08-30, 2020-08-25, 2020-08-20, 2020-08-15, 2020-08-10, 2020-08-05, 2020-07-31]
[2020-09-14, 2020-09-04, 2020-08-25, 2020-08-15, 2020-08-05]

使用传统 API:

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(getPastDaysOnIntervalOf(10, 5));// 10 days in the past at an interval of 5 days
        System.out.println(getPastDaysOnIntervalOf(5, 10));// 5 days in the past at an interval of 10 days
    }

    static List<Date> getPastDaysOnIntervalOf(int times, int interval) {
        // The list to be populated with the desired dates
        List<Date> list = new ArrayList<>();

        // Today
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();

        for (int i = 1; i <= times; i++) {
            list.add(date);
            cal.add(Calendar.DATE, -interval);
            date = cal.getTime();
        }

        // Return the populated list
        return list;
    }
}
英文:

I recommend you switch from the outdated and error-prone java.util date-time API to the modern java.time date-time API. Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java8, check https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project and Java 8+ APIs available through desugaring.

Do it as follows using the Java modern date-time API:

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class Main {
	public static void main(String[] args) {
		// Tests
		System.out.println(getPastDaysOnIntervalOf(10, 5));// 10 days in past at an interval of 5 days
		System.out.println(getPastDaysOnIntervalOf(5, 10));// 5 days in past at an interval of 10 days
	}

	static List&lt;LocalDate&gt; getPastDaysOnIntervalOf(int times, int interval) {
		// The list to be populated with the desired dates
		List&lt;LocalDate&gt; list = new ArrayList&lt;&gt;();

		// Today
		LocalDate date = LocalDate.now();

		for (int i = 1; i &lt;= times; i++) {
			list.add(date);
			date = date.minusDays(interval);
		}

		// Return the populated list
		return list;
	}
}

Output:

[2020-09-14, 2020-09-09, 2020-09-04, 2020-08-30, 2020-08-25, 2020-08-20, 2020-08-15, 2020-08-10, 2020-08-05, 2020-07-31]
[2020-09-14, 2020-09-04, 2020-08-25, 2020-08-15, 2020-08-05]

Using legacy API:

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Main {
	public static void main(String[] args) {
		// Tests
		System.out.println(getPastDaysOnIntervalOf(10, 5));// 10 days in past at an interval of 5 days
		System.out.println(getPastDaysOnIntervalOf(5, 10));// 5 days in past at an interval of 10 days
	}

	static List&lt;Date&gt; getPastDaysOnIntervalOf(int times, int interval) {
		// The list to be populated with the desired dates
		List&lt;Date&gt; list = new ArrayList&lt;&gt;();

		// Today
		Calendar cal = Calendar.getInstance();
		Date date = cal.getTime();

		for (int i = 1; i &lt;= times; i++) {
			list.add(date);
			cal.add(Calendar.DATE, -interval);
			date = cal.getTime();
		}

		// Return the populated list
		return list;
	}
}

huangapple
  • 本文由 发表于 2020年9月10日 02:45:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63817771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定