JAVA中計算兩個日期時間的差值竟然也有這麼多門道

来源:https://www.cnblogs.com/softwarearch/archive/2022/07/08/16459526.html
-Advertisement-
Play Games

日期時間的處理,是軟體開發中極其常見的場景,JAVA中與日期、時間相關的一些類與API方法也很多,這裡結合平時的編碼實踐全面的整理了下,希望可以幫助大家釐清其中的門道,更加游刃有餘的面對此方面的處理~ ...


上半年春招的時候,作為面試官,對於面試表現的不錯的同學會要求其寫一小段代碼看看。題目很簡單:

給定一個日期,然後計算下距離今天相差的天數。

本以為這麼個問題就是用來活躍面試氛圍的,但是結果卻讓人大跌眼鏡,真正能寫出來的人竟然寥寥無幾,很多人寫了一整張A4紙都寫不下,最後還是沒寫完...他們在做什麼?

先取出今天的日期,然後分別計算得出年、月、日的值,然後將給定的字元串進行切割,得到目標的年、月、日,然後再判斷是否閏年之類的邏輯,決定每月應該是加28天還是29天還是30或者31天,最後得出一個天數!

想想都令人窒息的操作...

日期時間的處理,是軟體開發中極其常見的場景,JAVA中與日期、時間相關的一些類與API方法也很多,這裡結合平時的編碼實踐全面的整理了下,希望可以幫助大家釐清其中的門道,更加游刃有餘的面對此方面的處理~

JAVA中與日期時間相關的類

java.util包中

類名 具體描述
Date Date對象算是JAVA中歷史比較悠久的用於處理日期、時間相關的類了,但是隨著版本的迭代演進,其中的眾多方法都已經被棄用,所以Date更多的時候僅被用來做一個數據類型使用,用於記錄對應的日期與時間信息
Calender 為了彌補Date對象在日期時間處理方法上的一些缺陷,JAVA提供了Calender抽象類來輔助實現Date相關的一些日曆日期時間的處理與計算。
TimeZone Timezone類提供了一些有用的方法用於獲取時區的相關信息

java.time包中

JAVA8之後新增了java.time包,提供了一些與日期時間有關的新實現類:

具體每個類對應的含義說明梳理如下表:

類名 含義說明
LocalDate 獲取當前的日期信息,僅有簡單的日期信息,不包含具體時間、不包含時區信息。
LocalTime 獲取當前的時間信息,僅有簡單的時間信息,不含具體的日期、時區信息。
LocalDateTime 可以看做是LocalDate和LocalTime的組合體,其同時含有日期信息與時間信息,但是依舊不包含任何時區信息。
OffsetDateTime 在LocalDateTime基礎上增加了時區偏移量信息
ZonedDateTime 在OffsetDateTime基礎上,增加了時區信息
ZoneOffset 時區偏移量信息, 比如+8:00或者-5:00等
ZoneId 具體的時區信息,比如Asia/Shanghai或者America/Chicago

時間間隔計算

Period與Duration類

JAVA8開始新增的java.time包中有提供Duration和Period兩個類,用於處理日期時間間隔相關的場景,兩個類的區別點如下:

描述
Duration 時間間隔,用於秒級的時間間隔計算
Period 日期間隔,用於天級別的時間間隔計算,比如年月日維度的

Duration與Period具體使用的時候還需要有一定的甄別,因為部分的方法很容易使用中被混淆,下麵分別說明下。

  • Duration

Duration的最小計數單位為納秒,其內部使用seconds和nanos兩個欄位來進行組合計數表示duration總長度。

Duration的常用API方法梳理如下:

