java velocity 日期_Java的时间日期API

Java为我们提供的时间日期的类有老的java.util.Date和java.util.Calender,以及新的java.time包

java.time包基于Joda-Time库构建

本章学习目标:

掌握Java8中提供的java.time包中的常用日期类与相关方法

可以从java.util包下的日期类过渡到java.time包下的日期类

掌握java8中的日期与字符串之间的相互转换

为什么会出现新的日期类API

java.util.Date和java.util.Calender类不是线程安全的

将java.util.Date类束之高阁才是正确之道。

—— 鲁迅(实际是Tim Yates)

在Java面世之初,标准库就引入了两种用于处理日期和时间的类,它们是java.util.Date和java.util.Calender,这两个类存在不少问题。

日期计算困难

毫秒值与日期直接转换比较繁琐,其次通过毫秒值来计算时间的差额步骤较多

/*** 程序员小李出生于1995年12月16日,计算当前这个时间他已经出生了多少天?

* 步骤:

* 1.初始化Date对象,无参构造(无参构造默认代表的就是当前时间)

* 2.获取当前时间距离1970年1月1日过了多少毫秒

* 3.初始化Calender对象并设时间为1995年12月16日,并将Calender对象转为Date对象,再转换为距离1970年1月1日过了多少毫秒

* 4.将两个毫秒数相减,然后将毫秒转为天数

**/

public classJavaUtilTimeCalculateDemo {public static voidmain(String[] args) {

Date date= newDate();long s1 = date.getTime(); //获取当前时间距离1970年1月1日过了多少毫秒

Calendar calendar=Calendar.getInstance();

calendar.set(1995, 11, 16); //这里的第二个参数是月,月从0开始,因此这里要写11。这里由于混乱,非常容易犯错。

Date date1=calendar.getTime();long s2 =date1.getTime();long intervalDays = (s1 - s2)/1000/60/60/24;

System.out.println("1995年12月16日距离现在已经过了"+intervalDays+"天");

}

}

结果

1995年12月16日距离现在已经过了9041天

使用新版本API

public classJavaUtilTimeCalculateDemo {public static voidmain(String[] args) {long days = ChronoUnit.DAYS.between(LocalDate.of(1995, 12, 16), LocalDate.now());

System.out.println("1995年12月16日距离现在已经过了"+days+"天");

}

}

结果

1995年12月16日距离现在已经过了9042天

新版本计算结果是正确的,老版本不仅繁琐还容易出错

线程安全问题

/*** 创建十个线程,将字符串"2018-12-12 12:12:12"转换为Date对象后打印到控制台上

**/

public classSimpleDateFormatUnSafeDemo {final static SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static voidmain(String[] args) {//循环十次,创建是个线程对象并启动

for (int i=0; i<10; i++){new Thread(newRunnable() {

@Overridepublic voidrun() {try{

Date date= SIMPLE_DATE_FORMAT.parse("2018-12-12 12:12:12");

System.out.println(date);

}catch(ParseException e) {

e.printStackTrace();

}

}

}).start();

}

}

}

IDEA控制台结果:

