Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:处理日期_Java_List_Date - Fatal编程技术网

Java:处理日期

Java:处理日期,java,list,date,Java,List,Date,我对Java非常陌生。所以请容忍我。我有4个变量: mode = prior|later|value;(can have either of these 3 values) occurrence = 2 day = Wednesday eta = 14:00 我正在尝试实现一种方法,该方法将返回一个基于以下条件的列表date: 案例1:(模式=之前,发生时间=2,日期=周三,预计到达时间=14:00) 应返回当月下个月的前两个星期三的日期 输出=[2018年8月1日星期三14:00:00,2

我对Java非常陌生。所以请容忍我。我有4个变量:

mode =  prior|later|value;(can have either of these 3 values)
occurrence = 2
day = Wednesday
eta = 14:00
我正在尝试实现一种方法,该方法将返回一个基于以下条件的列表
date

案例1:
(模式=之前,发生时间=2,日期=周三,预计到达时间=14:00)

应返回当月下个月的前两个星期三的日期

输出=[2018年8月1日星期三14:00:00,2018年8月8日星期三14:00:00]

案例2:(
mode=later,accurrence=2,day=周三,eta=14:00

应返回当月下个月最后2个星期三的日期

输出=【2018年8月22日星期三14:00:00,2018年8月29日星期三14:00:00】

案例3:
(模式=值,发生率=3,日期=周三,预计到达时间=14:00)

返回日期应为当月下个月的第三个星期三

output = [Wed Aug 15 14:00:00 2018, Wed Aug 29 14:00:00 2018]
这就是我到目前为止所做的

public static List<Date> getDates(Calendar c, String mode, int occurrence, int dayNo, String eta) {
            List<Date> dates = new ArrayList<Date>();
            switch(mode) {
            case "value": {
                String[] times = eta.split(":");
                c.set(Calendar.DAY_OF_WEEK, dayNo);  
                c.set(Calendar.DAY_OF_WEEK_IN_MONTH, occurrence);
                c.set(Calendar.MONTH, Calendar.JULY + 1); 
                c.set(Calendar.YEAR, 2018);
                c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(times[0]));
                c.set(Calendar.MINUTE, Integer.parseInt(times[1]));
                dates.add(c.getTime());
            }
            }
            return dates;
        }
公共静态列表getDates(日历c、字符串模式、整数出现、整数天数、字符串eta){
列表日期=新建ArrayList();
开关(模式){
案例“值”:{
字符串[]次=eta.split(“:”);
c、 设置(日历日,周中日,日号);
c、 设置(日历日、周日、月日、事件);
c、 设置(Calendar.MONTH、Calendar.JULY+1);
c、 set(日历年,2018年);
c、 set(Calendar.HOUR\u OF_DAY,Integer.parseInt(times[0]));
c、 set(Calendar.MINUTE,Integer.parseInt(times[1]));
dates.add(c.getTime());
}
}
返回日期;
}

有没有更好的方法来做我所做的事情。还有谁能帮我实施案例1和案例2

所以我理解了你的问题,比如我写了一些代码。我无法理解“价值”选项。期望的输出和方法的解释对我来说并不明显。如果你解释一下,我可以修改答案

public class Main {

    public static void main(String[] args) {
        for (String s : findOccurence("prior", DayOfWeek.WEDNESDAY, 2, "14:00")){
            System.out.println(s);
        }
    }

    public static String[] findOccurence(String mode, DayOfWeek day, int occurrence, String eta) {
        LocalDate now = LocalDate.now();
        LocalDate start = LocalDate.of(now.getYear(), now.getMonth().plus(1), 1);
        LocalDate finish = start.plusDays(start.lengthOfMonth());

        List<LocalDate> dates = Stream.iterate(start, date -> date.plusDays(1))
                .limit(ChronoUnit.DAYS.between(start, finish))
                .filter(d -> d.getDayOfWeek() == day)
                .collect(Collectors.toList());

        String[] formattedEta = eta.split(":");

        if (occurrence > dates.size()) {
            throw new IndexOutOfBoundsException();
        }

        if (mode.equalsIgnoreCase("value")) {

        }
        else if (mode.equalsIgnoreCase("later")) {
            dates = Lists.reverse(dates);
        }

        //later and prior shares common logic

        return dates.stream()
                .limit(occurrence)
                .map(d -> day.toString()
                            + " "
                            + start.getMonth().name()
                            + " "
                            + d.getDayOfMonth()
                            + " "
                            + LocalTime.of(Integer.valueOf(formattedEta[0]), Integer.valueOf(formattedEta[1]), 0)
                            + " "
                            + start.getYear())
                .collect(Collectors.toList())
                .toArray(new String[occurrence]);
    }
}
避免遗留日期时间类 您使用的是多年前被java.time类取代的糟糕的旧日期时间类

特别是,
Calendar
类(实际上,
gregoriacalendar
)被替换为

使用类型(类) 在可行的情况下,使用智能对象而不是哑字符串。使用适当的类型可以使代码更加自文档化,确保有效值,提供并让编译器捕获您的代码

在您的情况下,Java已经为大多数数据提供了类型。您可以为“模式”创建自己的类型

Java中的功能比其他语言中的功能更强大、更灵活。请参阅以了解更多信息。但基本原理很简单,如下所示:

public enum Mode {
    PRIOR ,
    LATER ,
    VALUE
}
对于星期几,使用枚举,预先定义七个对象,一周中的每一天一个。例如,
DayOfWeek.周三

对于一天中的某个时间,请使用

对于当前月份,使用类

确定当年月份意味着确定当前日期。确定当前日期需要时区。在任何一个特定的时刻,世界各地的日期都因地区而异

ZoneId z = ZoneId.of( "Africa/Tunis" ) ; // Or "America/Chicago", etc.
YearMonth ym = YearMonth.now( z ) ;
如果您有一个
LocalDate
,您可以确定它的年-月

YearMonth ym = YearMonth.from( myLocalDate ) ;
我建议让调用方法确定方法的类型,而不是让此方法跳过额外的限制。中的一般设计方法是分离或分离责任。我们正在编写的这个方法应该关注它自己的需求(一个年-月值),而不必关心调用方法如何到达它所需的年-月,无论是从当前日期还是当前月份还是最后一个月,等等

最后,如果您的目标是获得一个时间点(一个日期和一天中的某个时间),那么您还必须指定一个时区。没有时区上下文(或UTC偏移量)的日期+时间没有实际意义

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

因此,将这些放在一起,您的方法签名可以如下所示:

public static List< ZonedDateTime > getDates( 
    YearMonth ym , 
    Mode mode , 
    int occurrences , 
    DayOfWeek dow , 
    LocalTime lt ,
    ZoneId z
) { …
让我们看看三种模式的逻辑

Mode.PRIOR
获取每月一周的第一天

    LocalDate firstDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.firstInMonth( dow ) );
一个月下来,一次增加一周

        // Start with last day-of-week in month.
        LocalDate lastDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.lastInMonth( dow ) );
        // Work our way up through the month, subtracting a week at a time.
        for ( int i = 0 ; i < occurrences ; i++ ) {
            LocalDate ld = lastDowOfMonth.minusWeeks( i );
            ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
            if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
                moments.add( zdt );
            }
        }
我们可能会超过这个月的界限,进入下个月。因此,检查
YearMonth
以查看它是否与启动时相同

    for ( int i = 0 ; i < occurrences ; i++ ) {
        LocalDate ld = firstDowOfMonth.plusWeeks( i );
        ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
        if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
            moments.add( zdt );
        }
    }
因为我们在时光倒流,所以我们收集的
时刻
是按相反的时间顺序排列的。因此,我们需要按时间顺序对其进行排序

        Collections.sort( moments ); // If you want the list to be in chronological order, sort.  Otherwise in reverse chronological order for this `Mode.LATER`.
Mode.VALUE
最后一个例子是最简单的:得到一个月中一周的第n天。这只不过是一条直线

        LocalDate nthDowInMonth = ym.atDay( 1 ).with( TemporalAdjusters.dayOfWeekInMonth( occurrences , dow ) );
按常规操作,创建一个
ZoneDateTime

        ZonedDateTime zdt = ZonedDateTime.of( nthDowInMonth , lt , z );
核实这个月,因为文件似乎在说,超过这个月的限制将使我们进入下一个月。在这种情况下,我们的逻辑会从列表中忽略日期。因此,我们将以空列表的形式返回
时刻。这意味着调用方法应该检查包含元素的列表,因为它可能是空的

        if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
            moments.add( zdt );
        }
让我们看看所有的代码放在一起

// Simulate arguments passed.
LocalTime lt = LocalTime.of( 14 , 0 );
ZoneId z = ZoneId.of( "Africa/Tunis" ); // Or "America/Chicago", etc.
YearMonth ym = YearMonth.now( z );
DayOfWeek dow = DayOfWeek.WEDNESDAY;
Mode mode = Mode.PRIOR ;  // Mode.PRIOR, Mode.LATER, Mode.VALUE.
int occurrences = 3; // TODO: Add code to verify this value is in range of 1-5, not zero, not >5.