方法 描述
between 計算兩個時間的間隔,預設是秒
ofXxx 以of開頭的一系列方法,表示基於給定的值創建一個Duration實例。比如ofHours(2L),則表示創建一個Duration對象,其值為間隔2小時
plusXxx 以plus開頭的一系列方法,用於在現有的Duration值基礎上增加對應的時間長度,比如plusDays()表示追加多少天,或者plusMinutes()表示追加多少分鐘
minusXxx 以minus開頭的一系列方法,用於在現有的Duration值基礎上扣減對應的時間長度,與plusXxx相反
toXxxx 以to開頭的一系列方法,用於將當前Duration對象轉換為對應單位的long型數據,比如toDays()表示將當前的時間間隔的值,轉換為相差多少天,而toHours()則標識轉換為相差多少小時。
getSeconds 獲取當前Duration對象對應的秒數, 與toXxx方法類似,只是因為Duration使用秒作為計數單位,所以直接通過get方法即可獲取到值,而toDays()是需要通過將秒數轉為天數換算之後返回結果,所以提供的方法命名上會有些許差異。
getNano 獲取當前Duration對應的納秒數“零頭”。註意這裡與toNanos()不一樣,toNanos是Duration值的納秒單位總長度,getNano()只是獲取不滿1s剩餘的那個零頭,以納秒錶示。
isNegative 檢查Duration實例是否小於0,若小於0返回true, 若大於等於0返回false
isZero 用於判斷當前的時間間隔值是否為0 ,比如比較兩個時間是否一致,可以通過between計算出Duration值,然後通過isZero判斷是否沒有差值。
withSeconds 對現有的Duration對象的nanos零頭值不變的情況下,變更seconds部分的值,然後返回一個新的Duration對象
withNanos 對現有的Duration對象的seconds值不變的情況下,變更nanos部分的值,然後返回一個新的Duration對象

關於Duration的主要API的使用,參見如下示意:


public void testDuration() {
    LocalTime target = LocalTime.parse("00:02:35.700");
    // 獲取當前日期,此處為了保證後續結果固定,註掉自動獲取當前日期,指定固定日期
    // LocalDate today = LocalDate.now();
    LocalTime today = LocalTime.parse("12:12:25.600");
    // 輸出:12:12:25.600
    System.out.println(today);
    // 輸出:00:02:35.700
    System.out.println(target);
    Duration duration = Duration.between(target, today);
    // 輸出:PT12H9M49.9S
    System.out.println(duration);
    // 輸出:43789
    System.out.println(duration.getSeconds());
    // 輸出:900000000
    System.out.println(duration.getNano());
    // 輸出:729
    System.out.println(duration.toMinutes());
    // 輸出:PT42H9M49.9S
    System.out.println(duration.plusHours(30L));
    // 輸出:PT15.9S
    System.out.println(duration.withSeconds(15L));
}

  • Period

Period相關介面與Duration類似,其計數的最小單位是天,看下Period內部時間段記錄採用了年、月、日三個field來記錄:

常用的API方法列舉如下:

方法 描述
between 計算兩個日期之間的時間間隔。註意,這裡只能計算出相差幾年幾個月幾天。
ofXxx of()或者以of開頭的一系列static方法,用於基於傳入的參數構造出一個新的Period對象
withXxx 以with開頭的方法,比如withYears、withMonths、withDays等方法,用於對現有的Period對象中對應的年、月、日等欄位值進行修改(只修改對應的欄位,比如withYears方法,只修改year,保留month和day不變),並生成一個新的Period對象
getXxx 讀取Period中對應的year、month、day欄位的值。註意下,這裡是僅get其中的一個欄位值,而非整改Period的不同單位維度的總值。
plusXxx 對指定的欄位進行追加數值操作
minusXxx 對指定的欄位進行扣減數值操作
isNegative 檢查Period實例是否小於0,若小於0返回true, 若大於等於0返回false
isZero 用於判斷當前的時間間隔值是否為0 ,比如比較兩個時間是否一致,可以通過between計算出Period值,然後通過isZero判斷是否沒有差值。

關於Period的主要API的使用,參見如下示意:


public void calculateDurationDays() {
    LocalDate target = LocalDate.parse("2021-07-11");
    // 獲取當前日期,此處為了保證後續結果固定,註掉自動獲取當前日期,指定固定日期
    // LocalDate today = LocalDate.now();
    LocalDate today = LocalDate.parse("2022-07-08");
    // 輸出:2022-07-08
    System.out.println(today);
    // 輸出:2021-07-11
    System.out.println(target);
    Period period = Period.between(target, today);
    // 輸出:P11M27D, 表示11個月27天
    System.out.println(period);
    // 輸出:0, 因為period值為11月27天,即year欄位為0
    System.out.println(period.getYears());
    // 輸出:11, 因為period值為11月27天,即month欄位為11
    System.out.println(period.getMonths());
    // 輸出:27, 因為period值為11月27天,即days欄位為27
    System.out.println(period.getDays());
    // 輸出:P14M27D, 因為period為11月27天,加上3月,變成14月27天
    System.out.println(period.plusMonths(3L));
    // 輸出:P11M15D,因為period為11月27天,僅將days值設置為15,則變為11月15天
    System.out.println(period.withDays(15));
    // 輸出:P2Y3M44D
    System.out.println(Period.of(2, 3, 44));
}

