一篇文章带你学完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);  }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 快慢指针

1 环形链表 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; 定义两个指针&#xff0c;一快一慢。慢指针每次只移动一步&#xff0c;而快指针每次移动两步。初始时&#xff0c;慢指针和快指针都在位置 head&#xff0c;这样一来&#xff0c;如果在移动的过程中&#x…

05。拿捏ArkTS 第 3 天 --- 对象、联合类型、枚举

1&#xff0c;什么是对象&#xff1f;对象是干什么的&#xff1f; &#xff5e;用来存储不同类型数据的容器 &#xff5e;用来描述物体的特征和行为 //特征就是属性&#xff0c;行为就是方法&#xff08;对象内的函数&#xff09; 2&#xff0c;对象的基本样式是&#xff1f; …

Noah-MP陆面生态水文模拟与多源遥感数据同化技术

了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用&#xff1b;熟悉模型的发展历程&#xff0c;常见模型及各自特点&#xff1b;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP模型在单站和区域的模拟、模拟结果的输出和后续分析及可视化等方法&#xff1b;…

OpenGL入门第六步:材质

目录 结果显示 材质介绍 函数解析 具体代码 结果显示 材质介绍 当描述一个表面时&#xff0c;我们可以分别为三个光照分量定义一个材质颜色(Material Color)&#xff1a;环境光照(Ambient Lighting)、漫反射光照(Diffuse Lighting)和镜面光照(Specular Lighting)。通过为每…

JQuery 弹幕可上下左右

水平弹幕&#xff0c;可设置向左、向右 containerId为显示弹幕容器ID, message弹幕内容, direction弹幕移动方向 // Jquery指定容器 向左或向右弹幕function sendBarrage_horizontal(containerId, message, direction) {// 第1部分,设置并挂载元素// 定义弹幕元素&#xff0c…

23.jdk源码阅读之Thread(下)

1. 写在前面 上篇文章我们介绍了Tread的一些方法的底层代码实现&#xff0c;这篇文章我们继续。 2. join()方法的底层实现 /*** Waits at most {code millis} milliseconds for this thread to* die. A timeout of {code 0} means to wait forever.** <p> This impleme…

【java】【springboot】启动方法注解详解

在Spring Boot中&#xff0c;启动方法通常是main方法&#xff0c;它位于应用程序的主类中&#xff0c;负责启动Spring应用上下文。 一、SpringBootApplication SpringBootApplication 是 Spring Boot 中一个非常核心的注解&#xff0c;它是一个复合注解&#xff0c;包含了三个…

从工艺到性能:模具3D打印材料不断革新

在模具3D打印领域&#xff0c;材料性能的持续优化与创新是推动模具3D打印的关键因素&#xff0c;近年来&#xff0c;各种3D打印新材料不断涌现&#xff0c;模具3D打印材料也开始重工艺导向逐步向性能导向发展&#xff0c;如毅速公司推出的ESU-EM191/191S及ESU-EM201不锈钢粉末、…

电脑文件误删除如何恢复?数据恢复第一步是什么?这五点要第一时间处理!

电脑文件误删除如何恢复&#xff1f;数据删除恢复的第一时间要做什么&#xff0c;你知道吗&#xff1f; 在使用电脑的过程中&#xff0c;误删除重要文件的情况时有发生。面对这种情况&#xff0c;不必过于慌张&#xff0c;因为有多种方法可以帮助你恢复误删除的文件。以下是恢复…

网络通信---UDP

前两天做了个mplayer项目&#xff0c;今日继续学习 网络内容十分重要&#xff01;&#xff01;&#xff01; 1.OSI七层模型 应用层:要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等&#xff08;最接近用户&#xff0c;看传输的内容类型到底是什么&#xff09; …

香橙派orangepi系统没有apt,也没有apt-get,也没有yum命令,找不到apt、apt-get、yum的Linux系统

以下是一个关于如何在 Orange Pi 上的 Arch Linux 系统中发现缺失包管理器的问题并解决的详细教程。 发现问题 确认系统类型&#xff1a; 使用以下命令检查当前的 Linux 发行版&#xff1a; uname -a cat /etc/os-release如果你看到类似于 “Arch Linux” 的信息&#xff0c;说…

【数据结构与算法】顺序表

顺序表 一.顺序表的原理1.是什么2.数据结构 二.顺序表的初始化三.顺序表增加元素四.顺序表插入元素五.顺序表删除元素六.顺序表的销毁七.总结 一.顺序表的原理 1.是什么 顺序表是一种线性的结构,类似于数组,但是中间不能有空值. 元素顺序地存储在一段连续的内存空间中. 顺序表…

单关节电机动力学辨识

这是一个单关节电机的动力学辨识过程&#xff0c;这是一个yaw轴转动电机的动力学辨识过程 1、动力学建模 &#xff08;1&#xff09;整体动力学 F J α f F J\alpha f FJαf 单关节的物理量包括惯性项、离心力和科氏力、摩擦力。这里忽略离心力和科氏力&#xff0c;据说…

SolidEdge二次开发(C#)-环境配置

文章目录 1、前言2、环境配置2.1 安装Solidworks20242.2 安装VS20222.3 查看Com组件2.3.1 在VS2022中创建一个wpf工程项目2.3.2 添加com组件 1、前言 SolidEdge是Siemens PLM Software公司旗下的三维CAD软件&#xff0c;采用Siemens PLM Software公司自己拥有专利的Parasolid作…

使用Java和Spring Retry实现重试机制

使用Java和Spring Retry实现重试机制 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将探讨如何在Java中使用Spring Retry来实现重试机制。重试机制在处理临时性故障和提高系统稳…

Pandas筛选数据的10种方法

Pandas是Python中用于数据操作和分析的强大库之一.它提供了丰富的功能来处理和筛选数据.本文将介绍Pandas中筛选数据的10种常用方法,并通过示例展示具体操作步骤. 1. 基于条件筛选 Pandas支持通过布尔索引根据条件筛选数据.这是最常用的筛选方法之一. import pandas as pd# …

2679. 矩阵中的和

两种方法&#xff1a; 第一种&#xff1a;先对二维列表的每一列进行排序&#xff0c;然后对每一列的数据进行逐个比较&#xff0c;找出最大值。 class Solution:def matrixSum(self, nums: list[list[int]]) -> int:result0mlen(nums)nlen(nums[0])for i in range(m):nums…

js动画插件-vue

分享一个动画插件 学习 动画插件 是进入大厂的必备技能 首先我们需要先学会 去使用js 动画 封装好的 GreenSock 动画平台 &#xff08;GSAP&#xff09; greensock.com/gsap/ 就是这个插件 我现在分享一个用例 其实很简单 但是 具体的属性 和很多 内容需要慢慢使用 慢慢看…

C++客户端Qt开发——系统相关(文件操作)

2.文件操作 ①输入输出设备类 在Qt中&#xff0c;文件读写的类为QFile。QFile的父类为QFileDevice,QFileDevice提供了文件交互操作的底层功能。QFileDevice的父类是QIODevice,QIODevice的父类为QObject。 QIODevice是Qt中所有输入输出设备(input/output device,简称I/O设备)…