目前我正在撰写一个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
如何修改代码以使其有效?
答案 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)
解析日期
仅使用 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
,以表示股票在特定日期的表现。
切勿使用double
或Double
,float
或Float
来代表金钱。这些类型使用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 );
}
}
更好的是,不是编写自己的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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。