Duration與Period踩坑記

Duration與Period都是用於日期之間的計算操作。Duration主要用於秒、納秒等維度的數據處理與計算。Period主要用於計算年、月、日等維度的數據處理與計算。

先看個例子,計算兩個日期相差的天數,使用Duration的時候:


public void calculateDurationDays(String targetDate) {
    LocalDate target = LocalDate.parse(targetDate);
    LocalDate today = LocalDate.now();
    System.out.println("today : " + today);
    System.out.println("target: " + target);
    long days = Duration.between(target, today).abs().toDays();
    System.out.println("相差:"  + days + "天");
}

運行後會報錯:


today : 2022-07-07
target: 2022-07-11
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds
	at java.time.LocalDate.until(LocalDate.java:1614)
	at java.time.Duration.between(Duration.java:475)
	at com.veezean.demo5.DateService.calculateDurationDays(DateService.java:24)

點擊看下Duration.between源碼,可以看到註釋上明確有標註著,這個方法是用於秒級的時間段間隔計算,而我們這裡傳入的是兩個級別的數據,所以就不支持此類型運算,然後拋異常了。

再看下使用Period的實現:


public void calculateDurationDays(String targetDate) {
    LocalDate target = LocalDate.parse(targetDate);
    LocalDate today = LocalDate.now();
    System.out.println("today : " + today);
    System.out.println("target: " + target);
    // 註意,此處寫法錯誤!這裡容易踩坑:
    long days = Math.abs(Period.between(target, today).getDays());
    System.out.println("相差:"  + days + "天");
}

執行結果:

today : 2022-07-07
target: 2021-07-07
相差:0天

執行是不報錯,但是結果明顯是錯誤的。這是因為getDays()並不會將Period值換算為天數,而是單獨計算年、月、日,此處只是返回天數這個單獨的值。

再看下麵的寫法:


public void calculateDurationDays(String targetDate) {
    LocalDate target = LocalDate.parse(targetDate);
    LocalDate today = LocalDate.now();
    System.out.println("today : " + today);
    System.out.println("target: " + target);
    Period between = Period.between(target, today);
    System.out.println("相差:"
            + Math.abs(between.getYears()) + "年"
            + Math.abs(between.getMonths()) + "月"
            + Math.abs(between.getDays()) + "天");
}

結果為:


today : 2022-07-07
target: 2021-07-11
相差:0年11月26天

所以說,如果想要計算兩個日期之間相差的絕對天數,用Period不是一個好的思路。

計算日期差

  • 通過LocalDate來計算

LocalDate中的toEpocDay可返回當前時間距離原點時間之間的天數,可以基於這一點,來實現計算兩個日期之間相差的天數:

代碼如下:


public void calculateDurationDays(String targetDate) {
    LocalDate target = LocalDate.parse(targetDate);
    LocalDate today = LocalDate.now();
    System.out.println("today : " + today);
    System.out.println("target: " + target);
    long days = Math.abs(target.toEpochDay() - today.toEpochDay());
    System.out.println("相差:" + days + "天");
}

結果為:


today : 2022-07-07
target: 2021-07-11
相差:361天

  • 通過時間戳來計算

如果是使用的Date對象,則可以通過將Date日期轉換為毫秒時間戳的方式相減然後將毫秒數轉為天數的方式來得到結果。需要註意的是通過毫秒數計算日期天數的差值時,需要屏蔽掉時分秒帶來的誤差影響。


public void calculateDaysGap(Date start, Date end) {
    final long ONE_DAY_MILLIS = 1000L * 60 * 60 * 24;
    // 此處要註意,去掉時分秒的差值影響,此處採用先換算為天再相減的方式
    long gapDays = Math.abs(end.getTime()/ONE_DAY_MILLIS - start.getTime()/ONE_DAY_MILLIS);
    System.out.println(gapDays);
}

輸出結果:


today : 2022-07-08
target: 2021-07-11
相差:362天

  • 數學邏輯計算

分別算出年、月、日差值,然後根據是否閏年、每月是30還是31天等計數邏輯,純數學硬懟方式計算。

不推薦、代碼略...