// Logic
int initialCapacity = 5; // Max five weeks in any month.
List< ZonedDateTime > moments = new ArrayList<>( initialCapacity );
switch ( mode ) {
    case PRIOR:
        // Start with first day-of-week in month.
        LocalDate firstDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.firstInMonth( dow ) );
        // Work our way down through the month, adding a week at a time.
        for ( int i = 0 ; i < occurrences ; i++ ) {
            LocalDate ld = firstDowOfMonth.plusWeeks( i );
            ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
            if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
                moments.add( zdt );
            }
        }
        break;

    case LATER:
        // Start with last day-of-week in month.
        LocalDate lastDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.lastInMonth( dow ) );
        // Work our way up through the month, subtracting a week at a time.
        for ( int i = 0 ; i < occurrences ; i++ ) {
            LocalDate ld = lastDowOfMonth.minusWeeks( i );
            ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
            if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
                moments.add( zdt );
            }
        }
        Collections.sort( moments ); // If you want the list to be in chronological order, sort.  Otherwise in reverse chronological order for this `Mode.LATER`.
        break;

    case VALUE:
        // Get the nth day-of-week in month.
        LocalDate nthDowInMonth = ym.atDay( 1 ).with( TemporalAdjusters.dayOfWeekInMonth( occurrences , dow ) );
        ZonedDateTime zdt = ZonedDateTime.of( nthDowInMonth , lt , z );
        if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
            moments.add( zdt );
        }
        break;

    default:  // Defensive programming, testing for unexpected values.
        System.out.println( "ERROR - should not be able to reach this point. Unexpected `Mode` enum value." );
        break;
}
// return `moments` list from your method.
System.out.println( "moments:\n" + moments );
//模拟传递的参数。
LocalTime lt=LocalTime.of(14,0);
ZoneId z=ZoneId.of(“非洲/突尼斯”);//或“美国/芝加哥”等。
YearMonth ym=YearMonth.now(z);
DayOfWeek道琼斯指数=DayOfWeek.周三;
Mode Mode=Mode.PRIOR;//Mode.PRIOR、Mode.LATER、Mode.VALUE。
整数出现次数=3;//TODO:添加代码以验证此值是否在1-5范围内,不是零,也不是>5。
//逻辑
int initialCapacity=5;//任何月份最多五周。
列表时刻=新阵列列表(初始容量);
开关(模式){
先前案例:
//从一个月的第一天开始。
LocalDate firstDowOfMonth=ym.atDay(1)
        ZonedDateTime zdt = ZonedDateTime.of( nthDowInMonth , lt , z );
        if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
            moments.add( zdt );
        }
// Simulate arguments passed.
LocalTime lt = LocalTime.of( 14 , 0 );
ZoneId z = ZoneId.of( "Africa/Tunis" ); // Or "America/Chicago", etc.
YearMonth ym = YearMonth.now( z );
DayOfWeek dow = DayOfWeek.WEDNESDAY;
Mode mode = Mode.PRIOR ;  // Mode.PRIOR, Mode.LATER, Mode.VALUE.
int occurrences = 3; // TODO: Add code to verify this value is in range of 1-5, not zero, not >5.

// Logic
int initialCapacity = 5; // Max five weeks in any month.
List< ZonedDateTime > moments = new ArrayList<>( initialCapacity );
switch ( mode ) {
    case PRIOR:
        // Start with first day-of-week in month.
        LocalDate firstDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.firstInMonth( dow ) );
        // Work our way down through the month, adding a week at a time.
        for ( int i = 0 ; i < occurrences ; i++ ) {
            LocalDate ld = firstDowOfMonth.plusWeeks( i );
            ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
            if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
                moments.add( zdt );
            }
        }
        break;

    case LATER:
        // Start with last day-of-week in month.
        LocalDate lastDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.lastInMonth( dow ) );
        // Work our way up through the month, subtracting a week at a time.
        for ( int i = 0 ; i < occurrences ; i++ ) {
            LocalDate ld = lastDowOfMonth.minusWeeks( i );
            ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
            if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
                moments.add( zdt );
            }
        }
        Collections.sort( moments ); // If you want the list to be in chronological order, sort.  Otherwise in reverse chronological order for this `Mode.LATER`.
        break;

    case VALUE:
        // Get the nth day-of-week in month.
        LocalDate nthDowInMonth = ym.atDay( 1 ).with( TemporalAdjusters.dayOfWeekInMonth( occurrences , dow ) );
        ZonedDateTime zdt = ZonedDateTime.of( nthDowInMonth , lt , z );
        if ( YearMonth.from( zdt ).equals( ym ) ) {  // If in same month…
            moments.add( zdt );
        }
        break;

    default:  // Defensive programming, testing for unexpected values.
        System.out.println( "ERROR - should not be able to reach this point. Unexpected `Mode` enum value." );
        break;
}
// return `moments` list from your method.
System.out.println( "moments:\n" + moments );