------2019.08.06補充
日期年與日的加減運算。
給定一個開始日期,對其進行加年,加月,加天運算
如下給起始日期和給定月份,計算結束日期
/** * 給起始日期和給定月份,計算結束日期工具 * 開始日期格式為:yyyy-MM-dd * */ public static String getEndDateBymonths(String startDateStr, int months){ //分隔日期為字符串數組,1為年,2為月,3為日 String dataStr[] = startDateStr.split("-"); //年份,開始日期的月份加上當前月份。除以12,即增加年數。 int year = (Integer.parseInt(dataStr[1]) + months)/12; //月份 int mon = (Integer.parseInt(dataStr[1]) + months)%12; //格式化月份。 String a = ""; if(mon<10){ if(mon<1){ a = "12"; }else{ a = "0"+mon; } }else { a = mon+""; } dataStr[0]=String.valueOf(Integer.parseInt(dataStr[0]) + year); dataStr[1]=a; String newdata =""; newdata = dataStr[0]+"-"+dataStr[1]+"-"+dataStr[2]; return newdata; }
自己編寫計算方法需要很長代碼。而如果借助java.util.Calendar類來進行日期計算,能夠很方便計算出年月日的加減
SimpleDateFormat sj = new SimpleDateFormat("yyyy-MM-dd"); String newdata ="2018-01-01"; Date d; try { d = sj.parse(newdata); Calendar calendar = Calendar.getInstance(); calendar.setTime(d); calendar.add(Calendar.MONTH, 3); newdata = sj.format(calendar.getTime()); } catch (ParseException e) { e.printStackTrace(); } System.out.println(newdata);
上面加月份只需要幾行代碼,而不需要我們考慮內部細節
如果要加3年
calendar.add(Calendar.YEAR, 3);
減三年用calendar.add(Calendar.YEAR, -3);
Calendar的屬性字段有:YEAR年的計算,MONTH月的計算,DATE日的計算
借助工具類可以更加靈活方便
兩個日期之間相減得到的天數
(int) ((dateEnd.getTime() - dateStart.getTime()) / 1000 / 60 / 60 / 24) 實現思路是通過java.util.Date類的getTime()方法獲得日期的毫秒數, 然后相減dateEnd.getTime() - dateStart.getTime(),得到毫秒數的差,除以1000,得到秒數的差;再除以60,得到分鍾數的差;再除以60,得到小時數的差;再除以24小時,得到天數的差。 ———————————————— 版權聲明:本文為CSDN博主「wpydaguan」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/wpydaguan/article/details/46235349
1、獲得時間戳
為了統一其他語言的如php和unix系統獲取的時間戳是10位長度的,精確到秒。
java時間戳長度是13位,精確到毫秒 我們獲取時間戳需要相應處理。
//獲取當前時間戳,除以1000,獲取到長度為10位的,精確到秒 public static long now() { return System.currentTimeMillis() / 1000; }
2、時間戳轉化為固定模式的日期yyyy-MM-dd HH:mm:ss
兩種時間戳轉換為日期的方法,發現testTime方法比較快。
testTime2將long轉換為字符串加0后,再轉為long,需要時間比較久。
public static String testTime(String pattern, long timestamp) { SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.SIMPLIFIED_CHINESE); return format.format(timestamp * 1000); } public static String testTime2(String pattern, long timestamp) { SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.SIMPLIFIED_CHINESE); return format.format(Long.parseLong(String.valueOf(timestamp) + "000")); }
3日期轉換為時間戳
先將日期字符串轉為Date對象,再用Date.getTime()獲取時間戳
public static String datePattern = "yyyy-MM-dd"; public static String timeStampPattern = "yyyy-MM-dd HH:mm:ss"; public static Date toDate(String dateStr) { if (StrKit.isBlank(dateStr)) { return null; } dateStr = dateStr.trim(); int length = dateStr.length(); try { if (length == timeStampPattern.length()) { SimpleDateFormat sdf = new SimpleDateFormat(timeStampPattern); try { return sdf.parse(dateStr); } catch (ParseException e) { dateStr = dateStr.replace(".", "-"); dateStr = dateStr.replace("/", "-"); return sdf.parse(dateStr); } } else if (length == datePattern.length()) { SimpleDateFormat sdfDate = new SimpleDateFormat(datePattern); try { return sdfDate.parse(dateStr); } catch (ParseException e) { dateStr = dateStr.replace(".", "-"); dateStr = dateStr.replace("/", "-"); return sdfDate.parse(dateStr); } } else { throw new IllegalArgumentException("The date format is not supported for the time being"); } } catch (ParseException e) { throw new IllegalArgumentException("The date format is not supported for the time being"); } }
測試代碼如下
Date obtain = toDate("2017-12-10");
long ss = obtain.getTime();
String dateStr = timestamp2DateTime("yyyy-MM-dd HH:mm:ss", ss);
System.out.println(dateStr);
結果2017-12-10 00:00:00
下面是廢話
前端用js的Date對象的Date.getTime()方法獲取到的時間戳是13位長度的,精確到毫秒,一般需要進行轉換成精確度到秒。即除以1000
#時間戳轉日期
一般時間戳都是精確到毫秒
默認的時間戳轉日期的方法。
這個方法是調用的SimpleDateFormat只有一個參數的構造方法獲得格式轉換對象
這個方法會讓我們對時間格式時區掌控,當系統所在時區發生變化時,日期格式也會發生變化
public static String timestamp2DateTime(String pattern, long timestamp) { SimpleDateFormat format = new SimpleDateFormat(pattern); return format.format(timestamp); }
上面的SimpleDateFormat(pattern)
默認會指定當前運行環境所在時區為構造方法,這種不確定性的默認應該需要避免
public SimpleDateFormat(String pattern) { this(pattern, Locale.getDefault(Locale.Category.FORMAT)); }
我們自己指定需要轉換的時區
獲取到Locale,即指定國家的時間,這里是獲得簡體中文,北京時間也就是東八區的locale對象
Locale simpleChinese = new Locale("zh","CN");
Locale.SIMPLIFIED_CHINESE
/** * 時間戳轉化為北京時間日期格式 * @param pattern * 如:yyyy-MM-dd HH:mm:ss 獲取時間格式為: 年-月-日 時:分:秒<br> * pattern模式匹配語法: G 年代標志符<br> y 年<br> M 月<br> d 日<br> h 時 在上午或下午 (1~12)<br> H 時 在一天中 (0~23)<br> m 分<br> s 秒<br> S 毫秒<br> E 星期<br> D 一年中的第幾天<br> F 一月中第幾個星期幾<br> w 一年中第幾個星期<br> W 一月中第幾個星期<br> a 上午 / 下午 標記符<br> k 時 在一天中 (1~24)<br> K 時 在上午或下午 (0~11)<br> z 時區<br> * @param timestamp * 時間戳 * @return */ public static String timestamp2DateTime(String pattern, long timestamp) { //使用簡體中文所在的時區 SimpleDateFormat format = new SimpleDateFormat(pattern,Locale.SIMPLIFIED_CHINESE); return format.format(timestamp); }
時間更精確的值
1秒 = 1 X 10E15(次方)飛秒 = 1 X 10E12 皮秒 = 1 X 10E9 納秒 = 1 X 10E6 微妙 = 1 X 10E3 毫秒
1秒 = 1000000000000000飛秒 = 1000000000000皮秒 = 1000000000納秒 = 1000000微秒 = 1000毫秒
1秒 = 1000000000000皮秒 = 1000000000納秒 = 1000000微秒 = 1000毫秒
1秒 = 1000000000納秒 = 1000000微秒 = 1000毫秒
1秒 = 1000000微秒 = 1000毫秒
1秒 = 1000毫秒
#納秒
1秒等於10的9次方納秒
這個納秒只能用來精確統計程序運行的時間,比如計算一個程序運行的時間長短,需要一定的准確度。用currentTimeMillis()只能精確到毫秒
System.currentTimeMillis()起始時間是基於1970.1 10:00:00這個
前段時間項目中需要 統計接口連接時間,考慮到連接時間一般都是零點幾毫秒級別的,為了拿到更精確地數值,沒有使用System.currentTimeMillis(),而是貿然地使用System.nanoTime()來統計時間,后來分析服務器上的數據,發現 竟然有10-15%的數據數值竟然超過了 10的13次方。 原因: System.currentTimeMillis() 起始時間是基於 1970.1.1 0:00:00 這個確定的時間的,而System.nanoTime()是基於cpu核心的時鍾周期來計時,它的開始時間是不確定的。(有篇文章說是根據cpu核心的啟動時間開始計算的) 但是在多核處理器上,由於每個核心的開始時間不確定,但是在多核處理器上, long start = System.nanoTime();String ip = Utilities.getIpByUrl(url);long cost = System.nanoTime() - start; 這段代碼有可能會運行在兩個不同的cpu核心上,從而導致得到的結果完全不符邏輯。
這是測試納秒的時間間隔的測試方法
60萬次數據進行測試,600萬數據太大,文本文件打不開,看來要重新安裝nodepad++才好。
File tmpFile = new File("D:/testNanoTime.txt"); FileWriter write = null; try { write = new FileWriter(tmpFile); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } int size = 600000; long[] timeStamp = new long[size]; for (int i = 0; i < size; i++) { timeStamp[i] = System.nanoTime(); } long increase = 0l; for (int i = 0; i < size - 1; i++) { increase = timeStamp[i + 1] - timeStamp[i]; if (increase > 0) { // System.out.println("第" + i+1 + "個:"+timeStamp[i + 1]+"第" + i + "個:"+timeStamp[i]+"差值"+increase); try { write.write("第" + i+1 + "個:"+timeStamp[i + 1]+"第" + i + "個:"+timeStamp[i]+"差值"+increase+"\n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } increase = 0; } try { write.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("操作完成");