D:\programfiles\jdk8\bin\java.exe "-javaagent:D:\programfiles\IntelliJ IDEA 2020.1\lib\idea_rt.jar=10259:D:\programfiles\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath D:\programfiles\jdk8\jre\lib\charsets.jar;D:\programfiles\jdk8\jre\lib\deploy.jar;D:\programfiles\jdk8\jre\lib\ext\access-bridge-64.jar;D:\programfiles\jdk8\jre\lib\ext\cldrdata.jar;D:\programfiles\jdk8\jre\lib\ext\dnsns.jar;D:\programfiles\jdk8\jre\lib\ext\jaccess.jar;D:\programfiles\jdk8\jre\lib\ext\jfxrt.jar;D:\programfiles\jdk8\jre\lib\ext\localedata.jar;D:\programfiles\jdk8\jre\lib\ext\nashorn.jar;D:\programfiles\jdk8\jre\lib\ext\sunec.jar;D:\programfiles\jdk8\jre\lib\ext\sunjce_provider.jar;D:\programfiles\jdk8\jre\lib\ext\sunmscapi.jar;D:\programfiles\jdk8\jre\lib\ext\sunpkcs11.jar;D:\programfiles\jdk8\jre\lib\ext\zipfs.jar;D:\programfiles\jdk8\jre\lib\javaws.jar;D:\programfiles\jdk8\jre\lib\jce.jar;D:\programfiles\jdk8\jre\lib\jfr.jar;D:\programfiles\jdk8\jre\lib\jfxswt.jar;D:\programfiles\jdk8\jre\lib\jsse.jar;D:\programfiles\jdk8\jre\lib\management-agent.jar;D:\programfiles\jdk8\jre\lib\plugin.jar;D:\programfiles\jdk8\jre\lib\resources.jar;D:\programfiles\jdk8\jre\lib\rt.jar;D:\gitprojects\DataAnalySystem\Common\target\classes;C:\Users\My\.m2\repository\cn\hutool\hutool-all\5.4.2\hutool-all-5.4.2.jar;C:\Users\My\.m2\repository\com\alibaba\fastjson\1.2.58\fastjson-1.2.58.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-client\2.0.0\hbase-client-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\thirdparty\hbase-shaded-protobuf\2.1.0\hbase-shaded-protobuf-2.1.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-common\2.0.0\hbase-common-2.0.0.jar;C:\Users\My\.m2\repository\com\github\stephenc\findbugs\findbugs-annotations\1.3.9-1\findbugs-annotations-1.3.9-1.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-hadoop-compat\2.0.0\hbase-hadoop-compat-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-metrics-api\2.0.0\hbase-metrics-api-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-hadoop2-compat\2.0.0\hbase-hadoop2-compat-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-metrics\2.0.0\hbase-metrics-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-protocol-shaded\2.0.0\hbase-protocol-shaded-2.0.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\hbase-protocol\2.0.0\hbase-protocol-2.0.0.jar;C:\Users\My\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\My\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\My\.m2\repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;C:\Users\My\.m2\repository\commons-io\commons-io\2.5\commons-io-2.5.jar;C:\Users\My\.m2\repository\org\apache\commons\commons-lang3\3.7\commons-lang3-3.7.jar;C:\Users\My\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\My\.m2\repository\org\apache\hbase\thirdparty\hbase-shaded-miscellaneous\2.1.0\hbase-shaded-miscellaneous-2.1.0.jar;C:\Users\My\.m2\repository\com\google\protobuf\protobuf-java\2.5.0\protobuf-java-2.5.0.jar;C:\Users\My\.m2\repository\org\apache\hbase\thirdparty\hbase-shaded-netty\2.1.0\hbase-shaded-netty-2.1.0.jar;C:\Users\My\.m2\repository\org\apache\zookeeper\zookeeper\3.4.10\zookeeper-3.4.10.jar;C:\Users\My\.m2\repository\org\apache\htrace\htrace-core4\4.2.0-incubating\htrace-core4-4.2.0-incubating.jar;C:\Users\My\.m2\repository\org\jruby\jcodings\jcodings\1.0.18\jcodings-1.0.18.jar;C:\Users\My\.m2\repository\org\jruby\joni\joni\2.1.11\joni-2.1.11.jar;C:\Users\My\.m2\repository\io\dropwizard\metrics\metrics-core\3.2.6\metrics-core-3.2.6.jar;C:\Users\My\.m2\repository\org\apache\commons\commons-crypto\1.0.0\commons-crypto-1.0.0.jar;C:\Users\My\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.5\jackson-databind-2.9.5.jar;C:\Users\My\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-auth\2.7.4\hadoop-auth-2.7.4.jar;C:\Users\My\.m2\repository\org\apache\directory\server\apacheds-kerberos-codec\2.0.0-M15\apacheds-kerberos-codec-2.0.0-M15.jar;C:\Users\My\.m2\repository\org\apache\directory\server\apacheds-i18n\2.0.0-M15\apacheds-i18n-2.0.0-M15.jar;C:\Users\My\.m2\repository\org\apache\directory\api\api-asn1-api\1.0.0-M20\api-asn1-api-1.0.0-M20.jar;C:\Users\My\.m2\repository\org\apache\directory\api\api-util\1.0.0-M20\api-util-1.0.0-M20.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-common\2.7.4\hadoop-common-2.7.4.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-annotations\2.7.4\hadoop-annotations-2.7.4.jar;C:\Users\My\.m2\repository\commons-cli\commons-cli\1.2\commons-cli-1.2.jar;C:\Users\My\.m2\repository\org\apache\commons\commons-math3\3.1.1\commons-math3-3.1.1.jar;C:\Users\My\.m2\repository\xmlenc\xmlenc\0.52\xmlenc-0.52.jar;C:\Users\My\.m2\repository\commons-net\commons-net\3.1\commons-net-3.1.jar;C:\Users\My\.m2\repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\Users\My\.m2\repository\org\mortbay\jetty\jetty-sslengine\6.1.26\jetty-sslengine-6.1.26.jar;C:\Users\My\.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\Users\My\.m2\repository\commons-configuration\commons-configuration\1.6\commons-configuration-1.6.jar;C:\Users\My\.m2\repository\commons-digester\commons-digester\1.8\commons-digester-1.8.jar;C:\Users\My\.m2\repository\commons-beanutils\commons-beanutils\1.7.0\commons-beanutils-1.7.0.jar;C:\Users\My\.m2\repository\commons-beanutils\commons-beanutils-core\1.8.0\commons-beanutils-core-1.8.0.jar;C:\Users\My\.m2\repository\org\codehaus\jackson\jackson-core-asl\1.9.13\jackson-core-asl-1.9.13.jar;C:\Users\My\.m2\repository\org\codehaus\jackson\jackson-mapper-asl\1.9.13\jackson-mapper-asl-1.9.13.jar;C:\Users\My\.m2\repository\org\apache\avro\avro\1.7.4\avro-1.7.4.jar;C:\Users\My\.m2\repository\com\thoughtworks\paranamer\paranamer\2.3\paranamer-2.3.jar;C:\Users\My\.m2\repository\com\google\code\gson\gson\2.8.4\gson-2.8.4.jar;C:\Users\My\.m2\repository\com\jcraft\jsch\0.1.54\jsch-0.1.54.jar;C:\Users\My\.m2\repository\org\apache\curator\curator-client\2.7.1\curator-client-2.7.1.jar;C:\Users\My\.m2\repository\org\apache\curator\curator-recipes\4.0.1\curator-recipes-4.0.1.jar;C:\Users\My\.m2\repository\com\google\code\findbugs\jsr305\3.0.0\jsr305-3.0.0.jar;C:\Users\My\.m2\repository\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;C:\Users\My\.m2\repository\org\apache\kafka\kafka-clients\2.1.0\kafka-clients-2.1.0.jar;C:\Users\My\.m2\repository\com\github\luben\zstd-jni\1.3.5-4\zstd-jni-1.3.5-4.jar;C:\Users\My\.m2\repository\org\lz4\lz4-java\1.5.0\lz4-java-1.5.0.jar;C:\Users\My\.m2\repository\org\xerial\snappy\snappy-java\1.1.7.2\snappy-java-1.1.7.2.jar;C:\Users\My\.m2\repository\ru\yandex\clickhouse\clickhouse-jdbc\0.1.40\clickhouse-jdbc-0.1.40.jar;C:\Users\My\.m2\repository\org\apache\httpcomponents\httpclient\4.5.5\httpclient-4.5.5.jar;C:\Users\My\.m2\repository\org\apache\httpcomponents\httpmime\4.5.5\httpmime-4.5.5.jar;C:\Users\My\.m2\repository\net\jpountz\lz4\lz4\1.3.0\lz4-1.3.0.jar;C:\Users\My\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.5\jackson-core-2.9.5.jar;C:\Users\My\.m2\repository\com\google\guava\guava\19.0\guava-19.0.jar;C:\Users\My\.m2\repository\joda-time\joda-time\2.9.9\joda-time-2.9.9.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-exec\1.1.0\hive-exec-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-ant\1.1.0\hive-ant-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\velocity\velocity\1.5\velocity-1.5.jar;C:\Users\My\.m2\repository\oro\oro\2.0.8\oro-2.0.8.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-metastore\1.1.0\hive-metastore-1.1.0.jar;C:\Users\My\.m2\repository\com\jolbox\bonecp\0.8.0.RELEASE\bonecp-0.8.0.RELEASE.jar;C:\Users\My\.m2\repository\org\apache\derby\derby\10.14.1.0\derby-10.14.1.0.jar;C:\Users\My\.m2\repository\org\datanucleus\datanucleus-api-jdo\3.2.6\datanucleus-api-jdo-3.2.6.jar;C:\Users\My\.m2\repository\org\datanucleus\datanucleus-rdbms\3.2.9\datanucleus-rdbms-3.2.9.jar;C:\Users\My\.m2\repository\commons-pool\commons-pool\1.6\commons-pool-1.6.jar;C:\Users\My\.m2\repository\commons-dbcp\commons-dbcp\1.4\commons-dbcp-1.4.jar;C:\Users\My\.m2\repository\javax\jdo\jdo-api\3.0.1\jdo-api-3.0.1.jar;C:\Users\My\.m2\repository\javax\transaction\jta\1.1\jta-1.1.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-shims\1.1.0\hive-shims-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\shims\hive-shims-common\1.1.0\hive-shims-common-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\shims\hive-shims-0.20S\1.1.0\hive-shims-0.20S-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\shims\hive-shims-0.23\1.1.0\hive-shims-0.23-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-server-resourcemanager\2.6.0\hadoop-yarn-server-resourcemanager-2.6.0.jar;C:\Users\My\.m2\repository\com\google\inject\extensions\guice-servlet\3.0\guice-servlet-3.0.jar;C:\Users\My\.m2\repository\com\google\inject\guice\3.0\guice-3.0.jar;C:\Users\My\.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar;C:\Users\My\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\My\.m2\repository\com\sun\jersey\jersey-json\1.9\jersey-json-1.9.jar;C:\Users\My\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.3-1\jaxb-impl-2.2.3-1.jar;C:\Users\My\.m2\repository\org\codehaus\jackson\jackson-jaxrs\1.8.3\jackson-jaxrs-1.8.3.jar;C:\Users\My\.m2\repository\org\codehaus\jackson\jackson-xc\1.8.3\jackson-xc-1.8.3.jar;C:\Users\My\.m2\repository\com\sun\jersey\contribs\jersey-guice\1.9\jersey-guice-1.9.jar;C:\Users\My\.m2\repository\com\sun\jersey\jersey-server\1.19.1\jersey-server-1.19.1.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-common\2.6.0\hadoop-yarn-common-2.6.0.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-api\2.6.0\hadoop-yarn-api-2.6.0.jar;C:\Users\My\.m2\repository\javax\xml\bind\jaxb-api\2.3.0\jaxb-api-2.3.0.jar;C:\Users\My\.m2\repository\org\codehaus\jettison\jettison\1.1\jettison-1.1.jar;C:\Users\My\.m2\repository\com\sun\jersey\jersey-core\1.19.1\jersey-core-1.19.1.jar;C:\Users\My\.m2\repository\javax\ws\rs\jsr311-api\1.1.1\jsr311-api-1.1.1.jar;C:\Users\My\.m2\repository\com\sun\jersey\jersey-client\1.19.1\jersey-client-1.19.1.jar;C:\Users\My\.m2\repository\org\mortbay\jetty\jetty-util\6.1.26\jetty-util-6.1.26.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-server-common\2.6.0\hadoop-yarn-server-common-2.6.0.jar;C:\Users\My\.m2\repository\org\fusesource\leveldbjni\leveldbjni-all\1.8\leveldbjni-all-1.8.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-server-applicationhistoryservice\2.6.0\hadoop-yarn-server-applicationhistoryservice-2.6.0.jar;C:\Users\My\.m2\repository\org\apache\hadoop\hadoop-yarn-server-web-proxy\2.6.0\hadoop-yarn-server-web-proxy-2.6.0.jar;C:\Users\My\.m2\repository\org\mortbay\jetty\jetty\6.1.26\jetty-6.1.26.jar;C:\Users\My\.m2\repository\org\apache\hive\shims\hive-shims-scheduler\1.1.0\hive-shims-scheduler-1.1.0.jar;C:\Users\My\.m2\repository\commons-httpclient\commons-httpclient\3.0.1\commons-httpclient-3.0.1.jar;C:\Users\My\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\My\.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Users\My\.m2\repository\log4j\apache-log4j-extras\1.2.17\apache-log4j-extras-1.2.17.jar;C:\Users\My\.m2\repository\org\antlr\antlr-runtime\3.4\antlr-runtime-3.4.jar;C:\Users\My\.m2\repository\org\antlr\stringtemplate\3.2.1\stringtemplate-3.2.1.jar;C:\Users\My\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\My\.m2\repository\org\antlr\ST4\4.0.4\ST4-4.0.4.jar;C:\Users\My\.m2\repository\org\apache\ant\ant\1.9.1\ant-1.9.1.jar;C:\Users\My\.m2\repository\org\apache\ant\ant-launcher\1.9.1\ant-launcher-1.9.1.jar;C:\Users\My\.m2\repository\org\apache\commons\commons-compress\1.4.1\commons-compress-1.4.1.jar;C:\Users\My\.m2\repository\org\tukaani\xz\1.0\xz-1.0.jar;C:\Users\My\.m2\repository\org\apache\thrift\libfb303\0.9.2\libfb303-0.9.2.jar;C:\Users\My\.m2\repository\org\apache\curator\curator-framework\4.0.1\curator-framework-4.0.1.jar;C:\Users\My\.m2\repository\org\codehaus\groovy\groovy-all\2.4.15\groovy-all-2.4.15.jar;C:\Users\My\.m2\repository\org\datanucleus\datanucleus-core\3.2.10\datanucleus-core-3.2.10.jar;C:\Users\My\.m2\repository\org\apache\calcite\calcite-core\1.0.0-incubating\calcite-core-1.0.0-incubating.jar;C:\Users\My\.m2\repository\org\apache\calcite\calcite-linq4j\1.0.0-incubating\calcite-linq4j-1.0.0-incubating.jar;C:\Users\My\.m2\repository\eigenbase\eigenbase-properties\1.1.4\eigenbase-properties-1.1.4.jar;C:\Users\My\.m2\repository\org\codehaus\janino\janino\3.0.8\janino-3.0.8.jar;C:\Users\My\.m2\repository\org\codehaus\janino\commons-compiler\2.7.6\commons-compiler-2.7.6.jar;C:\Users\My\.m2\repository\org\apache\calcite\calcite-avatica\1.0.0-incubating\calcite-avatica-1.0.0-incubating.jar;C:\Users\My\.m2\repository\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\Users\My\.m2\repository\jline\jline\2.12\jline-2.12.jar;C:\Users\My\.m2\repository\org\slf4j\slf4j-log4j12\1.7.25\slf4j-log4j12-1.7.25.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-jdbc\1.1.0\hive-jdbc-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-common\1.1.0\hive-common-1.1.0.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-service\1.1.0\hive-service-1.1.0.jar;C:\Users\My\.m2\repository\net\sf\jpam\jpam\1.1\jpam-1.1.jar;C:\Users\My\.m2\repository\org\eclipse\jetty\aggregate\jetty-all\7.6.0.v20120127\jetty-all-7.6.0.v20120127.jar;C:\Users\My\.m2\repository\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar;C:\Users\My\.m2\repository\org\apache\geronimo\specs\geronimo-jta_1.1_spec\1.1.1\geronimo-jta_1.1_spec-1.1.1.jar;C:\Users\My\.m2\repository\javax\mail\mail\1.4.1\mail-1.4.1.jar;C:\Users\My\.m2\repository\javax\activation\activation\1.1\activation-1.1.jar;C:\Users\My\.m2\repository\org\apache\geronimo\specs\geronimo-jaspic_1.0_spec\1.0\geronimo-jaspic_1.0_spec-1.0.jar;C:\Users\My\.m2\repository\org\apache\geronimo\specs\geronimo-annotation_1.0_spec\1.1.1\geronimo-annotation_1.0_spec-1.1.1.jar;C:\Users\My\.m2\repository\asm\asm-commons\3.1\asm-commons-3.1.jar;C:\Users\My\.m2\repository\asm\asm-tree\3.1\asm-tree-3.1.jar;C:\Users\My\.m2\repository\asm\asm\3.1\asm-3.1.jar;C:\Users\My\.m2\repository\org\apache\hive\hive-serde\1.1.0\hive-serde-1.1.0.jar;C:\Users\My\.m2\repository\net\sf\opencsv\opencsv\2.3\opencsv-2.3.jar;C:\Users\My\.m2\repository\com\twitter\parquet-hadoop-bundle\1.6.0rc3\parquet-hadoop-bundle-1.6.0rc3.jar;C:\Users\My\.m2\repository\org\apache\httpcomponents\httpcore\4.4.9\httpcore-4.4.9.jar;C:\Users\My\.m2\repository\org\apache\thrift\libthrift\0.9.2\libthrift-0.9.2.jar com.aidata.utils.SimpleDateFormatUnSafeDemo

