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

[Java/日期/时间/时区] Java 时间的转换与处理:DateTimeUtils

概述:Java 时间的转换与处理

深入理解:Date / Calendar / Timestamp / TimeZone

  • java.util.Date / java.sql.Timestamp : 基于时间戳(Long)构建,与时区无关
  • java.util.Calendar: 基于时间字符串(String)构建,与时区强依赖
  • java.text.SimpleDateFormat : 与时区强依赖
  • java.util.TimeZone : 时区对象

Z 最佳实践

DateTimeUtils

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;/*** @updateTime 2025-09-10 23:28* @description* @reference-doc*  [1] java 不同时区转换 - CSDN - https://blog.csdn.net/qq_41344974/article/details/125505290*/
public class DatetimeUtils {private final static Logger logger = LoggerFactory.getLogger(DatetimeUtils.class);/** 毫秒级时间字符串 millisecond time format **/public final static String MILLISECOND_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";public final static String MILLISECOND_TIME_WITH_NUMBER_FORMAT = "yyyyMMddHHmmssSSS";/*** 时区ID* @sample-values 可选值*  "Asia/Shanghai" / "UTC" / "GMT" / ...* @note* "Asia/Shanghai" = "CST" (China Standard Time) = GMT+8 = UTC+8*/public final static String zoneId = "UTC";//public final static TimeZone timepublic static String calendarToString(Calendar calendar, String format, TimeZone targetTimeZone){SimpleDateFormat sdf = new SimpleDateFormat(format); //such as: "yyyy-MM-dd"sdf.setTimeZone( targetTimeZone );return sdf.format(calendar.getTime());//时间戳转指定时区的时间字符串}public static Calendar stringToCalendar(String dateStr,String format, TimeZone timeZone) throws ParseException {SimpleDateFormat sdf= new SimpleDateFormat(format); //such as:"yyyy-MM-dd"sdf.setTimeZone( timeZone );Date date = sdf.parse(dateStr);return dateToCalendar(date, timeZone);}/*** 时间戳 转 Date* @note*   1. {@link Date } 底层存储与维护的是 long (时间戳)*   2. 基于第1点,未涉及时区* @param time 13位的毫秒级时间戳 eg: 1503544630000L* @return*/public static Date longToDate(long time){return new Date(time);}public static Calendar longToCalender(long time, TimeZone timeZone){return dateToCalendar( longToDate(time), timeZone );}public static Long calenderToLong(Calendar calendar){return calendarToTimestamp(calendar).getTime();}/**** @param time*  eg:*      1665211423751L* @param format*  eg:*      "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"* @return*  eg:*      "2022-10-08T14:43:43.751Z"*/public static String longToString(long time, String format, TimeZone timeZone){return calendarToString( longToCalender(time, timeZone), format, timeZone );}/**** @param datetimeStr 当前应用的时间字符串*  eg:*      "2022-10-06 11:49:00"*      "2022-10-06 11:49"*      "2022-10-08T07:01:40.751Z"* @param format*  eg:*      "yyyy-MM-dd hh:mm:ss"*      "yyyy-MM-dd hh:mm"*      "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" | T代表可替换的任意字符, Z 代表时区* @param timeZone [选填参数] 允许为 null*  可选值有:*      "UTC" / "Asia/Shanghai" / "GMT" / "GMT+08:00" / ...* @return*  eg:*      1665028140000L*      1665028140000L*      1665212500751L [timeZone=UTC] 1665183700751L [timeZone=null]* @reference-doc*  [1] java 不同时区转换 - CSDN - https://blog.csdn.net/qq_41344974/article/details/125505290*/public static long stringToLong(String datetimeStr, String format, String timeZone) {SimpleDateFormat formatSDF = new SimpleDateFormat(format);// such as "yyyyMMddhhmmss"//new SimpleDateFormat(format, Locale.getDefault());// such as "yyyyMMddhhmmss"if(! StringUtils.isEmpty(timeZone) ){formatSDF.setTimeZone(TimeZone.getTimeZone(timeZone));}Date date = null;try {date = formatSDF.parse(datetimeStr);return date.getTime();} catch (ParseException e) {e.printStackTrace();}return -1;}public static long stringToLong(String datetimeStr, String format, TimeZone timeZone) {return stringToLong(datetimeStr, format, timeZone);}public static String dateToString(Date date, String format, TimeZone timeZone){SimpleDateFormat sdf= new SimpleDateFormat(format); //such as:"yyyy-MM-dd"sdf.setTimeZone(timeZone);return sdf.format(date);}public static Date stringToDate(String dateStr, String formatOfStr, TimeZone timeZone) throws ParseException {//dateStr such as :"2018-11-4"SimpleDateFormat sdf = new SimpleDateFormat(formatOfStr);//such as:"yyyy-MM-dd"sdf.setTimeZone( timeZone );return sdf.parse(dateStr);}/*** Date 转 Calendar* @note*   1. 此转换过程,因涉及 {@link Calendar } 涉及时区* @param date* @return*/@Deprecatedpublic static Calendar dateToCalendar(Date date){Calendar calendar = Calendar.getInstance();//等效于: createCalendar(TimeZone.getDefault(), Locale.getDefault(Category.FORMAT));calendar.setTime(date);return calendar;}public static Calendar dateToCalendar(Date date, TimeZone timeZone){Calendar calendar = Calendar.getInstance( timeZone );//createCalendar(TimeZone.getDefault(), Locale.getDefault(Category.FORMAT));calendar.setTime(date);return calendar;}public static Date calendarToDate(Calendar calendar){Date date = calendar.getTime();return date;}public static Timestamp stringToTimestamp(String dateStr,String dateFormat, TimeZone timeZone) throws ParseException {//dateStr such as:"2019-1-14 08:11:00"Calendar calendar = stringToCalendar(dateStr, dateFormat, timeZone);Timestamp timestamp = new Timestamp( calendar.getTimeInMillis() );//Timestamp timestamp = Timestamp.valueOf(dateStr);return timestamp;}public static String timestampToString(Timestamp timestamp, String format, TimeZone timeZone){SimpleDateFormat sdf= new SimpleDateFormat(format);//such as:"yyyy-MM-dd"sdf.setTimeZone( timeZone );return sdf.format(timestamp);}public static Timestamp dateToTimestamp(Date date){SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Timestamp timestamp = new Timestamp( date.getTime() );//Timestamp timestamp = Timestamp.valueOf(df.format(date));return timestamp;}public static Calendar timestampToCalendar(Timestamp timestamp, TimeZone timeZone){Calendar calendar = Calendar.getInstance(timeZone);calendar.setTime(timestamp);return calendar;}public static Timestamp calendarToTimestamp(Calendar calendar){return dateToTimestamp( calendarToDate(calendar) );}public static String millisecondToDateString(long ms){Integer ss = 1000;Integer mi = ss * 60;Integer hh = mi * 60;Integer dd = hh * 24;Long day = ms / dd;Long hour = (ms - day * dd) / hh;Long minute = (ms - day * dd - hour * hh) / mi;Long second = (ms - day * dd - hour * hh - minute * mi) / ss;StringBuffer sb = new StringBuffer();if(day >= 0) {sb.append(day+"day");}if(hour >= 0) {sb.append(hour+"hour");}if(minute >= 0) {sb.append(minute+"minute");}if(second >= 0) {sb.append(second+"second");}return sb.toString();}/*** 纳秒数转毫秒级时间戳* @param targetNanoTime*   eg: long targetNanoTime = System.nanoTime(); // 获取当前时间的 nano time,例如 : 87277522042200* @return*/public static long nanoTimeToMillisTimestamp(long targetNanoTime){//待转换的纳秒时间(targetNanoTime)//long targetNanoTime = System.nanoTime(); // 获取当前时间的 nano time,例如 : 87277522042200//获取当前的毫秒数(currentTimeMillis) 和 纳秒数(currentNanoTime)long currentTimeMillis = System.currentTimeMillis();//例如: 1733985453227long currentNanoTime = System.nanoTime();//例如 : 87277522044200//计算 currentNanoTime 与 targetNanoTime 的差值(nanoTimeDiff)long nanoTimeDiff = currentNanoTime - targetNanoTime;//例如: 2000// 利用 currentNanoTime 和 nanoTimeDiff ,向前推算出 targetNanoTime当时对应的毫秒级时间戳long targetMillisTime = currentTimeMillis - ( nanoTimeDiff / 1000000L);//13位的毫秒级时间戳,例如: 1733985453227//Date date = new Date(targetMillisTime); // 创建日期对象//System.out.println("date : " + date.toString());//例如: date : Thu Dec 12 14:37:33 CST 2024return targetMillisTime;}
}

