Java 使用GregorianCalendar和can'操纵和比较日期;我不能让代码正常工作

Java 使用GregorianCalendar和can'操纵和比较日期;我不能让代码正常工作,java,android,java-time,Java,Android,Java Time,我正在努力找到我代码中的错误。paytotal应该有一个数字,但它的值为0 支付支票的第一天是2020年10月23日 支付支票的最后一天是2020年11月6日 我的简单日期格式是“mmmdd,yyyy” 传递到runPayroll的字符串dateInQuestion是“2020年10月31日”,它最初来自与上述相同的sdf 我是java新手,没有处理过像这样操纵日历的问题。感觉下面的代码应该可以工作 private void runPayroll(String dateInQuestion,

我正在努力找到我代码中的错误。paytotal应该有一个数字,但它的值为0

支付支票的第一天是2020年10月23日

支付支票的最后一天是2020年11月6日

我的简单日期格式是“mmmdd,yyyy”

传递到runPayroll的字符串
dateInQuestion
是“2020年10月31日”,它最初来自与上述相同的sdf

我是java新手,没有处理过像这样操纵日历的问题。感觉下面的代码应该可以工作

 private void runPayroll(String dateInQuestion, long payForTask){   
     c.setTime(firstDayOfPaycheck);
        
        //loop through days of paycheck. number from time.compareTo(time2) is negative while time is before time2 
        while(c.getTime().compareTo(lastDayOfPaycheck)<=0){

            if(dateInQuestion != null) {

                Date questionDate = sdf.parse(dateInQuestion, new ParsePosition(0));
                if (c.getTime().compareTo(questionDate) == 0) {
                    payTotal += payForTask;
                }
            }
            c.add(Calendar.DAY_OF_YEAR, 1);
        }
} //ran inside the query to get the total pay

