在if语句中解析日期并仅在规定的时间范围内显示结果

时间:2016-11-07 15:51:31

标签: java simpledateformat

目前我正在撰写一个java程序,以了解Hammer或其他Candlestick pattern形成的日期。

用户在执行程序时必须输入2个日期作为参数,例如 java ReadingTest 2016-09-03 2016-10-31 ,该计划将寻找2016-09-03至2016-10-31的Hammer模式。

代码如下:

import java.io.*;
import java.util.*;
import java.text.*;

public class ReadingTest
{
    public static void main(String[] args) throws IOException,ParseException
    {
    //Import file to java
    File file = new file("table.csv");

    //Read the file
    Scanner infile = new Scanner(file);

    //Skip the first line in table.csv
    infile.nextLine();

    //Define format of date
    SImpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    //Name the variables user enters
    Date start = sdf.parse(args[0]);
    Date end = sdf.parse(args[1]);

    //Create ArrayList for each column of data
    ArrayList<String> date = new ArrayList<String>();
    ArrayList<Double> open = new ArrayList<Double>();
    ArrayList<Double> high = new ArrayList<Double>();
    ArrayList<Double> low = new ArrayList<Double>();
    ArrayList<Double> close = new ArrayList<Double>();

    while (infile.hasNext())
    {
        //Tokenize columns by comma
        String[] data = infile.nextLine().split(",");
        //Organize each column of data to one index of data array
        date.add(data[0]);
        open.add(Double.parseDouble(data[1]));
        high.add(Double.parseDouble(data[2]));
        low.add(Double.parseDouble(data[3]));
        close.add(Double.parseDouble(data[4]));
    }
    //Show options and ask user to choose
    System.out.println("1. Hammer");
    System.out.println("2. Three white soldiers");
    System.out.println("3. Bullish kicker");

    //Record user input and execute corresponding code
    Scanner input = new Scanner(System.in);
    int choice = input.nextInt();

    if (choice == 1)
        for (int i = 0; i < date.size(); i++)
            if (close.get(i) > open.get(i) &&
                close.get(i) > ((high.get(i)) + (low.get(i)))/2 &&
                ((close.get(i) - low.get(i))/2 > (high.get(i) - close.get(i)))
            System.out.println("Pattern found: " + date.get(i));
}
}

这段代码完美无缺。但是,最后一行代码中的输出是dd / MM / yyyy格式,我尝试使用sdf.parse(date.get(i))而不是date.get(i)来显示yyyy-MM中的结果-dd格式。使用sdf.parse(date.get(i))运行代码会返回以下错误:

Exception in thread "main" java.text.ParseException: Unparseable date: 
"25/10/2016" at 
java.text.DateFormat.parse(Unknown source) at ReadingTest.main(ReadingTest.java:59)

我还尝试仅使用以下内容显示显示Hammer的日期:

(date.get(i).after(start) && date.get(i).before(end))

并导致

error: cannot find symbol
symbol: method before(Date)
location: class String

CSV文件如下所示:

Date       Open  High  Low  Close  
31/10/2016 58.25 58.65 58.2 58.35
28/10/2016 58.95 59    58.3 58.35
.
.
.
1/8/2016   50.8  51.1 50.75  50.8

如何修改代码以使其有效?

3 个答案:

答案 0 :(得分:3)

我猜你想要的是这个

SimpleDateFormat hammerFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat slashFormat = new SimpleDateFormat("dd/MM/yyyy");

因此您可以将日期解析为yyyy-MM-dd表示,如此

hammerFormat.format(slashFormat.parse(date.get(i))));

完整代码

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