Y 推荐文献

  • [Linux/MYSQL/Java] 时间与时区(UTC/GMT/CST/Timestamp) - 博客园/千千寰宇

X 参考文献

http://www.hskmm.com/?act=detail&tid=1268

相关文章:

  • Tekla坐标定位插件源码
  • std::map的基本用法
  • 力扣20题 有效的括号
  • 2025年9月10日学习笔记之keil软件仿真调试
  • MySQL的explain使用
  • K8S常见的微服务中间件部署之strom
  • Android种某些常见但由不是很好实现的效果
  • P11696 [JRKSJ ExR] 七影蝶 题解
  • IDEA创建文件时如何自动生成头部文档注释(简单、实用)
  • 一文带你吃透Power Platform,开启低代码开发新世界
  • 力扣19题 删除链表的倒数第N个结点
  • 基于LZO的无损数据压缩IP,高性能压缩速率32Gbps,适用于FPGAASIC
  • MBR引导的OS Bootloader遇到被bios无视引导(自动重启)的解决办法
  • #java作业
  • 【Qt6】qt6下载地址
  • docker compose 启动 redis 服务
  • 同步框架与底层消费机制解决方案梳理
  • QOJ1838 Intellectual Implementation 题解
  • P11967 [GESP202503 八级] 割裂 题解
  • 变量和运算符和类型
  • win 图片和视频文件无法显示缩略图如何解决?
  • 输入和输出
  • 三种语句
  • 力扣第5题最长回文子串
  • 用 Python 和 PaddleOCR 进行验证码识别
  • TASK 1 训练一个网络识别手写数字
  • 复杂背景验证码的识别思路与图像处理方法
  • Symfony学习笔记 - The Symfony Framework Best Practices
  • 大学军训
  • Vue Day3【综合案例2】vue小兔鲜儿