Exception in thread"Thread-1"java.lang.NumberFormatException: empty String

at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)

at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)

at java.lang.Double.parseDouble(Double.java:538)

at java.text.DigitList.getDouble(DigitList.java:169)

at java.text.DecimalFormat.parse(DecimalFormat.java:2089)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)

at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)

at java.text.DateFormat.parse(DateFormat.java:364)

at com.aidata.utils.SimpleDateFormatUnSafeDemo$1.run(SimpleDateFormatUnSafeDemo.java:27)

at java.lang.Thread.run(Thread.java:748)

Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Wed Dec12 12:12:12 GMT+08:00 2018Process finished with exit code0

第27行报错,即标黄的那一行

全局使用同一个Calender对象,如果线程没有同步措施的话,很可能会造成线程安全问题

b868243fe476d02c5528b10af2ec7d34.png

如,线程一执行上面红色代码,线程二得到执行下面黄色代码,当线程一继续执行时,数据已被线程二清空,此时会报错。

解决

/*** 创建十个线程,将字符串"2018-12-12 12:12:12"转换为Date对象后打印到控制台上

**/

public classSimpleDateFormatUnSafeDemo {final static SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static voidmain(String[] args) {//循环十次,创建是个线程对象并启动

for (int i=0; i<10; i++){new Thread(newRunnable() {

@Overridepublic voidrun() {try{synchronized(SIMPLE_DATE_FORMAT){

Date date= SIMPLE_DATE_FORMAT.parse("2018-12-12 12:12:12");

System.out.println(date);

}

}catch(ParseException e) {

e.printStackTrace();

}

}

}).start();

}

}

}