public class ReadingTest {
    public static void main(String[] args) throws IOException, ParseException {
        // Import file to java
        File file = new File("table.csv");

        // Read the file
        Scanner infile = new Scanner(file);

        // Skip the first line in table.csv
        infile.nextLine();

        // Define format of date
        SimpleDateFormat hammerFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat slashFormat = new SimpleDateFormat("dd/MM/yyyy");

        // Name the variables user enters
        Date start = hammerFormat.parse(args[0]);
        Date end = hammerFormat.parse(args[1]);

        // Create ArrayList for each column of data
        ArrayList < String > date = new ArrayList < String > ();
        ArrayList < Double > open = new ArrayList < Double > ();
        ArrayList < Double > high = new ArrayList < Double > ();
        ArrayList < Double > low = new ArrayList < Double > ();
        ArrayList < Double > close = new ArrayList < Double > ();

        while (infile.hasNext()) {
            // Tokenize columns by comma
            String[] data = infile.nextLine().split(",");
            // Organize each column of data to one index of data array
            date.add(data[0]);
            open.add(Double.parseDouble(data[1]));
            high.add(Double.parseDouble(data[2]));
            low.add(Double.parseDouble(data[3]));
            close.add(Double.parseDouble(data[4]));
        }
        // Show options and ask user to choose
        System.out.println("1. Hammer");
        System.out.println("2. Three white soldiers");
        System.out.println("3. Bullish kicker");

        // Record user input and execute corresponding code
        Scanner input = new Scanner(System.in);
        int choice = input.nextInt();

        if (choice == 1)
            for (int i = 0; i < date.size(); i++)
                if (close.get(i) > open.get(i) && close.get(i) > ((high.get(i)) + (low.get(i))) / 2 && ((close.get(i) - low.get(i)) / 2 > (high.get(i) - close.get(i))))
                    System.out.println("Pattern found: " + hammerFormat.format(slashFormat.parse(date.get(i))));
    }
}

编辑:

