当前位置: 首页 > news >正文

一篇文章带你学完Java所有的时间与日期类

目录

一、传统时间与日期类

1.Date类

构造方法

获取日期和时间信息的方法

 设置日期和时间信息的方法

2.Calendar类

主要特点和功能

 常用方法

1. 获取当前日历对象

2. 获取日历中的某个信息

3. 获取日期对象

4. 获取时间毫秒值

5. 修改日历的某个信息

6. 为某个信息增加或者减少值

3.SimpleDateFormat类

主要用途

构造函数

模式字符串

将日期格式化成日期与时间字符串

将时间毫秒值格式化成字符串

解析日期

示例

要点

注意事项

二、新旧替换

一、新增的时间与日期类及其替代的旧类

二、具体变化

三、总结

三、JDK8后新时间与日期类 

LocalDate

LocalTime

LocalDateTime

ZoneId

ZonedDateTime

Instant

Instant 的主要特点

Instant 的常见方法

代码示例

DateTimeFormatter

主要特点

常见用法

代码示例

Period

示例代码

Duration

示例代码


一、传统时间与日期类

    在JDK8之前,Java语言自带的日期时间类主要有java.util.Datejava.util.Calendarjava.text.SimpleDateFormat。这些类存在一系列问题,使得在编写代码时需要做出许多不必要的努力:

  1. java.util.Date:除了表示当前日期时间以外,其余所有方法都被视为已过时(deprecated),且不支持时区信息,也不是线程安全的。
  2. java.util.Calendar:虽然是一个比较全面的日期时间处理类,并且可以进行一些精度更高的计算,但由于设计不够合理,使得代码变得冗长和难以维护,同时也不是线程安全的。
  3. java.text.SimpleDateFormat:虽然可以将日期时间格式化为字符串,但它同样也不是线程安全的。

  如今仍有部分公司在使用这些时间与日期类部分内容,所以我们也有必要去了解一下。有的完全过时的内容这里就不在讲解。

1.Date类

    Java中的Date类是一个用于表示特定瞬间(精确到毫秒)的日期和时间的类。尽管从Java 9开始,Date类被标记为过时(deprecated),并且推荐使用新的日期时间API(如java.time包下的类),但了解Date类的常见方法仍然是有价值的。以下是Date类的一些常见方法:

构造方法

1.Date():创建一个表示当前日期和时间的Date对象(使用系统默认的时区和毫秒计时器)。