另外,java.util.Date和java.util.Calender类之前,枚举类型(ENUM)还没有出现,所以字段中使用整数常量导致整数常量都是可变的,而不是线程安全的。为了处理实际开发中遇到的问题,标准库随后引入了java.sql.Data作为java.util.Date的子类,但还是没有彻底解决问题。

Java8新日期时间类的使用

Instant类

对时间轴上的单一瞬时点建模,可以用于记录应用程序中的事件时间戳,在之后学习的类型转换中,均可以使用Instant类作为中间类完成转换。

Duration类

表示秒或纳秒时间间隔,适合处理较短时间,需要更高的精确性 秒杀

Period类

表示一段时间的年、月、日

LocalDate类

是一个不可变的日期时间对象,表示日期,通常视为年月日 final修饰

LocalTime类

是一个不可变的日期时间对象,表示时间,通常视为时分秒,时间表示为纳秒精度

LocalDateTime类

是一个不可变的日期时间对象,代表日期时间,通常视为年月日时分秒

ZonedDateTime类

是具有失去的日期时间的不可变表示,此类存储所有日期和时间字段,精度为纳秒,时区为区域偏移量,用于处理模糊的本地日期时间。

创建对象

now()方法

所有类均生成不可变的实例,它们是线程安全的,这些类不提供公共构造函数,也就是说没办法通过new创建,需要采用工厂方法实例化。

