Date 查找今天日期的前一天和后一天

Date 查找今天日期的前一天和后一天,date,java-time,localdate,java.time.instant,localdatetime,Date,Java Time,Localdate,Java.time.instant,Localdatetime,我已经创建了一个财务应用程序,我希望该应用程序向用户显示财务月份。财务月通常代表用户获得工资或最大收入的日期。这一天可以是一个月的第一天,一个月的最后一天,或者只是每个月的第15天。 此值可在设置中配置 我尝试运行ViewModel中调用的两个方法,getFirstDayOfMonth和getLastDayOfMonth 为了更好地理解上下文,这里有一些例子,我们将以今天的日期作为参考。2020年9月9日。输入值是我从设置中读取的值,用户可以从中选择,是一个1到31之间的数字(包括1到31) 示

我已经创建了一个财务应用程序,我希望该应用程序向用户显示财务月份。财务月通常代表用户获得工资或最大收入的日期。这一天可以是一个月的第一天,一个月的最后一天,或者只是每个月的第15天。 此值可在设置中配置

我尝试运行ViewModel中调用的两个方法,getFirstDayOfMonth和getLastDayOfMonth

为了更好地理解上下文,这里有一些例子,我们将以今天的日期作为参考。2020年9月9日。输入值是我从设置中读取的值,用户可以从中选择,是一个1到31之间的数字(包括1到31)

示例:输入:5输出:2020年9月5日00:00开始,2020年10月4日23:59:59结束

================

输入:31输出:2020年8月31日00:00开始,2020年9月30日23:59:59

问题是,如果月份没有这一天,它将得到左边最近的一天,例如,如果选择31作为第一天,该月份有30天,30将被计算为第一天,并且对于结束日期,如果选择31,我们在2月份,它只有28天,28将被选择

到目前为止,我已经有了这段代码,但我觉得它可以改进,而且它并没有像预期的那样工作

fun getFirstDayOfMonth(date: LocalDateTime): Long {
    var tempDate = date
    val firstDayOfMonth = lastDay?.filter { it.isDigit() }!!.toInt()

    if (firstDayOfMonth < tempDate.dayOfMonth) {
        tempDate = tempDate.withDayOfMonth(firstDayOfMonth)
    } else if (firstDayOfMonth > tempDate.dayOfMonth) {
        tempDate = tempDate.minusMonths(1)
        if (tempDate.monthValue == 12) {
//I don't know why minusMonths does not work in the same way as plusMonths, when I write .plusMonths(1) it also change the year if I am in december, with minusMonths if I am in January it does not change the year to minus one year.
            tempDate = tempDate.minusYears(1)
        }

        if (firstDayOfMonth > tempDate.with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth) {
            tempDate.withDayOfMonth(tempDate.with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth)
        } else {
            tempDate = tempDate.withDayOfMonth(firstDayOfMonth)
        }
    }

    return tempDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
}

fun getLastDayOfMonth(date: LocalDateTime): Long {
    var tempDate = date
    val firstDayOfMonth = lastDay?.filter { it.isDigit() }!!.toInt()

    if (firstDayOfMonth > tempDate.dayOfMonth && firstDayOfMonth <= tempDate.with(
            TemporalAdjusters.lastDayOfMonth()
        ).dayOfMonth
    ) {
        tempDate = tempDate.withDayOfMonth(firstDayOfMonth).minusDays(1)
    } else {
        tempDate = tempDate.plusMonths(1)
        if (firstDayOfMonth > tempDate.with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth) {
            tempDate.withDayOfMonth(tempDate.with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth)
        } else {
            tempDate = tempDate.withDayOfMonth(firstDayOfMonth).minusDays(1)
        }
    }

    return tempDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
}
也有31名被选中

Todays date 09.01.2020
Running for month January
Running for 31 th of the month
31.12.2019
30.01.2020
===========================================
Todays date 09.02.2020
Running for month February
Running for 31 th of the month
31.01.2020
30.03.2020
===========================================
Todays date 09.03.2020
Running for month March
Running for 31 th of the month
09.02.2020
30.03.2020
===========================================
Todays date 09.04.2020
Running for month April
Running for 31 th of the month
31.03.2020
30.05.2020
===========================================
Todays date 09.05.2020
Running for month May
Running for 31 th of the month
09.04.2020
30.05.2020
===========================================
Todays date 09.06.2020
Running for month June
Running for 31 th of the month
31.05.2020
30.07.2020
===========================================
Todays date 09.07.2020
Running for month July
Running for 31 th of the month
09.06.2020
30.07.2020
===========================================
Todays date 09.08.2020
Running for month August
Running for 31 th of the month
31.07.2020
30.08.2020
===========================================
Todays date 09.09.2020
Running for month September
Running for 31 th of the month
31.08.2020
30.10.2020
===========================================
Todays date 09.10.2020
Running for month October
Running for 31 th of the month
09.09.2020
30.10.2020
===========================================
Todays date 09.11.2020
Running for month November
Running for 31 th of the month
31.10.2020
30.12.2021
===========================================
Todays date 09.12.2020
Running for month December
Running for 31 th of the month
09.11.2020
30.12.2021
===========================================