import java.util.Date;  public class DateExample {  public static void main(String[] args) {  // 创建一个表示当前日期和时间的Date对象  Date now = new Date();  // 打印当前日期和时间(注意:输出格式依赖于JVM的实现)  System.out.println("当前日期和时间(默认格式):" + now.toString());  }  
}

2.Date(long date):根据指定的毫秒数(自1970年1月1日00:00:00 GMT以来的毫秒数)创建一个Date对象。

import java.util.Date;  public class DateExample {  public static void main(String[] args) {  // 定义一个表示特定时间点的毫秒数(例如,2023年1月1日00:00:00 GMT的毫秒数)  // 注意:这里只是一个示例值,实际值需要根据具体日期计算  long specificTimeMillis = 1672483200000L; // 假设这是正确的毫秒数  // 根据指定的毫秒数创建一个Date对象  Date specificDate = new Date(specificTimeMillis);  // 打印特定日期和时间(注意:输出格式依赖于JVM的实现)  System.out.println("特定日期和时间(默认格式):" + specificDate.toString());  }  
}
获取日期和时间信息的方法

getTime():返回自1970年1月1日00:00:00 GMT以来的毫秒数(即时间戳)。

import java.util.Date;  public class DateExample {  public static void main(String[] args) {  // 创建一个表示当前日期和时间的Date对象  Date now = new Date();  // 获取当前日期和时间的毫秒数(时间戳)  long timestamp = now.getTime();  // 打印时间戳  System.out.println("当前时间戳(毫秒):" + timestamp);  }  
}
 设置日期和时间信息的方法

setTime(long time):设置Date对象表示的日期和时间,使用自1970年1月1日00:00:00 GMT以来的毫秒数。

import java.util.Date;  public class DateExample {  public static void main(String[] args) {  // 创建一个Date对象  Date date = new Date();  // 打印原始日期和时间(默认格式)  System.out.println("原始日期和时间:" + date.toString());  // 定义一个新的时间戳(例如,某个特定时间点的毫秒数)  long newTimeMillis = 1672483200000L; // 假设这是另一个日期的毫秒数  // 设置Date对象表示的新日期和时间  date.setTime(newTimeMillis);  // 打印修改后的日期和时间(默认格式)  System.out.println("修改后的日期和时间:" + date.toString());  }  
}

2.Calendar类

Java中的Calendar类是一个抽象类,用于封装日历信息,如年、月、日、时、分、秒等,并提供操作这些字段的方法。

由于Calendar是抽象类,因此你不能直接实例化它。相反,你需要使用Calendar类的一个子类实例,通常是通过调用Calendar类的getInstance()静态方法获得的,该方法会返回一个Calendar对象,该对象是根据默认时区和语言环境初始化的。

主要特点和功能
  1. 抽象性Calendar是一个抽象类,不能直接实例化。
  2. 时区和语言环境Calendar提供了操作日历字段的方法,这些字段值基于特定的时区和语言环境。
  3. 字段值Calendar类使用整数来表示日历字段,如YEARMONTHDAY_OF_MONTHHOUR_OF_DAY等。注意,MONTH字段是从0开始的(0表示1月,11表示12月)。
  4. 字段操作:提供了获取(get)、设置(set)、增加(add)和滚动(roll)日历字段值的方法。
  5. 不可变性(某种程度上):虽然Calendar对象本身是可变的(即,你可以修改其字段值),但一旦你通过getTime()方法获得了一个Date对象,那么该Date对象是不可变的。
 常用方法
1. 获取当前日历对象

Calendar类是一个抽象类,不能直接实例化。通常,我们使用Calendar.getInstance()方法来获取一个当前日期和时间的Calendar实例,该实例使用了默认的时区和语言环境。

import java.util.Calendar;  public class CalendarDemo {  public static void main(String[] args) {  // 获取当前日历对象  Calendar calendar = Calendar.getInstance();  System.out.println("当前日历对象:" + calendar.toString()); // 注意:toString()输出可能不直观  }  
}
2. 获取日历中的某个信息

你可以使用get(int field)方法来获取Calendar对象中的某个字段的值。字段常量(如YEARMONTHDAY_OF_MONTH等)定义在Calendar类中。

import java.util.Calendar;  public class CalendarDemo {  public static void main(String[] args) {  Calendar calendar = Calendar.getInstance();  // 获取当前年份  int year = calendar.get(Calendar.YEAR);  System.out.println("当前年份:" + year);  // 获取当前月份(注意:月份是从0开始的)  int month = calendar.get(Calendar.MONTH) + 1;  System.out.println("当前月份:" + month);  // 获取当前日期  int day = calendar.get(Calendar.DAY_OF_MONTH);  System.out.println("当前日期:" + day);  }  
}
3. 获取日期对象

你可以使用getTime()方法从Calendar对象中获取一个Date对象,该对象表示Calendar的时间值。

import java.util.Calendar;  
import java.util.Date;  public class CalendarDemo {  public static void main(String[] args) {  Calendar calendar = Calendar.getInstance();  // 获取Date对象  Date date = calendar.getTime();  System.out.println("当前日期和时间:" + date.toString());  }  
}
4. 获取时间毫秒值

Calendar类提供了getTimeInMillis()方法来获取当前时间相对于“纪元”(即1970年1月1日00:00:00.000 GMT)的毫秒数。

import java.util.Calendar;  public class CalendarDemo {  public static void main(String[] args) {  Calendar calendar = Calendar.getInstance();  // 获取时间毫秒值  long timeInMillis = calendar.getTimeInMillis();  System.out.println("当前时间毫秒值:" + timeInMillis);  }  
}
5. 修改日历的某个信息

你可以使用set(int field, int value)方法来修改Calendar对象中的某个字段的值。

import java.util.Calendar;  public class CalendarDemo {  public static void main(String[] args) {  Calendar calendar = Calendar.getInstance();  // 修改年份  calendar.set(Calendar.YEAR, 2024);  // 验证修改  System.out.println("修改后的年份:" + calendar.get(Calendar.YEAR));  }  
}
6. 为某个信息增加或者减少值

你可以使用add(int field, int amount)方法来给Calendar对象中的某个字段增加或减少指定的值。

import java.util.Calendar;  public class CalendarDemo {  public static void main(String[] args) {  Calendar calendar = Calendar.getInstance();  // 给当前日期增加10天  calendar.add(Calendar.DAY_OF_MONTH, 10);  // 验证增加  System.out.println("10天后的日期:" + calendar.getTime().toString());  // 给当前年份减少1年  calendar.add(Calendar.YEAR, -1);  // 验证减少  System.out.println("减少1年后的年份:" + calendar.get(Calendar.YEAR));  }  
}

3.SimpleDateFormat类

SimpleDateFormat 类是 Java 中用于格式化和解析日期的一个非常强大的类。它允许你进行用户自定义的日期-时间格式。这个类继承自 DateFormat 抽象类,并实现了 Serializable 接口,这意呀着它可以被序列化以便在网络中传输或存储到文件系统中。

主要用途
  1. 格式化日期:将 Date 对象转换成符合特定模式的字符串。
  2. 解析日期:将符合特定模式的字符串转换成 Date 对象。
构造函数

SimpleDateFormat 类提供了多个构造函数,但最常用的一个接受一个模式字符串作为参数,这个字符串定义了日期的格式。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
模式字符串

模式字符串由字母和数字组成,每个字母代表日期或时间的一部分。以下是一些常用的模式字母:

  • y:年
  • M:月
  • d:日
  • H:小时(0-23)
  • m:分钟
  • s:秒
  • S:毫秒

例如,"yyyy-MM-dd HH:mm:ss" 是一个常见的日期时间模式,它表示格式为“年-月-日 时:分:秒”的字符串。

将日期格式化成日期与时间字符串

当你有一个 Date 对象,并希望将其格式化为包含日期和时间的字符串时,你可以这样做:

import java.text.SimpleDateFormat;  
import java.util.Date;  public class SimpleDateFormatExample {  public static void main(String[] args) {  // 创建一个Date对象,这里以当前日期时间为例  Date date = new Date();  // 创建一个SimpleDateFormat实例,并指定日期时间格式为"yyyy-MM-dd HH:mm:ss"  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  // 使用format方法将Date对象格式化为字符串  String formattedDateTime = sdf.format(date);  // 输出格式化后的日期时间字符串  System.out.println(formattedDateTime); // 输出类似:2023-04-01 15:30:00  }  
}
将时间毫秒值格式化成字符串

时间毫秒值是自1970年1月1日00:00:00 UTC(协调世界时间)以来的毫秒数。要将这个时间毫秒值格式化为字符串,你首先需要将其转换为 Date 对象,然后使用 SimpleDateFormat 进行格式化。但实际上,SimpleDateFormat 的 format 方法也接受一个 long 类型的参数(即时间毫秒值),不过更常见的做法是先转换为 Date 对象,因为这样可以更清晰地表达你的意图。

不过,为了直接展示如何使用毫秒值,这里给出一个简化的例子:

import java.text.SimpleDateFormat;  public class SimpleDateFormatMillisExample {  public static void main(String[] args) {  // 获取当前时间的毫秒值  long millis = System.currentTimeMillis();  // 创建一个SimpleDateFormat实例,并指定日期时间格式为"yyyy-MM-dd HH:mm:ss"  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  // 直接使用format方法和毫秒值来格式化时间(虽然不常见,但技术上可行)  // 注意:这里实际上是在内部将long类型的毫秒值转换为了Date对象,然后进行了格式化  String formattedDateTime = sdf.format(new Date(millis));  // 输出格式化后的日期时间字符串  System.out.println(formattedDateTime); // 输出类似:2023-04-01 15:30:00  // 或者,更直接地(如果你确定只需要毫秒值),但这样不会进行格式化  // System.out.println(millis); // 这将输出一个长整型数字,不是格式化的日期时间字符串  }  
}

在这个例子中,我们首先获取了当前时间的毫秒值,然后创建了一个 SimpleDateFormat 实例来指定我们想要的日期时间格式。尽管 format 方法直接接受一个 long 类型的参数在技术上不是直接可行的(因为 format 方法的重载版本接受的是 Object 类型,但实际上是期望一个 Date 或其子类的实例),但上面的代码通过 new Date(millis) 将毫秒值转换为了 Date 对象,然后进行了格式化。这是处理时间毫秒值时更常见和推荐的做法。

解析日期

解析日期是指将符合特定格式的字符串转换成 Date 对象的过程。在 SimpleDateFormat 中,你可以通过定义日期时间的模式(pattern)来指定这个字符串的格式。

示例

假设你有一个日期字符串 "2023-04-01",并且你知道这个字符串是以 "yyyy-MM-dd" 格式表示的(即年-月-日)。你可以使用 SimpleDateFormat 来解析这个字符串到 Date 对象。

import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  public class SimpleDateFormatExample {  public static void main(String[] args) {  // 定义日期字符串和日期格式  String dateString = "2023-04-01";  String dateFormat = "yyyy-MM-dd";  // 创建 SimpleDateFormat 实例  SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);  try {  // 解析字符串到 Date 对象  Date date = sdf.parse(dateString);  // 输出 Date 对象(注意:直接输出 Date 对象可能不是很直观,因为 Date.toString() 使用的是默认格式)  System.out.println(date); // 输出类似于 Sat Apr 01 00:00:00 GMT 2023  // 如果需要按照特定格式输出,可以再次使用 SimpleDateFormat  System.out.println(sdf.format(date)); // 输出 2023-04-01  } catch (ParseException e) {  e.printStackTrace();  // 处理解析异常  }  }  
}
要点
  • 当使用 parse 方法时,如果字符串与指定的模式不匹配,会抛出 ParseException。因此,你需要处理这个异常。
  • 默认的 SimpleDateFormat 是不线程安全的。如果你在多线程环境中使用同一个 SimpleDateFormat 实例,可能会遇到并发问题。解决方法是为每个线程创建单独的 SimpleDateFormat 实例,或者使用 ThreadLocal 来管理它们。
  • 当你使用 SimpleDateFormat 格式化或解析日期时,请确保你的模式和字符串或 Date 对象相匹配,以避免意外错误。
  • Java 8 引入了新的日期和时间 API(位于 java.time 包中),这些API提供了更强大、灵活且线程安全的日期和时间处理能力。如果你正在使用 Java 8 或更高版本,建议考虑使用这些新的API。
注意事项
  • 线程安全性SimpleDateFormat 不是线程安全的。如果在多线程环境中使用相同的 SimpleDateFormat 实例,可能会出现并发问题。一个常见的解决方案是为每个线程创建单独的 SimpleDateFormat 实例,或者使用 ThreadLocal 来管理实例。
  • 时区:默认情况下,SimpleDateFormat 使用默认的时区和语言环境来格式化或解析日期。如果需要,可以使用 setTimeZone(TimeZone zone) 方法来设置时区。
  • 模式字符大小写:在模式中,某些字符的大小写是有意义的。例如,MM 表示月份,而 mm 表示分钟。

二、新旧替换

JDK8新增的时间与日期类相比以前的类,带来了显著的变化和改进。以下是对这些新增类及其替代的旧类以及具体变化的详细说明:

一、新增的时间与日期类及其替代的旧类

新增类替代的旧类(或功能)
LocalDatejava.util.Calendar(部分功能)
LocalTimejava.util.Calendar(部分功能)
LocalDateTimejava.util.Calendarjava.util.Date(部分功能)
Instant

java.util.Date(时间戳功能)

ZonedDateTimejava.util.Calendar(带时区功能)
DateTimeFormatterjava.text.SimpleDateFormat
Durationjava.util.concurrent.TimeUnit(部分功能)
Period

无直接替代,提供新的时间间隔表示

二、具体变化

  1. LocalDate
    • 替代了java.util.Calendar中处理日期的部分功能,但更加简洁和直观。
    • 表示一个具体的日期,如“2024-07-27”,不包含时间信息。
    • 提供了丰富的API来处理日期,如加减天数、月份、年份,以及比较日期等。
  2. LocalTime
    • 替代了java.util.Calendar中处理时间的部分功能。
    • 表示一个具体的时间,如“10:29:18”,不包含日期信息。
    • 提供了API来处理时间,如加减小时、分钟、秒等。
  3. LocalDateTime
    • 整合了LocalDateLocalTime的功能,表示一个具体的日期和时间,如“2024-07-27T10:29:18”。
    • 提供了更全面的API来处理日期和时间,包括加减日期、时间,以及比较等。
  4. Instant
    • 替代了java.util.Date中时间戳的功能,但更加精确(到纳秒)。
    • 表示一个具体的时间点,即时间线上的一个瞬时。
    • 提供了与ZonedDateTime等类进行转换的API,便于时区处理。
  5. ZonedDateTime
    • 替代了java.util.Calendar中处理带时区日期时间的部分功能,但更加完善。
    • 表示一个具体的带时区的日期时间,如“2024-07-27T10:29:18+08:00[Asia/Shanghai]”。
    • 提供了时区转换、加减日期时间等API。
  6. DateTimeFormatter
    • 替代了java.text.SimpleDateFormat,提供了更加强大和灵活的日期时间格式化功能。
    • 可以通过模式字符串来自定义日期时间的格式,也可以解析符合特定格式的字符串为日期时间对象。
  7. DurationPeriod
    • 这两个类提供了新的时间间隔表示方式。
    • Duration用于表示时间间隔,如“PT1H30M”(1小时30分钟)。
    • Period用于表示日期间隔,如“P2Y6M”(2年6个月)。

三、总结

JDK8新增的时间与日期类相比以前的类,在以下几个方面有了显著的变化:

  • 线程安全性:新类都是不可变的,因此它们是线程安全的。
  • 不可变性:一旦创建,新类的对象就不能被修改,这有助于防止意外的修改和并发问题。
  • 更清晰的API设计:新类提供了更直观、更易于理解的API,使得日期时间的处理更加简单和方便。
  • 更好的国际化支持:新类支持时区处理,并且遵循ISO 8601标准,使得日期时间的表示更加国际化。
  • 更精确的时间表示Instant类提供了纳秒级的时间精度,比旧的java.util.Date类更加精确。

三、JDK8后新时间与日期类 

LocalDate

LocalDate代表没有时区的日期,如年月日。

常见方法:

  • now(): 获取当前日期。
  • of(int year, int month, int dayOfMonth): 从年月日创建一个LocalDate
  • getYear(): 获取年份。
  • getMonth(): 获取月份,返回一个Month枚举。
  • getDayOfMonth(): 获取月份中的日。
  • plusDays(long days): 添加天数。
  • minusDays(long days): 减去天数。 
import java.time.LocalDate;  public class LocalDateExample {  public static void main(String[] args) {  // 获取当前日期  LocalDate today = LocalDate.now();  System.out.println("Today's date: " + today);  // 通过年、月、日创建LocalDate实例  LocalDate specificDate = LocalDate.of(2023, 4, 1);  System.out.println("Specific date: " + specificDate);  // 加上天数  LocalDate nextWeek = specificDate.plusDays(7);  System.out.println("Next week: " + nextWeek);  // 减去月份  LocalDate previousMonth = specificDate.minusMonths(1);  System.out.println("Previous month: " + previousMonth);  // 获取年份、月份和月份中的天数  int year = specificDate.getYear();  int month = specificDate.getMonthValue();  int dayOfMonth = specificDate.getDayOfMonth();  System.out.println("Year: " + year + ", Month: " + month + ", Day: " + dayOfMonth);  // 格式化日期  String formattedDate = specificDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));  System.out.println("Formatted date: " + formattedDate);  }  
}

LocalTime

LocalTime代表没有日期的时间,如时分秒。

常见方法:

  • now(): 获取当前时间。
  • of(int hour, int minute, int second): 从时分秒创建一个LocalTime
  • getHour(): 获取小时。
  • getMinute(): 获取分钟。
  • getSecond(): 获取秒。
import java.time.LocalTime;  public class LocalTimeExample {  public static void main(String[] args) {  // 获取当前时间  LocalTime now = LocalTime.now();  System.out.println("Current time: " + now);  // 通过小时、分钟、秒创建LocalTime实例  LocalTime specificTime = LocalTime.of(14, 30, 45);  System.out.println("Specific time: " + specificTime);  // 加上小时  LocalTime later = specificTime.plusHours(2);  System.out.println("Later time: " + later);  // 减去分钟  LocalTime earlier = later.minusMinutes(30);  System.out.println("Earlier time: " + earlier);  // 获取小时、分钟和秒  int hour = specificTime.getHour();  int minute = specificTime.getMinute();  int second = specificTime.getSecond();  System.out.println("Hour: " + hour + ", Minute: " + minute + ", Second: " + second);  // 格式化时间  String formattedTime = specificTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));  System.out.println("Formatted time: " + formattedTime);  }  
}

LocalDateTime

LocalDateTime代表没有时区的日期和时间。

常见方法:

  • now(): 获取当前的日期和时间。
  • of(LocalDate date, LocalTime time): 从LocalDateLocalTime创建一个LocalDateTime
  • getYear()getMonth()getDayOfMonth()getHour()getMinute()getSecond(): 获取日期和时间的各个部分。
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.LocalTime;public class LocalDateTimeExample {public static void main(String[] args) {LocalDateTime now = LocalDateTime.now();System.out.println("Current date and time: " + now);LocalDateTime specificDateTime = LocalDateTime.of(LocalDate.of(2024, 7, 27), LocalTime.of(13, 45, 20));System.out.println("Specific date and time: " + specificDateTime);int year = now.getYear();System.out.println("Year: " + year);int hour = now.getHour();System.out.println("Hour: " + hour);}
}

ZoneId

ZoneId是时区的标识符,它可以是诸如"Europe/Paris"的地理区域标识符,或者是像"UTC"这样的固定偏移量。

常见方法:

  • systemDefault(): 获取系统默认时区。
  • of(String zoneId): 从字符串创建一个ZoneId
  • getRules(): 获取与此ZoneId关联的时区规则。
  • normalized(): 返回规范化形式的ZoneId

示例代码:

import java.time.ZoneId;public class ZoneIdExample {public static void main(String[] args) {// 获取系统默认时区ZoneId systemDefaultZoneId = ZoneId.systemDefault();System.out.println("System Default ZoneId: " + systemDefaultZoneId);// 从字符串创建一个ZoneIdZoneId zoneId = ZoneId.of("Europe/Paris");System.out.println("ZoneId of Europe/Paris: " + zoneId);// 获取时区规则ZoneId zoneRules = zoneId.getRules();System.out.println("Zone Rules: " + zoneRules);// 返回规范化形式的ZoneIdZoneId normalizedZoneId = zoneId.normalized();System.out.println("Normalized ZoneId: " + normalizedZoneId);}
}

ZonedDateTime

ZonedDateTime是一个包含日期和时间的类,同时关联了时区信息。

常见方法:

  • now(): 获取当前日期和时间,并附加系统默认时区。
  • now(ZoneId zone): 获取指定时区的当前日期和时间。
  • of(LocalDateTime dateTime, ZoneId zone): 从LocalDateTimeZoneId创建一个ZonedDateTime
  • withZoneSameLocal(ZoneId zone): 更改时区,保留本地日期和时间。
  • withZoneSameInstant(ZoneId zone): 更改时区,保留瞬间。
  • plusDays(long days): 添加天数。
  • minusDays(long days): 减去天数。
  • toLocalDate(): 获取本地日期。
  • toLocalTime(): 获取本地时间。
  • getZone(): 获取时区。
import java.time.ZonedDateTime;
import java.time.LocalDateTime;
import java.time.ZoneId;public class ZonedDateTimeExample {public static void main(String[] args) {// 获取系统默认时区的当前日期和时间ZonedDateTime now = ZonedDateTime.now();System.out.println("Current date and time with system default timezone: " + now);// 获取指定时区的当前日期和时间ZonedDateTime nowInParis = ZonedDateTime.now(ZoneId.of("Europe/Paris"));System.out.println("Current date and time in Europe/Paris: " + nowInParis);// 从LocalDateTime和ZoneId创建一个ZonedDateTimeLocalDateTime localDateTime = LocalDateTime.of(2024, 7, 27, 13, 45, 20);ZonedDateTime specificDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());System.out.println("Specific date and time: " + specificDateTime);// 更改时区,保留本地日期和时间ZonedDateTime zonedDateTimeWithLocalTime = specificDateTime.withZoneSameLocal(ZoneId.of("Europe/Paris"));System.out.println("Specific date and time in Europe/Paris (same local time): " + zonedDateTimeWithLocalTime);// 更改时区,保留瞬间ZonedDateTime zonedDateTimeWithSameInstant = specificDateTime.withZoneSameInstant(ZoneId.of("Europe/Paris"));System.out.println("Specific date and time in Europe/Paris (same instant): " + zonedDateTimeWithSameInstant);// 添加天数ZonedDateTime plusDays = specificDateTime.plusDays(1);System.out.println("Specific date and time plus one day: " + plusDays);// 减去天数ZonedDateTime minusDays = specificDateTime.minusDays(1);System.out.println("Specific date and time minus one day: " + minusDays);// 获取本地日期LocalDate localDate = specificDateTime.toLocalDate();System.out.println("Local date: " + localDate);// 获取本地时间LocalTime localTime = specificDateTime.toLocalTime();System.out.println("Local time: " + localTime);// 获取时区ZoneId zone = specificDateTime.getZone();System.out.println("ZoneId: " + zone);}
}

Instant

Instant 类在 Java 中表示一个时间线上的一个瞬时点,它是以 Unix 时间戳(即自1970年1月1日UTC以来的秒数)为基础的,但精度更高,可以达到纳秒级别。Instant 是不带时区的,它表示的是全球统一的时间线上的一个点。

Instant 的主要特点
  • 精确到纳秒。
  • 不带时区信息,仅表示时间线上的一个点。
  • 可以用来表示时间戳,非常适合用于系统间的时间交互,因为它消除了时区带来的复杂性。
Instant 的常见方法
  • now(): 获取当前时间的 Instant 实例。
  • plus(TemporalQuery<? extends Temporal> query, long amount): 在 Instant 上加上指定的时间量。
  • minus(TemporalQuery<? extends Temporal> query, long amount): 从 Instant 上减去指定的时间量。
  • atZone(ZoneId zone): 将 Instant 转换为特定时区的 ZonedDateTime
  • toEpochMilli(): 将 Instant 转换为自1970年1月1日UTC以来的毫秒数(与 Unix 时间戳相似,但精度稍低)。
  • toEpochSecond(): 将 Instant 转换为自1970年1月1日UTC以来的秒数。
代码示例
import java.time.Instant;  
import java.time.ZoneId;  
import java.time.ZonedDateTime;  public class InstantExample {  public static void main(String[] args) {  // 获取当前时间的 Instant 实例  Instant now = Instant.now();  System.out.println("Current instant: " + now);  // 将 Instant 转换为自1970年1月1日UTC以来的毫秒数  long epochMilli = now.toEpochMilli();  System.out.println("Epoch milli: " + epochMilli);  // 将 Instant 转换为自1970年1月1日UTC以来的秒数  long epochSecond = now.toEpochSecond();  System.out.println("Epoch second: " + epochSecond);  // 加上10秒  Instant tenSecondsLater = now.plusSeconds(10);  System.out.println("Ten seconds later: " + tenSecondsLater);  // 减去5分钟  Instant fiveMinutesEarlier = now.minusMinutes(5);  System.out.println("Five minutes earlier: " + fiveMinutesEarlier);  // 将 Instant 转换为特定时区的 ZonedDateTime  ZonedDateTime zdt = now.atZone(ZoneId.of("Asia/Shanghai"));  System.out.println("Shanghai time: " + zdt);  }  
}

DateTimeFormatter

主要特点
  • 自定义格式:可以定义几乎任何所需的日期时间格式。
  • 解析:将文本(通常是字符串)解析为日期时间对象。
  • 格式化:将日期时间对象格式化为文本(字符串)。
  • 本地化:支持使用不同的语言环境和地区设置来格式化日期时间。
常见用法
  1. 预定义格式DateTimeFormatter 提供了一些预定义的格式,如 ISO_LOCAL_DATEISO_LOCAL_TIMEISO_LOCAL_DATE_TIME 等。

  2. 自定义格式:使用 DateTimeFormatter.ofPattern(String pattern) 方法可以根据指定的模式字符串创建自定义格式化程序。

  3. 解析和格式化:使用 parse(CharSequence text) 方法将文本解析为日期时间对象,使用 format(TemporalQuery<?> query) 方法将日期时间对象格式化为文本。

代码示例
import java.time.LocalDateTime;  
import java.time.format.DateTimeFormatter;  public class DateTimeFormatterExample {  public static void main(String[] args) {  // 定义自定义的日期时间格式  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");  // 使用 LocalDateTime 和 formatter 格式化日期时间  LocalDateTime now = LocalDateTime.now();  String formattedDateTime = now.format(formatter);  System.out.println("Formatted DateTime: " + formattedDateTime);  // 解析字符串为 LocalDateTime  String dateTimeStr = "2023-10-01 15:30:45";  LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeStr, formatter);  System.out.println("Parsed DateTime: " + parsedDateTime);  // 使用预定义的 ISO 格式  DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;  String isoDateTimeStr = now.format(isoFormatter);  System.out.println("ISO Formatted DateTime: " + isoDateTimeStr);  // 解析 ISO 格式的字符串  LocalDateTime parsedIsoDateTime = LocalDateTime.parse(isoDateTimeStr, isoFormatter);  System.out.println("Parsed ISO DateTime: " + parsedIsoDateTime);  }  
}

在这个例子中,我们首先创建了一个自定义的 DateTimeFormatter 实例,用于将 LocalDateTime 对象格式化为 "yyyy-MM-dd HH:mm:ss" 格式的字符串,并展示了如何将这个格式的字符串解析回 LocalDateTime 对象。接着,我们使用了一个预定义的 ISO 格式的 DateTimeFormatter 来演示如何以 ISO 标准格式进行日期时间的格式化和解析。

DateTimeFormatter 是处理日期时间文本表示的强大工具,它支持灵活的格式定义和本地化,相比于SimpleDateFormat,它的线程更安全。

Period

Period 类用于表示基于日历的日期(年、月、日)之间的间隔。它主要用于处理那些与时间无关,仅与日期相关的间隔,比如两个生日之间的年数差异。Period 的字段包括年(years)、月(months)和日(days)。

示例代码
import java.time.LocalDate;  
import java.time.Period;  public class PeriodExample {  public static void main(String[] args) {  LocalDate startDate = LocalDate.of(2020, 1, 15);  LocalDate endDate = LocalDate.of(2023, 4, 20);  // 计算两个日期之间的Period  Period period = Period.between(startDate, endDate);  // 输出结果  System.out.println("Years: " + period.getYears());  System.out.println("Months: " + period.getMonths());  System.out.println("Days: " + period.getDays());  // 也可以通过toTotalMonths()获取总月份数  long totalMonths = period.toTotalMonths();  System.out.println("Total Months: " + totalMonths);  }  
}

Duration

Duration 类用于表示基于时间的持续时间,精确到纳秒。它主要用于处理那些与时间相关的间隔,比如两个时间点之间的时长。Duration 的内部实现是基于秒和纳秒的,但它提供了方便的方法来以天、小时、分钟、秒等为单位进行操作。

示例代码
import java.time.Duration;  
import java.time.Instant;  public class DurationExample {  public static void main(String[] args) {  Instant startTime = Instant.now();  // 模拟一些操作...  try {  Thread.sleep(5000); // 休眠5秒  } catch (InterruptedException e) {  e.printStackTrace();  }  Instant endTime = Instant.now();  // 计算两个时间点之间的Duration  Duration duration = Duration.between(startTime, endTime);  // 输出结果  System.out.println("Seconds: " + duration.getSeconds());  // 获取剩余的纳秒部分  long nano = duration.getNano();  System.out.println("Nano seconds: " + nano);  // 也可以以其他单位输出  System.out.println("Duration in millis: " + duration.toMillis());  // 转换为以天为单位的近似值(注意:这只是一个近似值,因为天的小数部分被忽略了)  long days = duration.toDays();  System.out.println("Approximate days: " + days);  }  
}

相关文章:

一篇文章带你学完Java所有的时间与日期类

目录 一、传统时间与日期类 1.Date类 构造方法 获取日期和时间信息的方法 设置日期和时间信息的方法 2.Calendar类 主要特点和功能 常用方法 1. 获取当前日历对象 2. 获取日历中的某个信息 3. 获取日期对象 4. 获取时间毫秒值 5. 修改日历的某个信息 6. 为某个信息增…...

利用GPT4o Captcha工具和AI技术全面识别验证码

利用GPT4o Captcha工具和AI技术全面识别验证码 &#x1f9e0;&#x1f680; 摘要 GPT4o Captcha工具是一款命令行工具&#xff0c;通过Python和Selenium测试各种类型的验证码&#xff0c;包括拼图、文本、复杂文本和reCAPTCHA&#xff0c;并使用OpenAI GPT-4帮助解决验证码问…...

大学生算法高等数学学习平台设计方案 (第一版)

目录 目标用户群体的精准定位 初阶探索者 进阶学习者 资深研究者 功能需求的深度拓展 个性化学习路径定制 概念图谱构建 公式推导展示 交互式问题解决系统 新功能和创新点的引入 虚拟教室环境 数学建模工具集成 算法可视化平台 学术论文资源库 技术实现的前瞻性…...

机器学习算法与Python实战 | 两行代码即可应用 40 个机器学习模型--lazypredict 库!

本文来源公众号“机器学习算法与Python实战”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;两行代码即可应用 40 个机器学习模型 今天和大家一起学习使用 lazypredict 库&#xff0c;我们可以用一行代码在我们的数据集上实现许多…...

使用WebSocket协议调用群发方法将消息返回客户端页面

目录 一.C/S架构&#xff1a; 二.Http协议与WebSocket协议的区别&#xff1a; 1.Http协议与WebSocket协议的区别&#xff1a; 2.WebSocket协议的使用场景&#xff1a; 三.项目实际操作&#xff1a; 1.导入依赖&#xff1a; 2.通过WebSocket实现页面与服务端保持长连接&a…...

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十七章 Linux中断实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...

每日一题~961div2A+B+C(阅读题,思维,数学log)

A 题意&#xff1a;给你 n*n 的表格和k 个筹码。每个格子上至多放一个 问至少占据多少对角线。 显然&#xff0c;要先 格数的多的格子去放。 n n-1 n-2 …1 只有n 的是一个&#xff08;主对角线&#xff09;&#xff0c;其他的是两个。 #include <bits/stdc.h> using na…...

Fireflyrk3288 ubuntu18.04添加Qt开发环境、安装mysql-server

1、创建一台同版本的ubuntu18.04的虚拟机 2、下载rk3288_ubuntu_18.04_armhf_ext4_v2.04_20201125-1538_DESKTOP.img 3、创建空img镜像容器 dd if/dev/zero ofubuntu_rootfs.img bs1M count102404、将该容器格式化成ext4文件系统 mkfs.ext4 ubuntu_rootfs.img5、将该镜像文件…...

简化mybatis @Select IN条件的编写

最近从JPA切换到Mybatis&#xff0c;使用无XML配置&#xff0c;Select注解直接写到interface上&#xff0c;发现IN条件的编写相当麻烦。 一般得写成这样&#xff1a; Select({"<script>","SELECT *", "FROM blog","WHERE id IN&quo…...

Windows图形界面(GUI)-MFC-C/C++ - Control

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Control 资源编辑器 添加控件 设置控件属性 添加控件变量 添加消息处理 处理控件事件 控件焦点顺序 Control 资源编辑器 资源编辑器&#xff1a;用于可视化地编辑对话框和控件。…...

SQL Server数据库安全:策略制定与实践指南

SQL Server数据库安全&#xff1a;策略制定与实践指南 在当今数字化时代&#xff0c;数据安全是每个组织的核心关注点。SQL Server作为广泛使用的关系型数据库管理系统&#xff0c;提供了一套强大的安全特性来保护存储的数据。制定有效的数据库安全策略是确保数据完整性、可用…...

Spring Boot入门指南:留言板

一.留言板 1.输⼊留⾔信息,点击提交.后端把数据存储起来. 2.⻚⾯展⽰输⼊的表⽩墙的信息 规范&#xff1a; 1.写一个类MessageInfo对象&#xff0c;添加构造方法 虽然有快捷键&#xff0c;但是还是不够偷懒 项目添加Lombok。 Lombok是⼀个Java⼯具库&#xff0c;通过添加注…...

Docker 中安装和配置带用户名和密码保护的 Elasticsearch

在 Docker 中安装和配置带用户名和密码保护的 Elasticsearch 需要以下步骤。Elasticsearch 的安全功能&#xff08;包括基本身份验证&#xff09;在默认情况下是启用的&#xff0c;但在某些版本中可能需要手动配置。以下是详细步骤&#xff0c;包括如何设置用户名和密码。 1. …...

面试官:说说JVM内存调优及内存结构

1. JVM简介 JVM&#xff08;Java虚拟机&#xff09;是运行Java程序的平台&#xff0c;它使得Java能够跨平台运行。JVM负责内存的自动分配和回收&#xff0c;减轻了程序员的负担。 2. JVM内存结构 运行时数据区是JVM中最重要的部分&#xff0c;包含多个内存区域&#xff1a; …...

Ansible的脚本-----playbook剧本【下】

目录 实战演练六&#xff1a;tags 模块 实战演练七&#xff1a;Templates 模块 实战演练六&#xff1a;tags 模块 可以在一个playbook中为某个或某些任务定义“标签”&#xff0c;在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。 playboo…...

Mysql开启远程控制简化版,亲测有效

首先关闭防火墙 改表法 打开上图的CMD&#xff0c;输入密码进入&#xff0c;然后输入一下指令 1.use mysql; 2.update user set host % where user root;//更新root用户的权限&#xff0c;允许任何主机连接 3.FLUSH PRIVILEGES;//刷新权限&#xff0c;使更改生效 具体参考…...

【MQTT协议与IoT通信】MQTT协议的使用和管理

MQTT协议与IoT通信&#xff1a;MQTT协议的使用和管理 目录 引言MQTT协议概述 什么是MQTTMQTT的工作原理 MQTT协议的关键特性 轻量级与高效性发布/订阅模式质量服务等级(QoS)持久会话安全性 MQTT协议的使用方法 设置MQTT Broker连接MQTT Client发布消息订阅主题断开连接 MQTT协…...

根据题意写出完整的css,html和js代码【购物车模块页面及功能实现】

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…...

AWS免费层之后:了解和管理您的云服务成本

Amazon Web Services (AWS) 为新用户提供了12个月的免费层服务&#xff0c;这是许多人开始使用云服务的绝佳方式。但是&#xff0c;当这一年结束后&#xff0c;您的AWS使用会如何变化&#xff1f;我们九河云通过本文将探讨免费层结束后的AWS成本情况&#xff0c;以及如何有效管…...

Linux定时同步系统时间到硬件时间

Linux定时同步系统时间到硬件时间 1. 系统时间、软件时间 系统时间 &#xff08;System Time&#xff09;&#xff1a; 一般说来就是我们执行 date命令看到的时间&#xff0c;linux系统下所有的时间调 用&#xff08;除了直接访问硬件时间的命令&#xff09;都是使用的这个时…...

网络编程——wireshark抓包、tcp粘包

目录 一、前言 1.1 什么是粘包 1.2 为什么UDP不会粘包 二、编写程序 文件树 客户端程序 服务器程序 tcp程序 头文件 makefile 三、 实验现象 四、改进实验 五、小作业 一、前言 最近在做网络芯片的驱动&#xff0c;验证功能的时候需要借助wireshark这个工具&…...

el-table合计行更新问题

说明&#xff1a;在使用el-table自带的底部合计功能时&#xff0c;初始界面不会显示合计内容 解决方案&#xff1a;使用 doLayout()方法 updated() {this.$nextTick(() > {this.$refs[inventorySumTable].doLayout();});},完整代码&#xff1a; // show-summary&#xff1a…...

ChatGPT:数据库不符合第二范式示例

ChatGPT&#xff1a;数据库不符合第二范式示例 这张图片为什么不符合数据库第二范式 这个表格不符合数据库第二范式&#xff08;2NF&#xff09;的原因如下&#xff1a; 1. 数据库第二范式&#xff08;2NF&#xff09;定义 第二范式要求一个数据库表格在满足第一范式&#xf…...

27、美国国家冰雪中心(NSIDC)海冰密集度月数据下载与处理

文章目录 一、前言二、数据下载三、使用Ponply查看数据结构四、代码一、前言 处理美国国家冰雪中心(NSIDC)的海冰密集度月度数据时,坐标转换是一个重要的步骤。NSIDC提供的数据通常采用极地球面坐标系,需要将其转换为常用的地理坐标系(如经纬度)以便进行分析和可视化。 坐…...

vite环境下使用bootstrap

环境 nodejs 18 pnpm 初始化 pnpm init pnpm add -D vite --registry http://registry.npm.taobao.org pnpm add bootstrap popperjs/core --registry http://registry.npm.taobao.org pnpm add -D sass --registry http://registry.npm.taobao.org新建vite.config.js cons…...

Laravel视图渲染封装

第一种 app/Helpers/ViewHelper.php 创建一个辅助函数&#xff0c;用于动态确定视图路径&#xff1a; <?php if (!function_exists(fetchView)) {function fetchView($data []){$currentAction \Route::currentRouteAction();list($controller, $method) explode(, $c…...

C++学习补充2:MySQL select 查询

MySQL select 查询 MySQL 查询 select时&#xff0c; 不区分大小写的。 MySQL 在默认情况下是区分大小写的&#xff0c;但是它的行为可能因配置和使用的字符集而有所不同。以下是一些可能导致查询在 SELECT 语句中不区分大小写的原因&#xff1a; 字符集设置&#xff1a;如果…...

uni-app声生命周期

应用的生命周期函数在App.vue页面 onLaunch:当uni-app初始化完成时触发&#xff08;全局触发一次&#xff09; onShow:当uni-app启动&#xff0c;或从后台进入前台时显示 onHide:当uni-app从前台进入后台 onError:当uni-app报错时触发,异常信息为err 页面的生命周期 onLoad…...

排序算法--堆排序

基本思想 堆排序的基本思想是&#xff0c;将待排序的元素构建成一个最大堆或最小堆。对于最大堆来说&#xff0c;堆顶是整个堆中的最大元素&#xff1b;对于最小堆来说&#xff0c;堆顶是整个堆中的最小元素。然后&#xff0c;将堆顶元素与堆中最后一个元素交换&#xff0c;并…...

iPhone 在 App Store 中推出的 PC 模拟器 UTM SE

PC 模拟器是什么&#xff1f;PC 模拟器是一种软件工具&#xff0c;它模拟不同硬件或操作系统环境&#xff0c;使得用户可以在一台 PC 上运行其他平台的应用程序或操作系统。通过 PC 模拟器&#xff0c;用户可以在 Windows 电脑上体验 Android 应用、在 Mac 电脑上运行 Windows …...