使用像这样的.csv文件格式(因为在代码中它显示为.split(",")

31/10/2016, 58.25, 58.65, 58.20, 58.35
28/10/2016, 58.95, 59.00, 58.30, 58.35
01/08/2016, 50.80, 51.10, 50.75, 50.80

对我来说很好。我在执行程序时传递了两个参数2016-09-03 2016-10-31

答案 1 :(得分:2)

文件中的格式没有格式&#34; yyyy-MM-dd&#34;,它有格式&#34; dd / MM / yyyy&#34;,所以你不能用你的变量解析它SDF。您可以定义第二种日期格式

SImpleDateFormat sdfParse = new SimpleDateFormat("dd/MM/yyyy");

然后用它解析并用你的格式化:

sdf.format(sdfParse.parse(date.get(i)))

希望能获得更好的结果。

答案 2 :(得分:1)

TL;博士

  

解析日期

仅使用 java.time 类进行日期工作。

LocalDate start = LocalDate.parse( "2018-10-27" );  // Parse input string as a date-only value (no time-of-day, no time zone), a `java.time.LocalDate` object.
  

...在if语句中,仅显示规定时间范围内的结果

if ( 
    ( ! stockDay.getDate().isBefore( start ) )     // A shorter way to ask "is equal to OR later" is "is NOT before". 
    && 
    stockDay.getDate().isBefore( stop )            // Half-Open approach, where beginning is *inclusive* while the ending is *exclusive*.
) { … }

更好的是,使用 ThreeTen-Extra 库中的LocalDateRange类代表您的起止日期范围。

if ( 
     LocalDateRange.of( start , stop )
                   .contains( LocalDate.parse( "2018-10-27" ) )
) { … }

详细

  

如何修改代码以使其有效?

你要问你可能会感到遗憾。我对这个答案感到有点疯狂,对Candlestick Hammer感到好奇,并希望与Java Streams合作更多。

修复日期时间处理

您正在使用几年前取代的麻烦的旧日期时间类,但 java.time 类。

此外,您正在滥用这些遗留类。您将日期值设置为日期时间类型。请改用java.time.LocalDate,以获取仅限日期的值。

您无法定义格式模式以匹配您的输入。您的模式显示"yyyy-MM-dd",但您的输入是按日 - 月 - 年订单而非年 - 月 - 日订单。定义格式模式以匹配您的字符串输入。使用现代课程DateTimeFormatter

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;

解析输入字符串。

LocalDate ld = LocalDate.parse( "31/10/2016" , f ) ;
  

ld.toString():2018-10-31

请注意,日期时间对象没有“格式”。格式与表示日期时间值/对象的文本相关,与从日期时间对象生成的String对象相关。但是日期时间对象和String保持独立且不同。

顺便说一下,不要为输入使用这种自定义或本地化格式。 在将日期时间值作为文本交换时始终使用标准ISO 8601格式。在解析/生成字符串时, java.time 类默认使用这些标准格式。

定义数据模型的类

不要乱用数组或一堆List个对象,而是为数据定义一个类。将其命名为StockDay,以表示股票在特定日期的表现。

切勿使用doubleDoublefloatFloat来代表金钱。这些类型使用floating-point technology来消除准确性以获得更快的执行性能。而是使用BigDecimal类;慢,但准确。

在这个类中,我们在定义Candlestick Hammer时包含业务逻辑。为简单起见,我采用了更严格的定义,不允许上层“阴影”。所有这些代码仅供演示使用,完全未经测试:使用风险自负。

package com.basilbourque.example;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects;

public class StockDay implements Comparable < StockDay > {

    // Example data:
    // Date       Open  High  Low  Close
    // 31/10/2016 58.25 58.65 58.2 58.35

    // ---------|  Members  |------------------------
    private LocalDate date;
    private BigDecimal open, high, low, close;
    private Boolean isHammer;

    // ---------|  Constructors  |------------------------
    public StockDay ( final LocalDate localDateArg , final BigDecimal openArg , final BigDecimal highArg , final BigDecimal lowArg , final BigDecimal closeArg ) {
        // In real work, add defensive code to validate data such as no nulls, only positive numbers, reasonable dates.
        this.date = localDateArg;
        this.open = openArg;
        this.high = highArg;
        this.low = lowArg;
        // Verify the high is greater than or equal to the low.
        if ( this.high.compareTo( this.low ) < 0 ) {
            throw new IllegalArgumentException( "The passed High is below the passed Low for Date of " + this.date + ". Not possible." );
        }
        this.close = closeArg;
        this.isHammer = this.determineHammer();
    }

    private Boolean determineHammer () {
        // A hammer is a price pattern in candlestick charting that occurs when a security trades significantly lower than its opening, but rallies later in the day to close either above or near its opening price. This pattern forms a hammer-shaped candlestick, in which the body is at least half the size of the tail or wick.
        // Read more: Hammer https://www.investopedia.com/terms/h/hammer.asp#ixzz5G6rqtbkv
        // See also: http://www.onlinetradingconcepts.com/TechnicalAnalysis/Candlesticks/Hammer.html

        // Caveat: This code is a quick rough draft, not thought-through, and totally untested. Use at your own risk. For demonstration purposes only.

        // First check if the High is above the Close. A Hammer has little or no upper  "shadow" (line protruding above the box). We'll go with "no shadow" for simplicity here.
        if ( this.high.compareTo( this.close ) > 0 ) { // if high > close, not a hammer.
            return Boolean.FALSE;
        }

        // Proceed with next check: Is "tail" (lower shadow) at least twice as long as height of box.
        BigDecimal closeOpenDeltaAbsolute_BoxHeight = this.close.subtract( this.open ).abs();
        BigDecimal lowerOfCloseOrOpen = ( this.close.compareTo( this.open ) < 0 ) ? this.close : this.open;  // If x is smaller than y, use x. If x is greater than or equal to y, use y.
        BigDecimal lowerShadowHeight = lowerOfCloseOrOpen.subtract( this.low );
        // A Hammer has a long lower shadow (delta between either Close or Open, whichever is lower, and the Low), at least twice as tall as the box (Close-Open absolute delta).
        BigDecimal requiredMinimumLengthFactorOfShadow = new BigDecimal( "2" );
        BigDecimal doubleCloseOpenDeltaAbsolute = closeOpenDeltaAbsolute_BoxHeight.multiply( requiredMinimumLengthFactorOfShadow );
        Boolean hammer = ( lowerShadowHeight.compareTo( doubleCloseOpenDeltaAbsolute ) > 0 );
        return hammer;

    }


    // ---------|  Accessors  |------------------------
    // All fields are read-only. Just getters, no setters.
    public LocalDate getDate () {
        return this.date;
    }

    public BigDecimal getOpen () {
        return this.open;
    }

    public BigDecimal getHigh () {
        return this.high;
    }

    public BigDecimal getLow () {
        return this.low;
    }

    public BigDecimal getClose () {
        return this.close;
    }

    public Boolean isHammer () {
        return this.isHammer;
    }

    // ---------|  Override `Object`  |------------------------
    @Override
    public String toString () {
        return "StockDay{ " +
                "date=" + this.date +
                ", open=" + this.open +
                ", high=" + this.high +
                ", low=" + this.low +
                ", close=" + this.close +
                ", isHammer=" + this.isHammer +
                " }";
    }

    @Override
    public boolean equals ( final Object oArg ) {
        if ( this == oArg ) return true;
        if ( oArg == null || getClass() != oArg.getClass() ) return false;
        final StockDay stockDay = ( StockDay ) oArg;
        return Objects.equals( this.date , stockDay.date ) &&
                Objects.equals( this.open , stockDay.open ) &&
                Objects.equals( this.high , stockDay.high ) &&
                Objects.equals( this.low , stockDay.low ) &&
                Objects.equals( this.close , stockDay.close );
        // Perhaps this should be coded to only consider the `LocalDate` field alone.
    }

    @Override
    public int hashCode () {
        return Objects.hash( this.date , this.open , this.high , this.low , this.close );
        // Perhaps this should be coded to only consider the `LocalDate` field alone.
    }


    @Override
    public int compareTo ( final StockDay o ) {
        // Compare the date field only.
        int result = this.getDate().compareTo( o.getDate() );
        return result;
    }
}

定义用于加载数据的类

创建一个类来加载CSV数据。

package com.basilbourque.example;

import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class StockDayLoader {
    final private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );  // Tip: Instead of this custom format, use standard ISO 8601 formats when exchanging date-time values as text.

    public List < StockDay > loadFrom ( final Reader input ) {
        final List < StockDay > stockDays = new ArrayList <>();  // To be populated by lines of data read from the input.

        try (  // try-with-resources
               Scanner scanner = new Scanner( input ).useDelimiter( "\r\n" ) ; // Delimiter is a comma between fields.
        ) {
            scanner.useLocale( Locale.US ); // Determines cultural norms such as FULL STOP versus COMMA for decimal point in a `BigDecimal`.

            // Skip first line, the column headers.
            if ( scanner.hasNextLine() ) {
                String headers = scanner.nextLine(); // Ignore returned String.
                if ( ! "Date,Open,High,Low,Close".equals( headers ) ) { // Verify expected input.
                    throw new IllegalArgumentException( "The passed Readable object’s first row does not consist of expected column header names." );
                }
            }

            while ( scanner.hasNextLine() ) {
                String line = scanner.nextLine(); // Grab entire line.
                try (
                        Scanner lineScanner = new Scanner( line ).useDelimiter( "," ).useLocale( Locale.US ) ;
                ) {
                    String dateInput = lineScanner.next();
                    LocalDate date = LocalDate.parse( dateInput , this.dateFormatter );
                    try {
                        BigDecimal open = lineScanner.nextBigDecimal();
                        BigDecimal high = lineScanner.nextBigDecimal();
                        BigDecimal low = lineScanner.nextBigDecimal();
                        BigDecimal close = lineScanner.nextBigDecimal();
                        StockDay stockDay = new StockDay( date , open , high , low , close );
                        stockDays.add( stockDay );  // Collect the newly intanstiated `StockDay` object.
                    } catch ( InputMismatchException e ) {
                        System.out.println( "ERROR The next token does not match the Decimal regular expression, or is out of range.  " );
                        e.printStackTrace();
                    }
                }
            }

            return stockDays;
        }
    }


    // -----------|  Testing/Demo  |------------------------

    public static String bogusData () {
        final String eol = "\r\n";   // RFC 4180 requires CrLf as end-of-line.
        final StringBuilder sb = new StringBuilder();
        sb.append( "Date,Open,High,Low,Close" + eol );
        sb.append( "31/10/2016,58.25,58.65,58.2,58.35" + eol );
        sb.append( "28/10/2016,58.95,59,58.3,58.35" + eol );
        sb.append( "27/10/2016,58.78,58.22,33.3,58.55" + eol ); // Hammer.
        sb.append( "26/10/2016,58.95,59.05,58.43,58.45" + eol );
        sb.append( "25/10/2016,58.99,58.44,22.2,58.57" + eol ); // Hammer.
        String s = sb.toString();
        return s;
    }

    public static void main ( String[] args ) {
        String s = StockDayLoader.bogusData();
        Reader reader = new StringReader( s );

        StockDayLoader loader = new StockDayLoader();
        List < StockDay > list = loader.loadFrom( reader );

        System.out.println( list );
    }

}