now方法可以根据当前日期和时间创建实例

public classJava8TimeDateDemo {public static voidmain(String[] args) {

Instant instant=Instant.now();

LocalDate localDate=LocalDate.now();

LocalTime localTime=LocalTime.now();

LocalDateTime localDateTime=LocalDateTime.now();

ZonedDateTime zonedDateTime=ZonedDateTime.now();

System.out.println("Instant: "+instant);

System.out.println("LocalDate: "+localDate);

System.out.println("LocalTime: "+localTime);

System.out.println("LocalDateTime: "+localDateTime);

System.out.println("ZonedDateTime: "+zonedDateTime);

}

}

toSring方法都被重写了

结果

Instant: 2020-09-17T02:13:50.354Z 国际标准时

LocalDate:2020-09-17LocalTime:10:13:50.377LocalDateTime:2020-09-17T10:13:50.378ZonedDateTime:2020-09-17T10:13:50.380+08:00[GMT+08:00]

public classJava8TimeDateDemo {public static voidmain(String[] args) {//使用now方法创建Year类的实例对象

Year year =Year.now();//使用now方法创建YearMonth类的实例对象

YearMonth yearMonth =YearMonth.now();//使用now方法创建MonthDay的实例对象

MonthDay monthDay =MonthDay.now();

System.out.println("year: "+year);

System.out.println("yearMonth: "+yearMonth);

System.out.println("monthDay: "+monthDay);

}

}

结果

year: 2020yearMonth:2020-09monthDay:--09-17

of()方法

上面的now都是当前时间节点,想要指定时间节点怎么办呢?

of方法可以根据给定的参数生成对应的日期/时间对象,基本上每个基本类都有of方法用于生成的对应的对象,而且重载形式多变,可以根据不同的参数生成对应的数据。

public classJava8TimeDateDemo {public static voidmain(String[] args) {/*** 初始化2018年8月8日的LocalDate对象*/LocalDate localDate= LocalDate.of(2018, 8, 8);

System.out.println("LocalDate: " +localDate);/*** 初始化晚上8点0分0秒的LocalTime对象 -> 如果是晚上的时间,需要加12

* LocalTime.of 方法的重载形式有以下几种:

* LocalTime.of(int hour, int minute) -> 根据小时/分钟生成对象

* LocalTime.of(int hour, int minute, int second)

* LocalTime.of(int hour, int minute, int second, int nanOfSecond)

* 注意:如果秒和纳秒是0的话,那么默认不会封装这些数据,只显示小时和分钟*/LocalTime localTime= LocalTime.of(20, 0);

System.out.println("LocalTime: " +localTime);/*** 初始化2018年8月8日下午8点0分的LocalDateTime对象

* LocalDateTime.of方法重载形式有以下几种:

* LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanOfSecond)

* LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute)*/LocalDateTime localDateTime= LocalDateTime.of(2018,8,8,20,0);

System.out.println("LocalDateTime: " +localDateTime);/*** LodalDateTime的of方法特殊使用:

* LocalDateTime of(LocalDate date, LocalTime time)*/LocalDate date= LocalDate.of(2020, 9, 18);

LocalTime time= LocalTime.of(20, 0);

LocalDateTime dateTime=LocalDateTime.of(date, time);

System.out.println("SpecialLocalDateTime: " +dateTime);

}

}

结果

LocalDate: 2018-08-08LocalTime:20:00LocalDateTime:2018-08-08T20:00SpecialLocalDateTime:2020-09-18T20:00

为LocalDateTime添加时区信息

ZonedDateTime对象里面封装的不仅有时间日期,并且还有偏移量+时区,那么时区如何在java中获取呢?通过提供的一个类ZoneId的getAvailableZoneIds方法可以获取到一个Set集合,集合中封装了600个时区。

获取所有时区

public classJava8TimeDateDemo {public static voidmain(String[] args) {

Set availableZoneIds =ZoneId.getAvailableZoneIds();for(String zoneId: availableZoneIds){

System.out.println(zoneId);

}

}

}

当前系统默认时区

ZoneId zoneId =ZoneId.systemDefault();

System.out.println(zoneId);

可以通过给LocalDateTime添加时区来查看不同时区的时间,添加纽约的时区:

封装时间LocalDateTime并添加时区信息

