Java中对日期的处理
这个案例中最主要掌握
知识点1:怎么获取系统当前时间
知识点2:String------->Date
知识点3:Date--------->String
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest01 {
public static void main(String[] args) throws Exception {
// 获取系统当前时间(精确到毫秒的系统当前时间)
// 直接调用无参数构造方法就行。
Date nowTime = new Date();
// java.util.Date类的toString()方法已经被重写了。
// 输出的应该不是一个对象的内存地址,应该是一个日期字符串。
//System.out.println(nowTime); //Thu Mar 05 10:51:06 CST 2020
// 日期可以格式化吗?
// 将日期类型Date,按照指定的格式进行转换:Date --转换成具有一定格式的日期字符串-->String
// SimpleDateFormat是java.text包下的。专门负责日期格式化的。
/*
yyyy 年(年是4位)
MM 月(月是2位)
dd 日
HH 时
mm 分
ss 秒
SSS 毫秒(毫秒3位,最高999。1000毫秒代表1秒)
注意:在日期格式中,除了y M d H m s S这些字符不能随便写之外,剩下的符号格式自己随意组织。
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
//SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
String nowTimeStr = sdf.format(nowTime);
System.out.println(nowTimeStr);
// 假设现在有一个日期字符串String,怎么转换成Date类型?
// String --> Date
String time = "2008-08-08 08:08:08 888";
//SimpleDateFormat sdf2 = new SimpleDateFormat("格式不能随便写,要和日期字符串格式相同");
// 注意:字符串的日期格式和SimpleDateFormat对象指定的日期格式要一致。不然会出现异常:java.text.ParseException
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
Date dateTime = sdf2.parse(time);
System.out.println(dateTime); //Fri Aug 08 08:08:08 CST 2008
}
}
-
获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数。
1秒 = 1000毫秒 -
简单总结一下System类的相关属性和方法:
System.out 【out是System类的静态变量。】 System.out.println() 【println()方法不是System类的,是PrintStream类的方法。】 System.gc() 建议启动垃圾回收器 System.currentTimeMillis() 获取自1970年1月1日到系统当前时间的总毫秒数。 System.exit(0) 退出JVM。
public class DateTest02 {
public static void main(String[] args) {
// 获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数。
long nowTimeMillis = System.currentTimeMillis();
System.out.println(nowTimeMillis); //1583377912981
// 统计一个方法耗时
// 在调用目标方法之前记录一个毫秒数
long begin = System.currentTimeMillis();
print();
// 在执行完目标方法之后记录一个毫秒数
long end = System.currentTimeMillis();
System.out.println("耗费时长"+(end - begin)+"毫秒");
}
// 需求:统计一个方法执行所耗费的时长
public static void print(){
for(int i = 0; i < 1000000000; i++){
System.out.println("i = " + i);
}
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest03 {
public static void main(String[] args) {
// 这个时间是什么时间?
// 1970-01-01 00:00:00 001
Date time = new Date(1); // 注意:参数是一个毫秒
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String strTime = sdf.format(time);
// 北京是东8区。差8个小时。
System.out.println(strTime); // 1970-01-01 08:00:00 001
// 获取昨天的此时的时间。
Date time2 = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
String strTime2 = sdf.format(time2);
System.out.println(strTime2); //2020-03-04 11:44:14 829
// 获取“去年的今天”的时间
// 自己玩。
}
}
总结:
日期类
2.1、获取系统当前时间
Date d = new Date();
2.2、日期格式化:Date --> String
yyyy-MM-dd HH:mm:ss SSS
SimpleDateFormat sdf = new SimpleDate("yyyy-MM-dd HH:mm:ss SSS");
String s = sdf.format(new Date());
2.3、String --> Date
SimpleDateFormat sdf = new SimpleDate("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2008-08-08 08:08:08");
2.4、获取毫秒数
long begin = System.currentTimeMillis();
Date d = new Date(begin - 1000 * 60 * 60 * 24);
数字类
-
关于数字的格式化【了解】
-
数字格式化有哪些?
# 代表任意数字 , 代表千分位 . 代表小数点 0 代表不够时补0 ###,###.## 表示:加入千分位,保留2个小数。
import java.text.DecimalFormat;
public class DecimalFormatTest01 {
public static void main(String[] args) {
// java.text.DecimalFormat专门负责数字格式化的。
//DecimalFormat df = new DecimalFormat("数字格式");
DecimalFormat df = new DecimalFormat("###,###.##");
//String s = df.format(1234.56);
String s = df.format(1234.561232);
System.out.println(s); // "1,234.56"
DecimalFormat df2 = new DecimalFormat("###,###.0000"); //保留4个小数位,不够补上0
String s2 = df2.format(1234.56);
System.out.println(s2); // "1,234.5600"
}
}
-
BigDecimal 属于大数据,精度极高。不属于基本大数据类型,属于java对象(引用数据类型)这是SUN提供的一个类。专门用在财务软件当中。
-
【注意】:财务软件中double 是不够的,之前有一个同学去面试,经理就问了这样一个问题:
你处理过财务数据吗?用的哪一种类型?
千万别说 double,说java.math.BigDecimal
import java.math.BigDecimal;
public class BigDecimalTest01 {
public static void main(String[] args) {
// 这个100不是普通的100,是精度极高的100
BigDecimal v1 = new BigDecimal(100);
// 精度极高的200
BigDecimal v2 = new BigDecimal(200);
// 求和
// v1 + v2; // 这样不行,v1和v2都是引用,不能直接使用+求和。
BigDecimal v3 = v1.add(v2); // 调用方法求和。
System.out.println(v3); //300
BigDecimal v4 = v2.divide(v1);
System.out.println(v4); // 2
}
}
【总结】数字类
3.1、DecimalFormat数字格式化
###,###.## 表示加入千分位,保留两个小数。
###,###.0000 表示加入千分位,保留4个小数,不够补0
3.2、BigDecimal
财务软件中通常使用BigDecimal
随机数
import java.util.Random;
public class RandomTest01 {
public static void main(String[] args) {
// 创建随机数对象
Random random = new Random();
// 随机产生一个int类型取值范围内的数字。
int num1 = random.nextInt();
System.out.println(num1);
// 产生[0~100]之间的随机数。不能产生101。
// nextInt翻译为:下一个int类型的数据是101,表示只能取到100.
int num2 = random.nextInt(101); //不包括101
System.out.println(num2);
}
}
- 编写程序,生成5个不重复的随机数[0-100]。重复的话重新生成。最终生成的5个随机数放到数组中,要求数组中这5个随机数不重复。
import java.util.Arrays;
import java.util.Random;
public class RandomTest02 {
public static void main(String[] args) {
// 创建Random对象
Random random = new Random();
// 准备一个长度为5的一维数组。
int[] arr = new int[5]; // 默认值都是0
for(int i = 0; i < arr.length; i++){
arr[i] = -1;
}
// 循环,生成随机数
int index = 0;
while(index < arr.length){
// 生成随机数
//int num = random.nextInt(101);
//int num = random.nextInt(6); // 只能生成[0-5]的随机数!
int num = random.nextInt(4); // 只能生成[0-3]的随机数!永远都有重复的,永远都凑不够5个。
System.out.println("生成的随机数:" + num);
// 判断arr数组中有没有这个num
// 如果没有这个num,就放进去。
if(!contains(arr, num)){
arr[index++] = num;
}
}
// 遍历以上的数组
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
/**
* 单独编写一个方法,这个方法专门用来判断数组中是否包含某个元素
* @param arr 数组
* @param key 元素
* @return true表示包含,false表示不包含。
*/
public static boolean contains(int[] arr, int key){
/*
// 这个方案bug。(排序出问题了。)
// 对数组进行升序
//Arrays.sort(arr);
// 进行二分法查找
// 二分法查找的结果 >= 0说明,这个元素找到了,找到了表示存在!
//return Arrays.binarySearch(arr, key) >= 0;
*/
for(int i = 0; i < arr.length; i++){
if(arr[i] == key){
// 条件成立了表示包含,返回true
return true;
}
}
// 这个就表示不包含!
return false;
}
}
【总结】随机数
4.1、怎么产生int类型随机数。
Random r = new Random();
int i = r.nextInt();
4.2、怎么产生某个范围之内的int类型随机数。
Random r = new Random();
int i = r.nextInt(101); // 产生[0-100]的随机数。
枚举类
这个案例中没有使用java中的枚举,分析以下程序,在设计方面有什么缺陷?
以下代码可以编译,也可以运行,这些都没有问题。
就是设计上你觉得有什么缺陷??
public class EnumTest01 {
public static void main(String[] args) {
//System.out.println(10 / 0); //java.lang.ArithmeticException: / by zero
/*
int retValue = divide(10, 2);
System.out.println(retValue == 1 ? "计算成功" : "计算失败"); // 1
int retValue2 = divide(10, 0);
System.out.println(retValue2 == 0 ? "计算失败" : "计算成功"); // 0
*/
boolean success = divide(10, 0);
System.out.println(success ? "计算成功" : "计算失败");
}
/**
* 需求(这是设计者说的!):以下程序,计算两个int类型数据的商,计算成功返回1,计算失败返回0
* @param a int类型的数据
* @param b int类型的数据
* @return 返回1表示成功,返回0表示失败!
*/
/*
public static int divide(int a, int b){
try {
int c = a / b;
// 程序执行到此处表示以上代码没有发生异常。表示执行成功!
return 1;
} catch (Exception e){
// 程序执行到此处表示以上程序出现了异常!
// 表示执行失败!
return 0;
}
}
*/
// 设计缺陷?在这个方法的返回值类型上。返回一个int不恰当。
// 既然最后的结果只是成功和失败,最好使用布尔类型。因为布尔类型true和false正好可以表示两种不同的状态。
/*
public static int divide(int a, int b){
try {
int c = a / b;
// 返回10已经偏离了需求,实际上已经出错了,但是编译器没有检查出来。
// 我们一直想追求的是:所有的错误尽可能让编译器找出来,所有的错误越早发现越好!
return 10;
} catch (Exception e){
return 0;
}
}
*/
// 这种设计不错。
public static boolean divide(int a, int b){
try {
int c = a / b;
return true;
} catch (Exception e){
return false;
}
}
【思考】:
以上的这个方法设计没毛病,挺好,返回true和false表示两种情况,但是在以后的开发中,有可能遇到一个方法的执行结果可能包括三种情况,四种情况、五种情况不等,但是每一个都是可以数清楚的,一枚一枚都是可以列举出来的。这个布尔类型就无法满足需求了。此时需要使用java语言中的枚举类型。
采用枚举的方式改造程序
public class EnumTest02 {
public static void main(String[] args) {
Result r = divide(10, 2);
System.out.println(r == Result.SUCCESS ? "计算成功" : "计算失败");
}
/**
* 计算两个int类型数据的商。
* @param a int数据
* @param b int数据
* @return Result.SUCCESS表示成功,Result.FAIL表示失败!
*/
public static Result divide(int a, int b){
try {
int c = a / b;
return Result.SUCCESS;
} catch (Exception e){
return Result.FAIL;
}
}
}
// 枚举:一枚一枚可以列举出来的,才建议使用枚举类型。
// 枚举编译之后也是生成class文件。
// 枚举也是一种引用数据类型。
// 枚举中的每一个值可以看做是常量。
enum Result{
// SUCCESS 是枚举Result类型中的一个值
// FAIL 是枚举Result类型中的一个值
// 枚举中的每一个值,可以看做是“常量”
SUCCESS, FAIL
}
【总结】:
-
枚举是一种引用数据类型
-
枚举编译之后也是class文件
-
枚举类型怎么定义,语法是?
enum 枚举类型名{ 枚举值1,枚举值2 }
-
结果只有两种情况,建议使用布尔类型,结果超过两种并且还是可以一枚一枚列举出来的,建议使用枚举类型。
例如:颜色、四季、星期等都可以使用枚举类型
/**
* 四季枚举类型
*/
public enum Season {
/*
春夏秋冬
*/
SPRING, SUMMER, AUTUMN, WINTER
}
/**
* 颜色枚举类型
*/
public enum Color {
/**
* 颜色值
*/
RED,BLUE,YELLOW,BLACK
}
/*
class MyClass {
public static final String RED = "red";
public static final String BLUE = "blue";
public static final String YELLOW = "yellow";
public static final String BLACK = "black";
public static void main(String[] args) {
String c = MyClass.RED;
System.out.println(c);
// RED
System.out.println(Color.RED);
}
}
*/
public class SwitchTest {
public static void main(String[] args) {
// switch语句支持枚举类型
// switch也支持String、int
// 低版本的JDK,只支持int
// 高版本的JDK,支持int、String、枚举。
// byte short char也可以,因为存在自动类型转换。
switch (Season.SPRING) {
// 必须省略Season.
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}
下一篇:异常