Apache Commons CSV

更好的是,不是编写自己的CSV阅读器,而是利用Apache Commons CSV等库中现有的经过良好测试的代码。

package com.basilbourque.example;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class StockDayLoaderEasy {

    final private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );  // Tip: Instead of this custom format, use standard ISO 8601 formats when exchanging date-time values as text.

    public List < StockDay > loadFrom ( final Reader reader ) {
        final List < StockDay > stockDays = new ArrayList <>();  // To be populated by lines of data read from the input.

        Iterable < CSVRecord > records = null;
        try {
            records = CSVFormat.RFC4180.parse( reader );
        } catch ( IOException eArg ) {
            eArg.printStackTrace();
        }

        // Read each column. Names:  "Date,Open,High,Low,Close"
        for ( CSVRecord record : records ) {
            LocalDate date = LocalDate.parse( record.get( "Date" ) , this.dateFormatter );
            BigDecimal open = new BigDecimal( record.get( "Open" ) );
            BigDecimal high = new BigDecimal( record.get( "High" ) );
            BigDecimal low = new BigDecimal( record.get( "Low" ) );
            BigDecimal close = new BigDecimal( record.get( "Close" ) );

            StockDay stockDay = new StockDay( date , open , high , low , close );
            stockDays.add( stockDay );  // Collect the newly intanstiated `StockDay` object.
        }
        return stockDays;
    }

    // -----------|  Testing/Demo  |------------------------

    public static String bogusData () {
        final String eol = "\r\n";   // RFC 4180 requires CrLf as end-of-line.
        final StringBuilder sb = new StringBuilder();
        sb.append( "Date,Open,High,Low,Close" + eol );
        sb.append( "31/10/2016,58.25,58.65,58.2,58.35" + eol );
        sb.append( "28/10/2016,58.95,59,58.3,58.35" + eol );
        sb.append( "27/10/2016,58.78,58.22,33.3,58.55" + eol ); // Hammer.
        sb.append( "26/10/2016,58.95,59.05,58.43,58.45" + eol );
        sb.append( "25/10/2016,58.99,58.44,22.2,58.57" + eol ); // Hammer.
        String s = sb.toString();
        return s;
    }

    public static void main ( String[] args ) {
        String s = StockDayLoader.bogusData();
        Reader reader = new StringReader( s );

        StockDayLoader loader = new StockDayLoader();
        List < StockDay > list = loader.loadFrom( reader );

        System.out.println( list );
    }
}