更改时区信息查看对应的时间

public classJava8TimeDateDemo {public static voidmain(String[] args) {//1.封装LocalDateTime对象,参数自定义 -> 2018年11月11日 8点54分38秒

LocalDateTime localDateTime = LocalDateTime.of(2018, 11, 11, 8, 54, 38);//2.上面只是封装了时间,并没有时区相关的数据,所以要添加时区信息到对象中,使用atZone()方法

ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));

System.out.println("Asia/Shanghai时区当前时间是: " +zonedDateTime);//3.更改时区查看其他时区当前时间,通过withZoneSameInstant()方法即可更改

ZonedDateTime tokyoZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));

System.out.println("同一时刻,Asia/Tokyo时区当前时间是: " +tokyoZonedDateTime);

}

}

结果

Asia/Shanghai时区当前时间是: 2018-11-11T08:54:38+08:00[Asia/Shanghai]

同一时刻,Asia/Tokyo时区当前时间是: 2018-11-11T09:54:38+09:00[Asia/Tokyo]

Month枚举类

Month中包含了标准日历中的12个月份的常量(JANUARY-DECEMBER),也提供了一些方便的方法供我们使用。、

推荐在初始化LocalDate和LocalDateTime对象的时候,使用枚举的方式传入月份参数。

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime localDateTime= LocalDateTime.of(2011, Month.NOVEMBER, 12, 17, 1);

System.out.println(localDateTime);

Month month= Month.of(12);

System.out.println(month);

}

}

根据现有实例创建日期与时间对象

LocalDate、LocalTime、LocalDateTime一旦创建无法修改,不可改变,有利于线程安全。

想要修改某个日期/时间对象的现有实例时,可以使用plus和minus方法。返回的都是新的对象。

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDate localDate= LocalDate.of(2016, 2, 12);

System.out.println("当前时间是: " +localDate);

LocalDate localDate1= localDate.plusDays(4);

System.out.println(localDate1==localDate);

}

}

结果

当前时间是: 2016-02-12

false

plusXxx方法

plus方法

/*** 小占查看自己的保险记录的时候看到还有2年3月8天就到期了,计算到期的时间是什么时候?*/

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime now=LocalDateTime.now();

LocalDateTime endTime= now.plusYears(2).plusMonths(3).plusDays(8);

System.out.println("当前时间是: " + now + ",到期时间是: " +endTime);

}

}

结果

当前时间是: 2020-09-17T11:23:53.862,到期时间是: 2022-12-25T11:23:53.862

我们可以直接使用plus方法

plus(TemporalAmount amount)

TemporalAmount是一个接口,Period实现了这个接口

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime now=LocalDateTime.now();

Period period= Period.of(2, 3, 8);

LocalDateTime endTime1=now.plus(period);

System.out.println("当前时间是: " + now + ",到期时间是: " +endTime1);

}

}

结果一样

plus(long l, TemporaUnit unit) ,在实际开发中,可能还会更精准地去操作日期或者增加一些特殊的时间,如1个世纪,1个半天,10年等,Java8提供了这些日期的表示方式。

TemporaUnit 是一个接口,可以使用实现类 ChronoUnit ,封装了很多时间段

Unit that represents the concept of a century.

Unit that represents the concept of a day.

Unit that represents the concept of a decade.

Unit that represents the concept of an era.

Artificial unit that represents the concept of forever.

Unit that represents the concept of half a day, as used in AM/PM.

Unit that represents the concept of an hour.

Unit that represents the concept of a microsecond.

Unit that represents the concept of a millennium.

Unit that represents the concept of a millisecond.

Unit that represents the concept of a minute.

Unit that represents the concept of a month.

Unit that represents the concept of a nanosecond, the smallest supported unit of time.

Unit that represents the concept of a second.

Unit that represents the concept of a week.

Unit that represents the concept of a year.

/*** 结婚十年被称为锡婚,2020年2月2日11点11分11秒被称为对称日,如果该天结婚,锡婚会发生在什么时候?*/

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime marryTime= LocalDateTime.of(2020, Month.FEBRUARY, 2, 11, 11, 11);

LocalDateTime tinAnniversary= marryTime.plus(1, ChronoUnit.DECADES);

System.out.println("锡婚发生在: " +tinAnniversary);//锡婚后半天需要请客吃饭,半天的时间节点

LocalDateTime treatTime = tinAnniversary.plus(1, ChronoUnit.HALF_DAYS);

System.out.println("请客吃饭的时间: " +treatTime);

}

}

结果

锡婚发生在: 2030-02-02T11:11:11

请客吃饭的时间: 2030-02-02T23:11:11

with方法

不需要对日期进行加减而是直接修改,用with方法

LocalDateTime withNano(inti) 修改纳秒,下同

LocalDateTime withSecond(inti)

LocalDateTime withMinute(inti)

LocalDateTime withHour(inti)

LocalDateTime withDayOfMonth(inti)

LocalDateTime withMonth(inti)

LocalDateTime withYear(int i)

如果有人给你了一个getTime()方法,这个方法的天总是不固定的,而这是一个错误,需要你将天定为每月的1号

此时不能使用plus了,因为不固定,使用with直接修改即可

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime time=getTime();

LocalDateTime resultTime= time.withDayOfMonth(1);

System.out.println("修改前: " +time);

System.out.println("修改后: " +resultTime);

}public staticLocalDateTime getTime(){

Random random= newRandom();int day = random.nextInt(19);if (day == 0){

day= 1;

}return LocalDateTime.of(1999, 12, day, 12, 0);

}

}

结果

修改前: 1999-12-17T12:00修改后:1999-12-01T12:00

with(TemporalField, long newValue)

使用TemporalFiled实现类ChronoField

第一个参数指定了修改的field

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDateTime time=getTime();

