首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 判斷用戶登錄是否過期:時間比較最佳實踐

     編輯:程式設計綜合問答

需求描述

用戶最後登錄時間 `lastLoginTime` (Date 類型),有效期 7 天。需判斷當前時間是否超過 `lastLoginTime + 7天`,超過則視為過期(自動登出/刪除)。前端使用 ExtJS。

核心邏輯:時間戳毫秒數比較


// 推薦:使用長整型毫秒數比較,避免 Date 格式化解析開銷與時區陷阱
long now = System.currentTimeMillis();                    // 當前毫秒數
long lastLogin = user.getLastLoginTime().getTime();       // 最後登錄毫秒數
long expireTime = lastLogin + 7L * 24 * 60 * 60 * 1000;   // 過期時間點 (毫秒)

if (now >= expireTime) {
    // 用戶過期:執行登出、刪除、標記等業務邏輯
    result.put("result", false);
    result.put("message", "用戶過期!");
} else {
    long remainingDays = (expireTime - now) / (24 * 60 * 60 * 1000);
    // 可選:返回剩餘天數供前端提示
}

方案對比

用戶原始代碼問題分析

SimpleDateFormat sdf = new SimpleDateFormat("03/08/2015 00:00:00 "); // 格式化模板寫死為具體日期!
String outlogin = sdf.format(new Date()); // 格式化當前時間為 "03/08/2015 ..."
if(................){ ... }
  • **模板寫死**:`"03/08/2015 00:00:00 "` 不是模板,是固定字符串,`format` 會忽略模板字段直接輸出字面量。
  • **字符串比較**:無法直接比較大小,需解析回 Date/Long。
  • **時區風險**:`SimpleDateFormat` 默認使用 JVM 時區,服務器/客戶端時區不一致會導致判斷偏差。

ExtJS 前端配合

  • 後端返回 JSON:`{ success: true, expired: false, remainingDays: 3 }` 或 `{ success: false, message: "用戶過期!" }`。
  • 前端攔截器:`Ext.Ajax.on('requestcomplete', ...)` 或全局 `Ext.util.Observable` 監聽 `expired: true`,自動跳轉登錄頁、清理本地存儲。
  • 心跳機制:前端定時輪詢 `/api/heartbeat`,後端檢查過期並返回狀態,實現「掉線即過期」。

最佳實踐總結

  1. **存儲統一用 UTC 毫秒數** (Long/BIGINT),DB 字段 `BIGINT` 或 `TIMESTAMP` (UTC)。
  2. **業務計算全程用 Long 毫秒數**,避免 Date/Calendar 可變性陷阱。
  3. **Java 8+ 項目強制遷移到 `java.time`** (`Instant`, `Duration`, `Period`, `ZonedDateTime`)。
  4. **前端不做時間計算**,只顯示後端返回的剩餘時間/過期狀態。
  5. **定時清理任務**:獨立排程任務 (Quartz/XXL-JOB) 批量掃描過期用戶執行刪除/歸檔,而非依賴用戶訪問觸發。

最佳回答給出偽代碼核心邏輯:`nowtime - lasttime` 比較毫秒差,轉換天數。雖用 `SimpleDateFormat` 解析 DB 時間略繞彎,但毫秒數比較思路正確。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案代碼片段優點缺點
毫秒數比較 (推薦)`System.currentTimeMillis()` + `date.getTime()`性能最高、無時區歧義、無格式化開銷、邏輯最清晰無
Date.after/before`new Date().after(expireDate)`面向對象、可讀性好需先構造 expireDate 對象、內部仍轉毫秒數
Calendar 加減`cal.add(Calendar.DAY, 7); now.after(cal.getTime())`支持複雜日曆運算 (如工作日)API 繁瑣、mutable 易出錯
Java 8 java.time (現代)`Instant.now().isAfter(lastLogin.toInstant().plusSeconds(7*24*3600))`不可變、線程安全、功能豐富、標準化需 Java 8+、舊項目遷移成本
字符串格式化比較 (反模式)`SimpleDateFormat` 格式化後字符串比較無性能差、格式敏感、時區陷阱、邏輯錯誤高發