将它们全部拉出来

创建一个应用程序来练习这些作品。

该课题的目的是找出哪些股票日报告符合(a)日期范围内的日期标准,(b)是锤子。

这里有几个简短的例子。有些使用老式的Java语法,有些使用现代的Streams / Lambda语法,两种方式都有相同的结果。阅读代码注释以获得指导。

package com.basilbourque.example;

import org.threeten.extra.LocalDateRange;

import java.io.Reader;
import java.io.StringReader;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class HammerTime {
    public static void main ( String[] args ) {
        HammerTime hammerTime = new HammerTime();
        hammerTime.doIt();
    }

    private void doIt () {
        // Load all data.
        Reader reader = new StringReader( StockDayLoader.bogusData() );
        List < StockDay > stockDays = new StockDayLoader().loadFrom( reader );
        Collections.sort( stockDays );  // Sort chronologically, ascending order, oldest first. For newest first, call `Collections.reverse`.
        System.out.println( "All stockDays = " + stockDays );

        // Find hammers using the old-fashioned way.
        List < StockDay > hammers = new ArrayList <>();
        for ( StockDay stockDay : stockDays ) {
            if ( stockDay.isHammer() ) {
                hammers.add( stockDay );
            }
        }
        System.out.println( "hammers: " + hammers );

        // Find hammers using modern Streams/Lambda features, while tolerating NULLs.
        List < StockDay > hammers2 = stockDays.stream()
                .filter( stockDay -> Objects.equals( stockDay.isHammer() , Boolean.TRUE ) )  // Use `Objects.equals` to tolerate NULL values.
                .collect( Collectors.toList() );
        System.out.println( "hammers2: " + hammers2 );

        // Find hammers using modern Streams/Lambda features, assuming no NULL values exist.
        List < StockDay > hammers3 = stockDays.stream()
                .filter( stockDay -> stockDay.isHammer().equals( Boolean.TRUE ) )  // Simpler syntax than above, if you are certain of no NULLs.
                .collect( Collectors.toList() );
        System.out.println( "hammers3: " + hammers3 );

        // Find hammers within a certain date-range, per the original Question.

        // Parse the user’s input start/stop dates.
        LocalDate start = LocalDate.parse( "2016-10-26" ); // This range should pick up the hammer on the 27th while omitting the hammer on the 25th.
        LocalDate stop = LocalDate.parse( "2016-10-28" ); // Usual practice in defining a span-of-time is the Half-Open approach, where the beginning is *inclusive* while the ending is *exclusive*.

        // Find hammers within date range using the old-fashioned syntax, with built-in classes.
        List < StockDay > hammersInDateRange1 = new ArrayList <>();
        for ( StockDay stockDay : stockDays ) {
            if ( stockDay.isHammer() ) {
                if ( ( ! stockDay.getDate().isBefore( start ) ) && stockDay.getDate().isBefore( stop ) ) {
                    hammersInDateRange1.add( stockDay );
                }
            }
        }
        System.out.println( "hammersInDateRange1: " + hammersInDateRange1 );

        // Find hammers within date range using the old-fashioned syntax, with the ThreeTen-Extra library and its `LocalDateRange` class.  http://www.threeten.org/threeten-extra/
        final LocalDateRange dateRange = LocalDateRange.of( start , stop );
        List < StockDay > hammersInDateRange2 = new ArrayList <>();
        for ( StockDay stockDay : stockDays ) {
            if ( stockDay.isHammer() ) {
                if ( dateRange.contains( stockDay.getDate() ) ) {
                    hammersInDateRange2.add( stockDay );
                }
            }
        }
        System.out.println( "hammersInDateRange2: " + hammersInDateRange2 );

        // Find hammers within date range using modern Streams/Lambda syntax, with the ThreeTen-Extra library and its `LocalDateRange` class.  http://www.threeten.org/threeten-extra/
        List < StockDay > hammersInDateRange3 = stockDays.stream()
                .filter( stockDay -> stockDay.isHammer() && dateRange.contains( stockDay.getDate() ) )  // Assumes no NULLs.
                .collect( Collectors.toList() );
        System.out.println( "hammersInDateRange3: " + hammersInDateRange3 );


    }
}