LocalDateTime resultTime= time.with(ChronoField.DAY_OF_MONTH, 1); // 天改为1

System.out.println("修改前: " +time);

System.out.println("修改后: " +resultTime);

}public staticLocalDateTime getTime(){

Random random= newRandom();int day = random.nextInt(19);if (day == 0){

day= 1;

}return LocalDateTime.of(1999, 12, day, 12, 0);

}

}

TemporalAdjuster与TemporalQuery

可实现一些复杂操作

with(TemporalAdjuster adjuster)

上面的参数是接口

TemporalAdjusters类

TemporalAdjuster是接口,该名字加了s后是个类

Returns the day-of-week in month adjuster, which returns a new date in the same month with the ordinal day-of-week.

Returns the "first day of month" adjuster, which returns a new date set to the first day of the current month.

Returns the "first day of next month" adjuster, which returns a new date set to the first day of the next month.

Returns the "first day of next year" adjuster, which returns a new date set to the first day of the next year.

Returns the "first day of year" adjuster, which returns a new date set to the first day of the current year.

Returns the first in month adjuster, which returns a new date in the same month with the first matching day-of-week.

Returns the "last day of month" adjuster, which returns a new date set to the last day of the current month.

Returns the "last day of year" adjuster, which returns a new date set to the last day of the current year.

Returns the last in month adjuster, which returns a new date in the same month with the last matching day-of-week.

Returns the next day-of-week adjuster, which adjusts the date to the first occurrence of the specified day-of-week after the date being adjusted.

Returns the next-or-same day-of-week adjuster, which adjusts the date to the first occurrence of the specified day-of-week after the date being adjusted unless it is already on that day in which case the same object is returned.

Obtains a TemporalAdjuster that wraps a date adjuster.

Returns the previous day-of-week adjuster, which adjusts the date to the first occurrence of the specified day-of-week before the date being adjusted.

Returns the previous-or-same day-of-week adjuster, which adjusts the date to the first occurrence of the specified day-of-week before the date being adjusted unless it is already on that day in which case the same object is returned.

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDate now=LocalDate.now();

LocalDate nextMonth=now.with(TemporalAdjusters.firstDayOfNextMonth());

System.out.println("修改前: " +now);

System.out.println("修改后: " +nextMonth);

}

}

DayOfWeek枚举类

一周中星期几的枚举类

enumDayOfWeek {

SUNDAY("Sun"),

MONDAY("Mon"),

TUESDAY("Tue"),

WEDNESDAY("Wed"),

THURSDAY("Thu"),

FRIDAY("Fri"),

SATURDAY("Sat");private finalString abbr;privateDayOfWeek(String abbr) {this.abbr =abbr;

}

String getAbbr() {returnabbr;

}intvalue() {return ordinal() + 1;

}

}

public classJava8TimeDateDemo {public static voidmain(String[] args) {

LocalDate now=LocalDate.now();//将当前时间修改为下一个周日

LocalDate nextMonth =now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));

System.out.println("修改前: " +now);

System.out.println("修改后: " +nextMonth);

}

}

自定义TemporalAdjuster调节器

自定义日期时间的更改逻辑

创建类实现接口TemporalAdjuster

实现adjustInto()方法,传入一个日期的时间对象,完成逻辑后返回日期的时间对象

通过with方法传入自定义调节器对象完成更改

函数式接口

有且仅有一个抽象方法的接口

/*** 假如员工一个中领取工资,发薪日是每个月的15号,如果发薪日是周末,则调整为周五

* 之后会传入一个日期的时间对象,判断日期时间对象是不是15号,如果不是15号改为15号,如果是周六或周日改为周五(上一个)*/

public class PayDayAdjuster implementsTemporalAdjuster {public static voidmain(String[] args) {

LocalDate payDay= LocalDate.of(2019, 12, 15);

LocalDate realPayDay= LocalDate.from(newPayDayAdjuster().adjustInto(payDay));

System.out.println("预计发薪日:" + payDay +" 真实发薪日: " +realPayDay);

}

@OverridepublicTemporal adjustInto(Temporal temporal) {//1.Temporal是日期时间类对象的父接口,实际上可以理解为传入的就是LocalDate或LocalTime对象,需要转换

LocalDate payDay =LocalDate.from(temporal);//2.判断当前封装的实际中的日期是不是当月15号,如果不是,则修改为15号

intday;if (payDay.getDayOfMonth() != 15){

day= 15;

}else{

day=payDay.getDayOfMonth();

}

LocalDate realPayDay=payDay.withDayOfMonth(day);//3.判断realPayDay对象中封装的星期数是不是周六或周日,如果是改为上一个周五

if (realPayDay.getDayOfWeek() == DayOfWeek.SUNDAY || realPayDay.getDayOfWeek() ==DayOfWeek.SATURDAY){

realPayDay=realPayDay.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));

}returnrealPayDay;

}

}

TemporalQuery的应用

LocalDate和LocalTime都有一个方法叫query,可以针对日期进行查询。

R query(Temporal query) 这个方法是一个泛型方法,返回的数据就是传入的泛型类的类型,TemporalQuery是一个泛型接口,里面有一个抽象方法是R queryFrom(TemporalAccessor temporal),TemporalAccessor是Temporal的父接口,实际就是LocalDate、LocalDateTime相关类的顶级父接口,这个qureyFrom方法的实现逻辑就是,传入一个日期/时间对象通过自定义逻辑返回数据。

/*** 获取某一天距离下一个劳动节相隔天数

**/