private void buildPayrollDash(){
    String strPayrollAmt = "$" + payTotal;


    String startDate = sdf.format(firstDayOfPaycheck);
    String trimmedStart = startDate.split(",")[0]; //cuts out the year in the date
    String endDate = sdf.format(lastDayOfPaycheck);
    String trimmedEnd = endDate.split(",")[0];
    int holdBack = sharedPreferences.getInt("payroll holdback", 7);
    c.setTime(lastDayOfPaycheck);
    c.add(Calendar.DAY_OF_YEAR, holdBack);
    String payDate = sdf.format(c.getTime());
    String trimmedPaydate = payDate.split(",")[0];

    tvPayrollTimefame.setText("Pay from " + trimmedStart + " - " + trimmedEnd);
    tvPayrollAmount.setText(strPayrollAmt + " due " + trimmedPaydate);
private void runPayroll(字符串dateInQuestion,long payForTask){
c、 设置时间(支付支票的第一天);
//循环查看工资支票的天数。来自时间的数字。当时间在时间2之前时,compareTo(时间2)为负数
while(c.getTime().compareTo(lastDayOfPaycheck)
我正在努力找到我代码中的错误

您使用的日期时间类很糟糕,多年前已被现代java.time类取代。请不要使用
date
Calendar
GregorianCalendar
或其亲属

支付支票的第一天是2020年10月23日

用于表示没有时间和时区的日期

LocalDate firstDayOfPayPeriod = LocalDate.of( 2020 , Month.OCTOBER , 23 ) ;
支付支票的最后一天是2020年11月6日

如果您使用半开放式方法定义时间跨度,您会发现日期-时间处理更容易。开始是包容性的,而结束是排他性的。因此,与其关注支付期的最后一天,不如关注下一个期间的第一天

LocalDate firstDayOfSuccessivePayPeriod = LocalDate.of( 2020 , 11 , 7 ) ;
提示:如果将库添加到Java项目中,则可以将付款期的日期范围表示为对象

我的简单日期格式是“mmmdd,yyyy”

您不应将业务逻辑与本地化代码混为一谈。日期时间的自定义格式应仅用于向用户演示

当以文本形式交换日期时间值作为数据时,请使用标准格式。对于仅限日期的值,标准格式为YYYY-MM-DD。默认情况下,java.time使用ISO 8601格式,因此无需指定任何格式模式

传递到
runPayroll
的字符串
dateInQuestion
是“2020年10月31日”,它最初来自与上述相同的sdf

如果您必须输入格式化的日期字符串,而不是标准的ISO 8601格式,请使用。堆栈溢出中已经多次介绍了这一点,请搜索更多信息

与其在以后检查有效数据,不如在代码的早期检查输入。“快速失败”是一句谚语

try
{
    LocalDate dateInQuestion = LocalDate.parse( "2020-10-31" );
}
catch ( DateTimeParseException e )
{
    // … Handle faulty input.
    e.printStackTrace();
}
我是java新手,没有处理过像这样操纵日历的问题。感觉下面的代码应该可以工作

 private void runPayroll(String dateInQuestion, long payForTask){   
     c.setTime(firstDayOfPaycheck);
        
        //loop through days of paycheck. number from time.compareTo(time2) is negative while time is before time2 
        while(c.getTime().compareTo(lastDayOfPaycheck)<=0){

            if(dateInQuestion != null) {

                Date questionDate = sdf.parse(dateInQuestion, new ParsePosition(0));
                if (c.getTime().compareTo(questionDate) == 0) {
                    payTotal += payForTask;
                }
            }
            c.add(Calendar.DAY_OF_YEAR, 1);
        }
} //ran inside the query to get the total pay

private void buildPayrollDash(){
    String strPayrollAmt = "$" + payTotal;


    String startDate = sdf.format(firstDayOfPaycheck);
    String trimmedStart = startDate.split(",")[0]; //cuts out the year in the date
    String endDate = sdf.format(lastDayOfPaycheck);
    String trimmedEnd = endDate.split(",")[0];
    int holdBack = sharedPreferences.getInt("payroll holdback", 7);
    c.setTime(lastDayOfPaycheck);
    c.add(Calendar.DAY_OF_YEAR, holdBack);
    String payDate = sdf.format(c.getTime());
    String trimmedPaydate = payDate.split(",")[0];

    tvPayrollTimefame.setText("Pay from " + trimmedStart + " - " + trimmedEnd);
    tvPayrollAmount.setText(strPayrollAmt + " due " + trimmedPaydate);
使用java.time时,您的代码会简单得多。首先,java.time类提供了方便的
isBefore
isAfter
isEqual
方法,因此无需进行笨拙的
比较
调用

LocalDate firstDayOfPayPeriod = LocalDate.of( 2020 , Month.OCTOBER , 23 );
LocalDate firstDayOfSuccessivePayPeriod = LocalDate.of( 2020 , 11 , 7 );

String input = "2020-10-31";
LocalDate dateInQuestion = null;
try
{
    dateInQuestion = LocalDate.parse( input );
}
catch ( DateTimeParseException e )
{
    // Handle faulty input.
    e.printStackTrace();
}

// Validate dates.
Objects.requireNonNull( firstDayOfPayPeriod );
Objects.requireNonNull( firstDayOfSuccessivePayPeriod );
Objects.requireNonNull( dateInQuestion );
if ( ! firstDayOfPayPeriod.isBefore( firstDayOfSuccessivePayPeriod ) )
{
    throw new IllegalStateException( "…" );
}
if ( dateInQuestion.isBefore( firstDayOfPayPeriod ) )
{
    throw new IllegalStateException( "…" );
}
if ( ! dateInQuestion.isBefore( firstDayOfSuccessivePayPeriod ) )
{
    throw new IllegalStateException( "…" );
}


long payPerDay = 100;
long partialPay = 0;

LocalDate localDate = firstDayOfPayPeriod;
while ( localDate.isBefore( firstDayOfSuccessivePayPeriod ) )
{
    if ( localDate.isBefore( dateInQuestion ) )
    {
        partialPay = ( partialPay + payPerDay );
    }

    // Set up the next loop.
    // Notice that java.time uses immutable objects. So we generate a new object based on another’s values rather than alter (mutate) the original.
    localDate = localDate.plusDays( 1 ); // Increment to next date.
}

System.out.println( "Partial pay earned from firstDayOfPayPeriod " + firstDayOfPayPeriod + " to dateInQuestion " + dateInQuestion + " is " + partialPay );
看这个

从付款期2020-10-23的第一天到2020-10-31的问题日期的部分工资为800

有了更多的Java编程经验,您可能希望使用streams完成此类工作。请参阅

顺便说一下,如果您想跳过周末,请添加以下内容:

Set< DayOfWeek > weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) ;
…
if ( weekend.contains( localDate.getDayOfWeek() ) ) { … }
Setweekend=EnumSet.of(DayOfWeek.周六,DayOfWeek.周日);
…
if(weekend.contains(localDate.getDayOfWeek()){…}

关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,&

要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为

该项目现已启动,建议迁移到类

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
classes。Hibernate 5和JPA 2.2支持java.time

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • 带来了一些小功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • Android(26+)的更高版本捆绑了java.time类的实现
    • 对于早期的Android( 我正在努力找到我代码中的错误

      您使用的日期时间类很糟糕,多年前已被现代java.time类取代。请不要使用
      date
      Calendar
      GregorianCalendar
      或其亲属

      支付支票的第一天是2020年10月23日

      用于表示没有时间和时区的日期

      LocalDate firstDayOfPayPeriod = LocalDate.of( 2020 , Month.OCTOBER , 23 ) ;
      
      支付支票的最后一天是2020年11月6日

      如果您使用半开放式方法定义时间跨度,您会发现日期-时间处理更容易。开始是包容性的,而结束是排他性的。因此,与其关注支付期的最后一天,不如关注下一个期间的第一天

      LocalDate firstDayOfSuccessivePayPeriod = LocalDate.of( 2020 , 11 , 7 ) ;
      
      提示:如果将库添加到Java项目中,则可以将付款期的日期范围表示为对象

      我的简单日期格式是“mmmdd,yyyy”

      您不应将业务逻辑与本地化代码混为一谈。日期时间的自定义格式应仅用于向用户演示

      当以文本形式交换日期时间值作为数据时,请使用标准格式。对于仅限日期的值,标准格式为YYYY-MM-DD。默认情况下,java.time使用ISO 8601格式,因此无需指定任何格式模式

      传递到
      runPayroll
      的字符串
      dateInQuestion
      是源于