跑步时。

  

所有stockDays = [StockDay {date = 2016-10-25,open = 58.99,high = 58.44,low = 22.2,close = 58.57,isHammer = true},StockDay {date = 2016-10-26,open = 58.95,高= 59.05,低= 58.43,收盘= 58.45,isHammer = false},StockDay {date = 2016-10-27,open = 58.78,high = 58.22,low = 33.3,close = 58.55,isHammer = true}, StockDay {date = 2016-10-28,open = 58.95,high = 59,low = 58.3,close = 58.35,isHammer = false},StockDay {date = 2016-10-31,open = 58.25,high = 58.65,low = 58.2,close = 58.35,isHammer = false}]

     锤子:[StockDay {date = 2016-10-25,open = 58.99,high = 58.44,low = 22.2,close = 58.57,isHammer = true},StockDay {date = 2016-10-27,open = 58.78 ,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

     

hammers2:[StockDay {date = 2016-10-25,open = 58.99,high = 58.44,low = 22.2,close = 58.57,isHammer = true},StockDay {date = 2016-10-27,open = 58.78 ,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

     

hammers3:[StockDay {date = 2016-10-25,open = 58.99,high = 58.44,low = 22.2,close = 58.57,isHammer = true},StockDay {date = 2016-10-27,open = 58.78 ,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

     

hammersInDateRange1:[StockDay {date = 2016-10-27,open = 58.78,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

     

hammersInDateRange2:[StockDay {date = 2016-10-27,open = 58.78,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

     

hammersInDateRange3:[StockDay {date = 2016-10-27,open = 58.78,high = 58.22,low = 33.3,close = 58.55,isHammer = true}]

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore