开发喵星球

日期时间常用类和抽象类

日期时间常用类

日期时间类

Date类

Date类位于java.util包中,用于表示特定的时间点。它包含了一些基本的日期和时间操作方法。

Date对象记录的时间是用毫秒值来表示的。Java语言规定,1970年1月1日0时0分0秒认为是时间的起点,此时记作0,那么1000(1秒=1000毫秒)就表示1970年1月1日0时0分1秒,依次内推。

image-20230824205028513

以下是Date类的一些常用方法:

方法 描述
Date() 创建一个表示当前时间的Date对象。
Date(long millis) 使用给定的毫秒数创建一个Date对象。
getTime() 返回自1970年1月1日以来,以毫秒为单位的日期时间值。
getYear() 返回从1900年开始计算的年份(Deprecated,推荐使用Calendar或新的日期API)。
getMonth() 返回0到11之间的月份(Deprecated,推荐使用Calendar或新的日期API)。
getDate() 返回一个月中的某一天(从1开始)(Deprecated,推荐使用Calendar或新的日期API)。
getHours() 返回小时数(24小时制)。
getMinutes() 返回分钟数。
getSeconds() 返回秒数。
setTime(long time) 设置Date对象的时间为给定的毫秒数。
setYear(int year) 设置年份(Deprecated,推荐使用Calendar或新的日期API)。
setMonth(int month) 设置月份(从0到11)(Deprecated,推荐使用Calendar或新的日期API)。
setDate(int date) 设置一个月中的某一天(从1开始)(Deprecated,推荐使用Calendar或新的日期API)。
setHours(int hours) 设置小时数(24小时制)。
setMinutes(int minutes) 设置分钟数。
setSeconds(int seconds) 设置秒数。
toString() 将Date对象转换为字符串表示。
equals(Object obj) 判断当前对象是否与另一个对象相等。
compareTo(Date anotherDate) 将当前Date对象与另一个Date对象进行比较。

Date类中的很多方法已经被标记为过时(Deprecated),不推荐使用,原因是它们存在一些问题,如不是线程安全、年份从1900年开始计算等。建议使用新的日期和时间API,如java.time包中的类,来进行日期和时间的处理。

格式化Date对象

要格式化一个Date对象,可以使用SimpleDateFormat类来指定所需的日期和时间格式。SimpleDateFormat类是Java中用于日期和时间格式化的类,它位于java.text包中。它允许将Date对象格式化为指定的日期和时间字符串,或者将日期和时间字符串解析为Date对象。

我们把Date对象转换为指定格式的日期字符串这个操作,叫做日期格式化

反过来把指定格式的日期符串转换为Date对象的操作,叫做日期解析。

以下是SimpleDateFormat类的一些常用方法:

方法 描述
SimpleDateFormat(String pattern) 使用给定的模式字符串创建一个SimpleDateFormat对象。
format(Date date) 将给定的Date对象格式化为字符串,使用指定的模式。
parse(String source) 将给定的字符串解析为Date对象,使用指定的模式。
applyPattern(String pattern) 设置格式化模式,用于指定日期和时间的格式。
toPattern() 返回当前的格式化模式。

格式化模式字符串由一系列字符组成,用于定义日期和时间的显示格式。以下是一些常用的格式化模式字符:

public static void main(String[] args) {
    Date date = new Date(99, 1, 1);
    // 创建SimpleDateFormat对象,并指定格式化模式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 格式化Date对象为字符串
    String formattedDate = sdf.format(date);
    // Formatted Date: 1999-02-01 00:00:00
    System.out.println("Formatted Date: " + formattedDate);
    // 解析字符串为Date对象
    String dateString = "1949-10-01 15:30:45";
    try {
        Date parsedDate = sdf.parse(dateString);
        // Parsed Date: Sat Oct 01 15:30:45 CST 1949
        System.out.println("Parsed Date: " + parsedDate);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

请注意,SimpleDateFormat类不是线程安全的,如果在多线程环境下使用,建议每个线程都创建一个独立的SimpleDateFormat实例,或者使用线程安全的替代方案,如DateTimeFormatter类(JDK 8及以上版本)。

此外,还可以使用SimpleDateFormat类的其他方法来自定义日期和时间的格式化行为,如设置时区、设置解析的宽容性等。具体的用法可以参考API官方文档或其他相关资源。

Calendar类

Calendar类是Java中用于处理日期和时间的类,位于java.util包中。它提供了一种比Date类更灵活和功能更强大的日期和时间操作方式。

比如下面的案例,用Date类就不太好做,而用Calendar就特别方便。因为Calendar类提供了方法可以直接对日历中的年、月、日、时、分、秒等进行运算。

image-20230824205415250

以下是Calendar类的一些常用方法:

方法 描述
get(int field) 返回给定字段的值,例如Calendar.YEAR、Calendar.MONTH等。
getActualMaximum(int field) 返回给定字段的最大值。
getActualMinimum(int field) 返回给定字段的最小值。
set(int field, int value) 将给定字段设置为指定的值。
set(int year, int month, int day) 设置年、月、日。
setTime(Date date) 使用给定的Date对象设置Calendar的时间
add(int field, int amount) 在给定字段上增加或减少指定的量。
roll(int field, int amount) 在给定字段上增加或减少指定的量,但不影响较大的字段。
getTime() 返回一个表示Calendar时间的Date对象。
getTimeInMillis() 返回自1970年1月1日以来的毫秒数。
toString() 返回一个表示Calendar时间的字符串。
getFirstDayOfWeek() 返回一周的第一天,默认是Sunday。
setFirstDayOfWeek(int value) 设置一周的第一天。
getWeekYear() 返回指定日期所在周的年份。
get(Calendar.ZONE_OFFSET) 返回与GMT的时差。
public static void main(String[] args) {
   // 获取当前日期和时间的Calendar对象
   Calendar calendar = Calendar.getInstance();
   // 设置日期为指定的年份、月份和日
   calendar.set(1970, 1, 1);
   // 获取年份
   int year = calendar.get(Calendar.YEAR);
   System.out.println(year); // 1970
   // 获取月份(需要注意,月份从0开始计数)
   int month = calendar.get(Calendar.MONTH) + 1;
   System.out.println(month); // 2
   // 获取当前是月份中的第几天
   int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
   System.out.println(dayOfMonth); // 1
   // 在月份上增加1
   calendar.add(Calendar.MONTH, 1);
   // 输出修改后的日期
   System.out.println(calendar.getTime()); 
   // 将Calendar转换为Date对象
   Date date = calendar.getTime();
   System.out.println(date); 
}

Calendar对象和Date对象的转换

// 将Calendar对象转换为Date对象
public static Date calendarToDate(Calendar calendar) {
    return calendar.getTime();
}

// 将Date对象转换为Calendar对象
public static Calendar dateToCalendar(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar;
}

LocalDate类

LocalDate 是 Java 中的一个日期类,它提供了处理日期的方法和功能。LocalDate 类位于 java.time 包中,从 JDK 8 开始引入。

以下是LocalDate类的一些常用方法:

方法 描述
now() 获取当前日期。
of(year, month, dayOfMonth) 根据年、月、日创建LocalDate对象。
parse(dateString) 将字符串解析为LocalDate对象。
getYear() 获取年份。
getMonth() 获取月份。
getDayOfMonth() 获取月份中的日期。
getDayOfWeek() 获取星期几。
isLeapYear() 判断是否为闰年。
plusDays(days) 增加指定的天数。
plusWeeks(weeks) 增加指定的周数。
plusMonths(months) 增加指定的月数。
plusYears(years) 增加指定的年数。
minusDays(days) 减去指定的天数。
minusWeeks(weeks) 减去指定的周数。
minusMonths(months) 减去指定的月数。
minusYears(years) 减去指定的年数。
isBefore(otherDate) 判断是否在另一个日期之前。
isAfter(otherDate) 判断是否在另一个日期之后。
isEqual(otherDate) 判断是否与另一个日期相等。
format(formatter) 将日期格式化为指定的字符串。
public static void main(String[] args) {
    // 创建LocalDate对象
    LocalDate today = LocalDate.now();
    LocalDate specificDate = LocalDate.of(1970, 1, 1);
    System.out.println("指定日期: " + specificDate);
    // 解析字符串为LocalDate对象
    LocalDate parsedDate = LocalDate.parse("1949-10-01");
    System.out.println("解析后的日期: " + parsedDate);
    // 获取日期信息
    int year = specificDate.getYear();
    int month = specificDate.getMonthValue();
    int day = specificDate.getDayOfMonth();
    System.out.println("年份: " + year);
    System.out.println("月份: " + month);
    System.out.println("日期: " + day);
    // 增加/减少日期
    LocalDate futureDate = specificDate.plusDays(7);
    LocalDate pastDate = specificDate.minusMonths(1);
    System.out.println("增加日期: " + futureDate);
    System.out.println("减少日期: " + pastDate);
    // 判断日期关系
    boolean isBefore = specificDate.isBefore(parsedDate);
    boolean isAfter = specificDate.isAfter(parsedDate);
    boolean isEqual = specificDate.isEqual(parsedDate);
    System.out.println("是否在指定日期之前: " + isBefore);
    System.out.println("是否在指定日期之后: " + isAfter);
    System.out.println("是否与指定日期相等: " + isEqual);
    // 格式化日期
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String formattedDate = specificDate.format(formatter);
    System.out.println("格式化后的日期: " + formattedDate);
}

LocalTime类

LocalTime类是JDK 8引入的日期时间类,位于java.time包中。它用于表示时间,提供了处理时间相关操作的方法。

以下是LocalTime类的一些常用方法:

方法 描述
now() 获取当前时间。
of(hour, minute) 根据小时和分钟创建LocalTime对象。
of(hour, minute, second) 根据小时、分钟和秒创建LocalTime对象。
of(hour, minute, second, nanoOfSecond) 根据小时、分钟、秒和纳秒创建LocalTime对象。
parse(timeString) 将字符串解析为LocalTime对象。
getHour() 获取小时数。
getMinute() 获取分钟数。
getSecond() 获取秒数。
getNano() 获取纳秒数。
plusHours(hours) 增加指定的小时数。
plusMinutes(minutes) 增加指定的分钟数。
plusSeconds(seconds) 增加指定的秒数。
plusNanos(nanos) 增加指定的纳秒数。
minusHours(hours) 减去指定的小时数。
minusMinutes(minutes) 减去指定的分钟数。
minusSeconds(seconds) 减去指定的秒数。
minusNanos(nanos) 减去指定的纳秒数。
isBefore(otherTime) 判断是否在另一个时间之前。
isAfter(otherTime) 判断是否在另一个时间之后。
equals(otherTime) 判断是否与另一个时间相等。
format(formatter) 将时间格式化为指定的字符串。
public static void main(String[] args) {
    // 创建LocalTime对象
    LocalTime now = LocalTime.now();
    System.out.println("当前时间: " + now);
    LocalTime specificTime = LocalTime.of(14, 30);
    System.out.println("指定时间: " + specificTime);
    // 解析字符串为LocalTime对象
    LocalTime parsedTime = LocalTime.parse("08:45:30");
    System.out.println("解析后的时间: " + parsedTime);
    // 获取时间信息
    int hour = now.getHour();
    int minute = now.getMinute();
    int second = now.getSecond();
    System.out.println("小时数: " + hour);
    System.out.println("分钟数: " + minute);
    System.out.println("秒数: " + second);
    // 增加/减少时间
    LocalTime futureTime = now.plusHours(3);
    LocalTime pastTime = now.minusMinutes(15);
    System.out.println("未来时间: " + futureTime);
    System.out.println("过去时间: " + pastTime);
    // 判断时间关系
    boolean isBefore = now.isBefore(specificTime);
    boolean isAfter = now.isAfter(specificTime);
    boolean isEqual = now.equals(specificTime);
    System.out.println("当前时间是否在指定时间之前: " + isBefore);
    System.out.println("当前时间是否在指定时间之后: " + isAfter);
    System.out.println("当前时间是否与指定时间相等: " + isEqual);
    // 格式化时间
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    String formattedTime = now.format(formatter);
    System.out.println("格式化后的时间: " + formattedTime);
}

LocalDateTime类

LocalDateTime类是JDK 8引入的日期时间类,位于java.time包中。它结合了LocalDate和LocalTime的功能,用于表示日期和时间的组合。

以下是LocalDateTime类的一些常用方法:

方法 描述
now() 获取当前日期和时间。
of(year, month, dayOfMonth, hour, minute) 根据年、月、日、小时和分钟创建LocalDateTime对象。
of(year, month, dayOfMonth, hour, minute, second) 根据年、月、日、小时、分钟和秒创建LocalDateTime对象。
of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond) 根据年、月、日、小时、分钟、秒和纳秒创建LocalDateTime对象。
parse(dateTimeString) 将字符串解析为LocalDateTime对象。
toLocalDate() 获取日期部分,返回LocalDate对象。
toLocalTime() 获取时间部分,返回LocalTime对象。
getYear() 获取年份。
getMonth() 获取月份。
getDayOfMonth() 获取月份中的日期。
getHour() 获取小时数。
getMinute() 获取分钟数。
getSecond() 获取秒数。
getNano() 获取纳秒数。
plusYears(years) 增加指定的年数。
plusMonths(months) 增加指定的月数。
plusDays(days) 增加指定的天数。
plusHours(hours) 增加指定的小时数。
plusMinutes(minutes) 增加指定的分钟数。
plusSeconds(seconds) 增加指定的秒数。
plusNanos(nanos) 增加指定的纳秒数。
minusYears(years) 减去指定的年数。
minusMonths(months) 减去指定的月数。
minusDays(days) 减去指定的天数。
minusHours(hours) 减去指定的小时数。
minusMinutes(minutes) 减去指定的分钟数。
minusSeconds(seconds) 减去指定的秒数。
minusNanos(nanos) 减去指定的纳秒数。
isBefore(otherDateTime) 判断是否在另一个日期时间之前。
isAfter(otherDateTime) 判断是否在另一个日期时间之后。
isEqual(otherDateTime) 判断是否与另一个日期时间相等。
format(formatter) 将日期时间格式化为指定的字符串。
public static void main(String[] args) {
    // 创建LocalDateTime对象
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime specificDateTime = LocalDateTime.of(1949, 10, 1, 14, 0);
    System.out.println("指定日期时间: " + specificDateTime);
    // 解析字符串为LocalDateTime对象
    LocalDateTime parsedDateTime = LocalDateTime.parse("1970-01-01T09:00:00");
    System.out.println("解析后的日期时间: " + parsedDateTime);
    // 获取日期和时间信息
    LocalDate date = specificDateTime.toLocalDate();
    int year = specificDateTime.getYear();
    int minute = specificDateTime.getMinute();
    System.out.println("日期部分: " + date);
    System.out.println("年份: " + year);
    System.out.println("分钟数: " + minute);
    // 增加/减少日期和时间
    LocalDateTime futureDateTime = specificDateTime.plusDays(7).plusHours(3);
    System.out.println("增加日期时间: " + futureDateTime);
    // 判断日期时间关系
    boolean isBefore = parsedDateTime.isBefore(specificDateTime);
    System.out.println("当前日期时间是否在指定日期时间之前: " + isBefore);
    // 格式化日期时间
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String formattedDateTime = parsedDateTime.format(formatter);
    System.out.println("格式化后的日期时间: " + formattedDateTime);
}

相互转换

LocalDate转LocalDateTime

atStartOfDay(): 将Time初始化为 00:00

atTime(int hours, int minutes[, int seconds[, int nanoOfSecond]]) :将时间初始化为指定的值

atTime(LocalTime time) 以指定的时间

LocalDateTimeof(LocalDate date, LocalTime time)

LocalTime localTime = LocalTime.now();
LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime = localDate.atTime(localTime);
System.out.println(localDateTime);

LocalDateTime dateTime = LocalDateTime.of(localDate, localTime);
System.out.println(dateTime);

LocalTime转LocalDateTime

LocalTimeatDate(LocalDate date)以指定的日期

LocalDateTimeof(LocalDate date, LocalTime time)

LocalTime localTime = LocalTime.now();
LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime = localTime.atDate(localDate);
System.out.println(localDateTime);

LocalDateTime dateTime = LocalDateTime.of(localDate, localTime);
System.out.println(dateTime);

LocalDateTime转 LocalDate或 LocalTime

LocalDate toLocalDate():将LocalDateTime转换成LocalDate
LocalTime toLocalTime():将LocalDateTime转换成LocalTime

和Date对象的转换

要在Date对象和LocalDate对象之间进行相互转换,可以使用java.util.Datejava.time.LocalDate类的方法。

toInstant():将Date对象转换为Instant对象。Instant是Java 8引入的一个表示时间戳的类,它是以UTC(协调世界时)为基准的。

ZoneId.systemDefault( ):创建了一个ZoneId对象,表示当前系统的默认时区。

atZone(zoneId):通过atZone()方法,我们将Instant对象与指定的时区关联,创建一个ZonedDateTime对象。atZone()方法接受一个ZoneId对象作为参数,将Instant对象转换为具有时区信息的日期时间对象。

toLocalDate( ):从ZonedDateTime对象中提取出LocalDate对象,即只保留日期部分,去除时间和时区信息。

atStartOfDay(zoneId):这部分代码将LocalDate对象与指定的时区关联,创建一个LocalDateTime对象。atStartOfDay()方法将时间部分设置为当天的起始时间,即午夜零点。

toInstant():LocalDateTime对象没有直接转换为Date对象的方法,所以我们需要使用toInstant()方法将其转换为Instant对象。Instant是以UTC(协调世界时)为基准的时间戳。

Date.from():通过Date.from()方法,我们可以将以UTC时间为基准的Instant对象转换为Date对象。这样就得到了表示与LocalDate对象对应日期的Date对象。

 public static void main(String[] args) {
     // 将Date对象转换为LocalDate对象
     Date date = new Date(70, 0, 1);
     LocalDate localDate = dateToLocalDate(date);
     // Date对象转换为LocalDate对象: 1970-02-01
     System.out.println("Date对象转换为LocalDate对象: " + localDate);

     // 将LocalDate对象转换为Date对象
     LocalDate localDate1 = LocalDate.of(1970, 1, 1);
     Date convertedDate = localDateToDate(localDate1);
     // LocalDate对象转换为Date对象: Thu Jan 01 00:00:00 CST 1970
     System.out.println("LocalDate对象转换为Date对象: " + convertedDate);
 }

// 将Date对象转换为LocalDate对象
public static LocalDate dateToLocalDate(Date date) {
    ZoneId zoneId = ZoneId.systemDefault();
    return date.toInstant().atZone(zoneId).toLocalDate();
}

// 将LocalDate对象转换为Date对象
public static Date localDateToDate(LocalDate localDate) {
    ZoneId zoneId = ZoneId.systemDefault();
    return Date.from(localDate.atStartOfDay(zoneId).toInstant());
}

抽象类

抽象类和抽象方法

基本概念

抽象方法和普通方法

当一个类的方法被abstract关键字修饰的时候,该方法称为抽象方法。抽象方法必须定义在抽象类中。

当一个方法被定义为抽象方法后,意味着该方法不会有具体的实现,而是在抽象类的子类中通过方法重写进行实现。定义抽象方法的语法格式如下:

[访问修饰符] abstract 返回值类型 方法名([参数列表]);

// 普通方法
[访问修饰符] 返回值类型 方法名(参数列表) {方法体}

abstract关键字表示该方法被定义为抽象方法。

普通方法和抽象方法相比,主要有下列两点区别:

  1. 抽象方法需要用修饰符 abstract修饰,普通方法不允许。
  2. 普通方法有方法体,抽象方法没有方法体。
抽象类和普通类

在Java中,当一个类被abstract关键字修饰的时候这个类称为抽象类。定义抽象类的语法格式如下:

[访问修饰符] abstract class 类名{}

// 普通类
[访问修饰符] class 类名{}

abstract关键字表示该方法被定义为抽象类。

普通类与抽象类相比,主要有下列两点区别:

  1. 抽象类需要用修饰符abstract修饰,普通类不允许。
  2. 普通类可以被实例化,抽象类不可以被实例化。
定义一个抽象类

当一个类被定义为抽象类时,它可以包含各种类型的成员,包括属性、方法等,其中方法又分为普通方法和抽象方法,下面是抽象类结构的示例:

public abstract class 类名{
    修饰符 数据类型 变量名;
    修饰符 abstract 返回值类型 方法名称(参数列表);
    修饰符 返回值类型 方法名称(参数列表){
    }
}

抽象类中可以声明成员变量,可以定义普通方法,还可以有构造方法等。

总结

  1. 抽象方法只能出现在抽象类中。
  2. 抽象类中除了抽象方法还可以有其他方法。
  3. 抽象类不能被直接实例化,但是有构造方法。
  4. 抽象方法不能使用private修饰,否则由于封装导致子类无法重写抽象方法。抽象方法不能被static关键字修饰。
  5. 抽象方法没有方法体,当一个方法被修饰为抽象方法时,意味该方法不会有具体的实现,而是在抽象类的子类中通过方法重写进行实现。
  6. abstract不能和final关键字一起使用, final修饰的类不能被继承,final修饰的方法不能被重写
  7. 如果一个类继承了一个抽象类,必须重写所有的抽象方法,不然这个类得声明为抽象类。
  8. 定义某种规范时,可以使用抽象类。
案例
图形计算器

你正在开发一个图形计算器应用程序。你希望为不同类型的图形(如圆形、矩形、三角形等)创建一个通用的计算器。使用抽象类来实现这个想法。

  1. 创建一个抽象类 Shape,其中包含一个抽象方法 calculateArea() 和一个普通方法 displayShape().
  2. 派生出三个子类:CircleRectangleTriangle,分别实现 calculateArea() 方法以计算它们的面积,并重写 displayShape() 方法以显示相应的形状名字。
  3. 在一个主程序中,创建不同类型的图形对象,调用它们的方法展示形状和计算面积。
银行账户继承体系

你正在为一个银行开发账户管理系统。系统需要处理不同类型的账户,如储蓄账户、支票账户等。

  1. 创建一个抽象类 BankAccount,包含实例变量 accountNumberbalance,以及抽象方法 withdraw()deposit().
  2. 派生出两个子类:SavingsAccountCheckingAccountCheckingAccount中新增属性overdraftLimit透支额度,分别实现 withdraw()deposit() 方法,考虑不同类型账户的操作规则。普通账户只能取自己的余额,CheckingAccount允许在一定范围内透支。
  3. 在主程序中,创建几个储蓄账户和支票账户对象,进行存款和取款操作。
动物继承层次

设计一个关于动物的继承层次,包括一些基本的动物类型。

  1. 创建一个抽象类 Animal,包含实例变量 name 和抽象方法 makeSound().
  2. 派生出多个子类,如 DogCatCow,每个子类实现 makeSound() 方法以发出相应的动物叫声。
  3. 创建一个 Zoo 类,其中有一个数组,用于存储不同类型的动物对象。展示它们的叫声。
   
分类:Java/OOP 作者:开发喵 发表于:2023-08-29 17:40:13 阅读量:115
<<   >>


powered by kaifamiao