Process finished with exit code 0

这个LocalDateTime类似乎具有您需要的所有内置功能。检查minusDays和plusDays方法。

在您的计算中有一些错误,一旦您理解了下面给出的解决方案,您就可以很容易地发现这些错误。我已经在代码中添加了足够的注释,这将帮助您快速理解它

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

public class Main {
    public static void main(String[] args) {
        // Test for 31
        int startDay = 31;

        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        
        // Test for 30
        startDay = 30;
        System.out.println();
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
                
        // Test for 28
        startDay = 28;
        System.out.println();
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
    }

    static long getFirstDayOfMonth(int startDay, YearMonth ym) {
        // Get last day of the month
        int lastDayOfTheMonth = ym.getMonth().length(ym.isLeapYear());

        // Start of the day and on the first day of the month
        LocalDateTime ldt = LocalDate.of(ym.getYear(), ym.getMonth(), 1)
                            .atStartOfDay();

        if (startDay > lastDayOfTheMonth) {
            ldt = ldt.minusMonths(1) // Go back to the last month
                    .with(TemporalAdjusters.lastDayOfMonth()); // Adjust to the last day of the obtained month
        }
        return ldt.toInstant(ZoneOffset.UTC).toEpochMilli();
    }

    static long getLastDayOfMonth(int startDay, YearMonth ym) {
        return Instant.ofEpochMilli(getFirstDayOfMonth(startDay, ym))// Get the point to start with
                .plus(ym.getMonth().length(ym.isLeapYear()), ChronoUnit.DAYS)// Add the no. of days of the given month
                .atOffset(ZoneOffset.UTC)// Get OffsetDateTime in order to get LocalDate
                .toLocalDate()// Convert to LocalDate
                .atTime(LocalTime.of(23, 59, 59))// At 23:59:59
                .toInstant(ZoneOffset.UTC)// Convert to Instant
                .toEpochMilli();
    }
}
输出:


你真的需要时间吗?不要将结束时间表示为最后一天的23:59:59。第二个财政月将不属于这两个财政月,这是令人不快的,并有可能导致错误。而是将会计月表示为从会计月开始(含)到下一个会计月开始(不含)的半开放时间间隔。这是时间间隔的标准和推荐处理方法。@OleV.V。好用户在应用程序中添加这些值并使用当前时间。我认为在23:59将新条目添加到数据库是不可能的:59@MarianPavel-这有助于解决问题吗?
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

public class Main {
    public static void main(String[] args) {
        // Test for 31
        int startDay = 31;

        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        
        // Test for 30
        startDay = 30;
        System.out.println();
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
                
        // Test for 28
        startDay = 28;
        System.out.println();
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.SEPTEMBER))));
        
        System.out.println(Instant.ofEpochMilli(getFirstDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
        System.out.println(Instant.ofEpochMilli(getLastDayOfMonth(startDay, YearMonth.of(2020, Month.FEBRUARY))));
    }

    static long getFirstDayOfMonth(int startDay, YearMonth ym) {
        // Get last day of the month
        int lastDayOfTheMonth = ym.getMonth().length(ym.isLeapYear());

        // Start of the day and on the first day of the month
        LocalDateTime ldt = LocalDate.of(ym.getYear(), ym.getMonth(), 1)
                            .atStartOfDay();

        if (startDay > lastDayOfTheMonth) {
            ldt = ldt.minusMonths(1) // Go back to the last month
                    .with(TemporalAdjusters.lastDayOfMonth()); // Adjust to the last day of the obtained month
        }
        return ldt.toInstant(ZoneOffset.UTC).toEpochMilli();
    }

    static long getLastDayOfMonth(int startDay, YearMonth ym) {
        return Instant.ofEpochMilli(getFirstDayOfMonth(startDay, ym))// Get the point to start with
                .plus(ym.getMonth().length(ym.isLeapYear()), ChronoUnit.DAYS)// Add the no. of days of the given month
                .atOffset(ZoneOffset.UTC)// Get OffsetDateTime in order to get LocalDate
                .toLocalDate()// Convert to LocalDate
                .atTime(LocalTime.of(23, 59, 59))// At 23:59:59
                .toInstant(ZoneOffset.UTC)// Convert to Instant
                .toEpochMilli();
    }
}
2020-08-31T00:00:00Z
2020-09-30T23:59:59Z
2020-01-31T00:00:00Z
2020-02-29T23:59:59Z

2020-09-01T00:00:00Z
2020-10-01T23:59:59Z
2020-01-31T00:00:00Z
2020-02-29T23:59:59Z

2020-09-01T00:00:00Z
2020-10-01T23:59:59Z
2020-02-01T00:00:00Z
2020-03-01T23:59:59Z