計算介面處理耗時

在一些性能優化的場景中,我們需要獲取到方法處理的執行耗時,很多人都是這麼寫的:


public void doSomething() {
    // 記錄開始時間戳
    long startMillis = System.currentTimeMillis();
    // do something ...
    
    // 計算結束時間戳
    long endMillis = System.currentTimeMillis();
    
    // 計算相差的毫秒數
    System.out.println(endMillis - startMillis);
}

當然啦,如果你使用的是JDK8+的版本,你還可以這麼寫:


public void doSomething() {
    // 記錄開始時間戳
    Instant start = Instant.now();
    // do something ...

    // 計算結束時間戳
    Instant end = Instant.now();

    // 計算相差的毫秒數
    System.out.println(Duration.between(start, end).toMillis());
}

時間格式轉換

項目中,時間格式轉換是一個非常典型的日期處理操作,可能會涉及到將一個字元串日期轉換為JAVA對象,或者是將一個JAVA日期對象轉換為指定格式的字元串日期時間。

SimpleDataFormat實現

在JAVA8之前,通常會使用SimpleDateFormat類來處理日期與字元串之間的相互轉換:


public void testDateFormatter() {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 日期轉字元串
    String format = simpleDateFormat.format(new Date());
    System.out.println("當前時間:" + format);
   
    try {
        // 字元串轉日期
        Date parseDate = simpleDateFormat.parse("2022-07-08 06:19:27");
        System.out.println("轉換後Date對象: " + parseDate);
        // 按照指定的時區進行轉換,可以對比下前面轉換後的結果,會發現不一樣
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+5:00"));
        parseDate = simpleDateFormat.parse("2022-07-08 06:19:27");
        System.out.println("指定時區轉換後Date對象: " + parseDate);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

輸出結果如下:


當前時間:2022-07-08 06:25:31
轉換後Date對象: Fri Jul 08 06:19:27 CST 2022
指定時區轉換後Date對象: Fri Jul 08 09:19:27 CST 2022

補充說明:

SimpleDateFormat對象是非線程安全的,所以項目中在封裝為工具方法使用的時候需要特別留意,最好結合ThreadLocal來適應在多線程場景的正確使用。
JAVA8之後,推薦使用DateTimeFormat替代SimpleDateFormat。

DataTimeFormatter實現

JAVA8開始提供的新的用於日期與字元串之間轉換的類,它很好的解決了SimpleDateFormat多線程的弊端,也可以更方便的與java.time中心的日期時間相關類的集成調用。


public void testDateFormatter() {
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime localDateTime = LocalDateTime.now();
    // 格式化為字元串
    String format = localDateTime.format(dateTimeFormatter);
    System.out.println("當前時間:" + format);
    // 字元串轉Date
    LocalDateTime parse = LocalDateTime.parse("2022-07-08 06:19:27", dateTimeFormatter);
    Date date = Date.from(parse.atZone(ZoneId.systemDefault()).toInstant());
    System.out.println("轉換後Date對象: " + date);
}


輸出結果:


當前時間:2022-07-08 18:37:46
轉換後Date對象: Fri Jul 08 06:19:27 CST 2022

日期時間格式模板

對於電腦而言,時間處理的時候按照基於時間原點的數字進行處理即可,但是轉為人類方便識別的場景顯示時,經常會需要轉換為不同的日期時間顯示格式,比如:


2022-07-08 12:02:34
2022/07/08 12:02:34.238
2022年07月08日 12點03分48秒

在JAVA中,為了方便各種格式轉換,提供了基於時間模板進行轉換的實現能力:

時間格式模板中的字幕含義說明如下:

字母 使用說明
yyyy 4位數的年份
yy 顯示2位數的年份,比如2022年,則顯示為22年
MM 顯示2位數的月份,不滿2位數的,前面補0,比如7月份顯示07月
M 月份,不滿2位的月份不會補0
dd 天, 如果1位數的天數,則補0
d 天,不滿2位數字的,不補0
HH 24小時制的時間顯示,小時數,兩位數,不滿2位數字的前面補0
H 24小時制的時間顯示,小時數,不滿2位數字的不補0
hh 12小時制的時間顯示,小時數,兩位數,不滿2位數字的前面補0
ss 秒數,不滿2位的前面補0
s 秒數,不滿2位的不補0
SSS 毫秒數
z 時區名稱,比如北京時間東八區,則顯示CST
Z 時區偏移信息,比如北京時間東八區,則顯示+0800

消失的8小時問題

日期字元串存入DB後差8小時

在後端與資料庫交互的時候,可能會遇到一個問題,就是往DB中存儲了一個時間欄位之後,後面再查詢的時候,就會發現時間數值差了8個小時,這個需要在DB的連接信息中指定下時區信息:


spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai

界面時間與後臺時間差8小時

在有一些前後端交互的項目中,可能會遇到一個問題,就是前端選擇並保存了一個時間信息,再查詢的時候就會發現與設置的時間差了8個小時,這個其實就是後端時區轉換設置的問題。

SpringBoot的配置文件中,需要指定時間字元串轉換的時區信息:


spring.jackson.time-zone=GMT+8

這樣從介面json中傳遞過來的時間信息,jackson框架可以根據對應時區轉換為正確的Date數據進行處理。


我是悟道,聊技術、又不僅僅聊技術~

如果覺得有用,請點個關註,也可以關註下我的公眾號【架構悟道】,獲取更及時的更新。

期待與你一起探討,一起成長為更好的自己。

本文來自博客園,作者:架構悟道,歡迎關註公眾號[架構悟道]持續獲取更多乾貨,轉載請註明原文鏈接:https://www.cnblogs.com/softwarearch/p/16459526.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • @(公眾號測試號H5授權《前端》) Tips:因為申請公眾號需要 ¥300。 so 我用的是測試號。【白嫖永遠不虧】 需要註意的是 測試號是和個人微信號關聯起來的,不是公眾號主體關聯。。也就是每個人都可以申請,而不是必須有公眾號主題才可以。測試號和公眾號是獨立的。 一、前置準備-註冊配置測試賬號 1 ...
  • CSS進階內容 在學習了CSS基本知識之後,我們需要進一步瞭解CSS,因此寫下了這篇文章 當然如果沒有學習之前的知識,可以到我的主頁中查看之前的文章:秋落雨微涼 - 博客園 CSS三大特性 首先我們先來瞭解CSS的三大特點,以便於我們下麵知識點的講解 CSS三大特性包括: 層疊性 繼承性 優先順序 層 ...
  • 經查,發現我們開發的程式是用webpack打包發佈的,而該頁面在微信小程式打開時,對方註入了幾個微信相關的js腳本,而該腳本也是使用webpack打包生成的。雙方的js代碼導致window.webpackJsonp 被重覆定義。 當兩者的webpack版本不同時,生成的 window.webpack ...
  • 隨著Vue3和TypeScript的大浪潮不斷襲來,越來越多的Vue項目採用了TypeScript的語法來編寫代碼,而Vue3的JS中的Setup語法糖也越來越廣泛的使用,給我們這些以前用弱類型的JS語法編寫Vue代碼的人不少衝擊,不過隨著大量的學習和代碼編寫,經歷過一段難熬的時間後,逐步適應了這種... ...
  • 從屏幕上下左右滑入滑出效果,代碼比較粗糙,但是效果已實現 需要註意的是,從屏幕右邊和下邊滑入的時候,需要給滑動的容器外面再加一個容器,加樣式 position: fixed; 讓它 固定定位,否則頁面右邊和底部會出現滾動條 主要使用了 css animate 屬性 <!DOCTYPE html> < ...
  • 從排查一次匪夷所思的coredump,引出各種體系架構的差異。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 1 背景 從全世界有記載的第一臺電腦Z1 (computer) - Wikipedia在1936年發明,到1946年馮諾依曼體系架 ...
  • 多維數組 多維數組可以看成是數組的數組,比如二維數組就是一個特殊的一堆數組,其每一個元素都是一個一維數組 二維數組 ​ 首先看一下二維數組的定義: int arr[][]=new int[2][3] 上述定義的數組可以看成是一個2行3列的數組。 我們可以寫代碼來看一下關於二維數組的應用。 代碼示例: ...
  • 1. 線程簡介 程式:程式時指令和數據的有序集合,其本身沒有任何運行的含義,是一個靜態的概念 進程:執行程式的一次執行過程,或是正在運行的一個程式,是一個動態的過程。由它自身的產生、存在和消亡的過程 線程是由進程創建的,是進程的一個實體。通常在一個進程中可以包含若幹個線程,當然一個進程中至少有一個線 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...