public class UtilDayQueryImpl implements TemporalQuery{

@OverridepublicLong queryFrom(TemporalAccessor temporal) {//1.TemporalAccessor是LocalDate和LocalDateTime的顶级父接口,相当于LocalDate就是其实现类,将temporal转换为LocalDate进行使用

LocalDate now =LocalDate.from(temporal);//2.封装当年的劳动节实际

LocalDate labDay = LocalDate.of(now.getYear(), Month.MAY, 1);//3.判断当前实际是否已经超过了劳动,超过了则labDay+1年

if(now.isAfter(labDay)){

labDay= labDay.plusYears(1);

}//4.通过ChronoUnit的between方法计算两个时间点的差额

long days =ChronoUnit.DAYS.between(now, labDay);returndays;

}public static voidmain(String[] args) {

LocalDate now=LocalDate.now();

Long days= now.query(newUtilDayQueryImpl());

System.out.println("当前的时间是: " + now + " ,距离下一个劳动节还有" + days + "天。");

}

}

java.util.Date与java.time.LocalDate的转换

可以使用Instant类作为中介,也可以使用java.sql.Date和java.sql.Timestamp类提供的方法进行转换

使用Instant类

Java8给Date类和Calender类提供了toInstant()方法,将它们转为LocalDate对象。

public static voidmain(String[] args) {//初始化Date对象

Date date = newDate();//1.将Date对象转换为Instant对象

Instant instant =date.toInstant();//2.Date类包含日期和时间信息,但没有时区信息,通过Instant的atZone方法添加时区信息

ZonedDateTime zonedDateTime =instant.atZone(ZoneId.systemDefault());//3.将ZonedDateTime通过toLocalDateTime转换

LocalDateTime localDateTime =zonedDateTime.toLocalDateTime();

System.out.println("转换之前Date对象是: " +date);

System.out.println("转换之后Date对象是: " +localDateTime);

}

使用java.sql.Date和java.sql.Timestamp类

TimeStamp是时间戳对象,通过传入一个毫秒值对象进行初始化。

public static voidmain(String[] args) {//初始化java.sql.Date对象

Date date = newDate(System.currentTimeMillis());//java.sql.Date类中自带转换为LocalDate的方法

LocalDate localDate =date.toLocalDate();//初始化java.sql.TimeStamp对象即时间戳对象//datetime

Timestamp timeStamp =newTimestamp(System.currentTimeMillis());

LocalDateTime localDate1=timeStamp.toLocalDateTime();

}

由上可知

可以将java.util.Date先转为java.sql.Date

java.sql.Date的构造可以接收毫秒值,而java.util.Date对象的getTime方法可以获取毫秒值

public static voidmain(String[] args) {

java.util.Date date= newjava.util.Date();//初始化java.sql.Date对象

java.sql.Date date1 = newDate(date.getTime());//java.sql.Date类中自带转换为LocalDate的方法

LocalDate localDate =date1.toLocalDate();

}

Calender转为ZonedDateTime

public static voidmain(String[] args) {//1.初始化Calender对象

Calendar cal =Calendar.getInstance();//2.Calender获取时区对象

TimeZone timeZone =cal.getTimeZone();//3.获取ZoneId

ZoneId zoneId =timeZone.toZoneId();//4.ZoneDateTime有一个方法Instant,可以将一个Instant对象和ZoneId对象封装为一个ZonedDate对象

ZonedDateTime zonedDateTime =ZonedDateTime.ofInstant(cal.toInstant(), zoneId);

System.out.println(zonedDateTime);

}

Calender转为LocalDateTime

Calender可以得到年月日时分秒的信息,这些信息可以作为LocalDateTime构造方法的参数

public static voidmain(String[] args) {//1.初始化Calender对象

Calendar cal =Calendar.getInstance();//2.通过get方法获得Calender对象中的信息

int year =cal.get(Calendar.YEAR);int month =cal.get(Calendar.MONTH);int day =cal.get(Calendar.DAY_OF_MONTH);int hour =cal.get(Calendar.HOUR);int minute =cal.get(Calendar.MINUTE);int second =cal.get(Calendar.SECOND);//3.将以上方法获得的参数作为参数 month从0开始,下面的month要加1

LocalDateTime localDateTime = LocalDateTime.of(year, month+1, day, hour, minute ,second);

System.out.println(localDateTime);

}

日期的解析与格式化

SimpleDateFormat类是线程不安全的,Java8提供了新类DateTimeFormatter。

DateTimeFormatter提供了大量的预定义格式化器,包括常量和模式字母以及本地化样式。

parse/format

通过时间日期对象的parse/format方法可以直接进行转换

public static voidmain(String[] args) {//初始化

LocalDateTime now =LocalDateTime.now();//now()可以直接调用format方法进行格式化

String s1 =now.format(DateTimeFormatter.ISO_DATE_TIME);

String s2=now.format(DateTimeFormatter.ISO_DATE);

System.out.println(s1);

System.out.println(s2);//解析字符串。

LocalDateTime time =LocalDateTime.parse(s1);

System.out.println(time);

}

结果

2020-09-17T14:45:32.553

2020-09-17

2020-09-17T14:45:32.553

ofLocalizedDate方法

public static voidmain(String[] args) {//初始化

LocalDateTime now =LocalDateTime.now();//now()可以直接调用format方法进行格式化

String s1 =now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));

String s2=now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));

String s3=now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));

String s4=now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));

System.out.println(s1);

System.out.println(s2);

System.out.println(s3);

System.out.println(s4);

}

结果

2020年9月17日 星期四

2020年9月17日2020-9-17

20-9-17

不同时区显示方式不一样,在其他时区可能不显示中文,根据系统默认时区

自定义格式化

可以通过DateTimeFormatter类提供的ofPattern方式创建自定义格式化器,格式化的写法与SimpleDateFormat相同。

public static voidmain(String[] args) {//初始化

LocalDateTime now =LocalDateTime.now();

String dt= now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm-ss"));

System.out.println(dt);

}

结果

2020-09-17 14:54-13

总结

小项目-万年历

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值