如何验证显示的日期正确?

时间:2019-05-20 14:58:38

标签: java

我需要一些帮助,以尝试在元素中的每个日期与实际日期之间断言。 基本上,我的应用程序中有5个日期磁贴,显示如下:

Mon 20th May
Tue 21st May
Wed 22nd May
Thu 23rd May
Fri 24th May

现在,当日期的元素为“ id = day”(例如,周一,周二,周三)且日期的元素为“ id = date”(例如,5月20日,21日)时,这些磁贴的元素相同5月22日)等。

以下解释了我要做什么:

  • 在应用程序中,它始终显示5个日期

  • 显示的5个日期始终从明天的日期开始,并显示接下来的5个日期(星期日除外)。

  

我想执行一个断言来检查从日期磁贴起的5天   (例如,周一,周二,周三)符合上述条件。

     

我还想执行一个断言来检查日期中的5个日期   磁贴(例如5月20日,5月21日,5月22日)符合上述条件。   如何实现?

我在下面设置了一个小的日期选择器,但我不是开发人员,因此需要更多的编码知识和逻辑来帮助实现此目标:

    SimpleDateFormat sdf = new SimpleDateFormat("E-dd-MMM");
    Calendar cal = Calendar.getInstance();
    // get start date
    cal.add(Calendar.DAY_OF_YEAR, +1);

    // loop adding one day in each iteration
    for(int i = 0; i< 5; i++){
        cal.add(Calendar.DAY_OF_YEAR, 1);
        System.out.println(sdf.format(cal.getTime()));
    }

1 个答案:

答案 0 :(得分:1)

避免使用旧类

您使用的是可怕的日期时间类,而这些类在几年前已被JSR 310中定义的 java.time 类取代。

LocalDate

LocalDate类表示没有日期,没有time zoneoffset-from-UTC的仅日期值。

时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将您的期望/期望时区明确指定为参数。如果紧急,请与您的用户确认区域。

Continent/Region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,代码将变得难以理解,因为我们不确定您是否打算使用默认值,还是像许多程序员一样不知道该问题。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

或指定日期。您可以用数字设置月份,一月至十二月的理智编号为1-12。

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

或者更好的是,使用预定义的Month枚举对象,每年的每个月使用一个。提示:在整个代码库中使用这些Month对象,而不是仅使用整数,可以使您的代码更具自记录性,确保有效值并提供type-safetyYearYearMonth的同上。

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

DayOfWeek

如果您需要跟踪星期几(问题中不清楚),请使用DayOfWeek枚举。

DayOfWeek dow = ld.getDayOfWeek() ;

Tile

您的Tile类应包含类型LocalDate的成员变量。使用智能对象而不是哑字符串。生成本地化文本以显示给用户,但是您的内部业务逻辑应使用特定于任务的类型的对象。

您的类应实现重写的toString方法,以生成有助于调试或记录日志的文本。定义一个名为getDisplayName之类的单独方法,以生成适合用户显示的文本。

public class Tile {
    LocalDate localDate ;
    static private DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "EEE dd MMM" , Locale.US ) ;

    public Tile( LocalDate localDateArg ) {
        this.localDate = localDateArg ;
    }

    public String getDisplayName() {
        String output = this.localDate.format( Tile.formatter ) ;
        return output ;
    }

    @Override
    public String toString() {
        String output = Tile.class.getSimpleName() + "{ localDate:" + this.localDate.toString() + " }" ;
    }

}

如果您的电话号码确实需要thst,则需要采取其他措施。 DateTimeFormatter中未内置此功能。在堆栈溢出中搜索“标准日期”,因为已经多次涉及了。在您完成其余工作之后,建议您最后添加此功能。

生成图块

  

显示的5个日期始终从明天开始,并显示接下来的5个日期(星期日除外)。

所以我们需要一张瓷砖清单。对于每个新的图块,如果发现是星期天,则将其丢弃。

int limit = 5 ; 
List< Tile > tiles = new ArrayList<>( limit ) ;

获取今天的日期。递增到下一个日期,省略周日。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate tomorrow = LocalDate.now( z ).plusDays( 1 ) ;  // Tomorrow is today plus one day.
LocalDate localDate = tomorrow ;

for ( int i = 1 ; i <= limit ; i ++ ) {
    if( localDate.getDayOfWeek().equals( DayOfWeek.SUNDAY ) { // If this date is a Sunday…
        localDate = localDate.plusDays( 1 ) ; // Omit Sunday, bump to the next date.
    }
    Tile tile = new Tile( localDate ) ;
    tiles.add( tile ) ;
    // Set up the next loop.
    localDate = localDate.plusDays( 1 ) ;
}
  

我想执行一个断言,以检查从日期磁贴(例如,周一,周二,周三)起的5天是否符合上述条件。

写一些方法检查我们的瓷砖集合。我使用了类似于创建图块列表的方法的逻辑。

public boolean areTilesValidByDate( final List< Tile > tiles ) {
    Objects.requireNonNull​( tiles ) ;  // Verify we were passed a list.

    int limit = 5 ;
    if( tiles.size() != limit ) {      // If unexpected size, the list cannot be valid.
        return false ;
    }

    ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
    LocalDate tomorrow = LocalDate.now( z ).plusDays( 1 ) ;  // Tomorrow is today plus one day.
    LocalDate localDate = tomorrow ;

    // Loop through the five dates we expect to find in the existing tiles.
    for ( int i = 1 ; i <= limit ; i ++ ) {
        if( localDate.getDayOfWeek().equals( DayOfWeek.SUNDAY ) { // If this date is a Sunday…
            localDate = localDate.plusDays( 1 ) ; // Omit Sunday, bump to the next date.
        }
        Tile tile = tiles.get( i - 1 ) ;  // Subtract one for annoying zero-based index counting rather than 1-based ordinal counting. Index-counting comes from simplistic array and byte-jumping code in old C-style languages, and is a habit the industry finds difficult to shake off.
        if( ! tile.localDate.isEqual( localDate ) {
            return false ;
        }
        // Set up the next loop.
        localDate = localDate.plusDays( 1 ) ;
    }
    // If we make it to this point, the list must be valid.
    return true ;
}

在实际工作中,我不会对时区(ZoneId)进行硬编码。

注意:我从未运行过任何这段代码。您可能需要修复。 (⇐轻描淡写是开发者的笑话。)

P.S。如果您正在制作供人们使用的软件,那么您 是开发人员。欢迎来到俱乐部。

提示:发布前彻底搜索堆栈溢出。这次我为您提供了帮助,但也许不应该这样做,因为我们通常不鼓励在此站点上进行简单的重复。所有这些材料在Stack Overflow上已被覆盖很多次。努力拼凑各种发现的金块将帮助您了解更多。