代码之家  ›  专栏  ›  技术社区  ›  Phillip

Java:处理日期

  •  1
  • Phillip  · 技术社区  · 6 年前

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

    mode =  prior|later|value;(can have either of these 3 values)
    occurrence = 2
    day = Wednesday
    eta = 14:00
    

    我正在尝试实现一个方法,它将返回一个列表 date 基于以下标准:

    案例1: (mode=prior,occurence=2,day=wednesday,eta=14:00)

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

    产出=【2018年8月1日星期三14:00:00,2018年8月8日星期三14:00:00】

    案例2: mode=later,occurence=2,day=wednesday,eta=14:00 )

    应返回下个月最后两个星期三的日期(从当月算起)。

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

    案例3: (mode=value,occurence=3,day=wednesday,eta=14:00)

    应返回下个月的第3个星期三的日期。

    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;
            }
    

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

    2 回复  |  直到 6 年前
        1
  •  2
  •   Basil Bourque    6 年前

    Calendar GregorianCalendar ZonedDateTime

    type-safety typos

    enum Oracle Tutorial

    public enum Mode {
        PRIOR ,
        LATER ,
        VALUE
    }
    

    DayOfWeek DayOfWeek.WEDNESDAY

    LocalTime

    LocalTime lt = LocalTime.of( 14 , 0 ) ;
    

    YearMonth

    ZoneId z = ZoneId.of( "Africa/Tunis" ) ; // Or "America/Chicago", etc.
    YearMonth ym = YearMonth.now( z ) ;
    

    LocalDate

    YearMonth ym = YearMonth.from( myLocalDate ) ;
    

    OOP

    proper time zone name continent/region America/Montreal Africa/Casablanca Pacific/Auckland EST IST

    public static List< ZonedDateTime > getDates( 
        YearMonth ym , 
        Mode mode , 
        int occurrences , 
        DayOfWeek dow , 
        LocalTime lt ,
        ZoneId z
    ) { …
    

    Mode.PRIOR Mode.LATER TemporalAdjuster TemporalAdjusters

    occurrences

    switch Mode discussed here PRIOR case PRIOR: case Mode.PRIOR:

    List moments

    int initialCapacity = 5; // Max five weeks in any month.
    List< ZonedDateTime > moments = new ArrayList<>( initialCapacity );
    

        LocalDate firstDowOfMonth = ym.atDay( 1 ).with( TemporalAdjusters.firstInMonth( dow ) );
    

        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 );
            }
        }
    

            // 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`.
    

    Mode.VALUE

            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 );
            }
    

    // 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 );
    


    java.time legacy java.util.Date Calendar SimpleDateFormat

    Joda-Time maintenance mode java.time

    Oracle Tutorial JSR 310

    JDBC driver JDBC 4.2 java.sql.*

    ThreeTen-Extra Interval YearWeek YearQuarter more

        2
  •  0
  •   Emre Savcı    6 年前

    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]);
        }
    }
    

    WEDNESDAY AUGUST 1 14:00 2018
    WEDNESDAY AUGUST 8 14:00 2018
    
    推荐文章