[轉][Java] Date 的替代品 Instant

來自:https://mp.weixin.qq.com/s/SotzqrKAfrND88n12QFCEA

怎麼改?

只能說這種基礎的類改起來牽一髮動全身,需要從DO實體類看起,然後就是各種Converter,最後是DTO。由於我們還是微服務架構,業務服務依賴於基礎服務的API,所以必須要一起改否則就會報錯。這裏就不細說修改流程了,主要說一下我們在改造的時候遇到的一些問題。

1. 耐心比對數據庫日期字段和DO的映射

1)確定字段類型

首先你需要確定數據對象中的 Date 字段代表的是日期、時間還是時間戳。

  • 如果字段代表日期和時間,則可能需要使用 LocalDateTime。
  • 如果字段僅代表日期,則可能需要使用 LocalDate。
  • 如果字段僅代表時間,則可能需要使用 LocalTime。
  • 如果字段需要保存時間戳(帶時區的),則可能需要使用 Instant 或 ZonedDateTime。
2)更新數據對象類

更新數據對象類中的字段,把 Date 類型改爲適當的 java.time 類型。

2. 將DateUtil中的方法改造

1)替換原來的new Date()和Calendar.getInstance().getTime()

原來的方式:

Date nowDate = new Date();
Date nowCalendarDate = Calendar.getInstance().getTime();

使用 java.time 改造後:

// 使用Instant代表一個時間點,這與Date類似
Instant nowInstant = Instant.now();

// 如果需要用到具體的日期和時間(例如年、月、日、時、分、秒)
LocalDateTime nowLocalDateTime = LocalDateTime.now();

// 如果你需要和特定的時區交互,可以使用ZonedDateTime
ZonedDateTime nowZonedDateTime = ZonedDateTime.now();

// 如果你需要轉換回java.util.Date,你可以這樣做(假設你的代碼其他部分還需要使用Date)
Date nowFromDateInstant = Date.from(nowInstant);

// 如果需要與java.sql.Timestamp交互
java.sql.Timestamp nowFromInstant = java.sql.Timestamp.from(nowInstant);
一些注意點:
  • Instant 表示的是一個時間點,它是時區無關的,相當於舊的 Date 類。它通常用於表示時間戳。
  • LocalDateTime 表示沒有時區信息的日期和時間,它不能直接轉換爲時間戳,除非你將其與時區結合使用(例如通過 ZonedDateTime)。
  • ZonedDateTime 包含時區信息的日期和時間,它更類似於 Calendar,因爲 Calendar 也包含時區信息。
  • 當你需要將 java.time 對象轉換回 java.util.Date 對象時,可以使用 Date.from(Instant) 方法。這在你的代碼需要與舊的API或庫交互時非常有用。
2)一些基礎的方法改造

a. dateFormat原來的方式

public static String dateFormat(Date date, String dateFormat) {
    SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
    return formatter.format(date);
}

使用java.time改造後

public static String dateFormat(LocalDateTime date, String dateFormat) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
    return date.format(formatter);
}

b. addSecond、addMinute、addHour、addDay、addMonth、addYear原來的方式

public static Date addSecond(Date date, int second) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(13, second);
    return calendar.getTime();
}

public static Date addMinute(Date date, int minute) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(12, minute);
    return calendar.getTime();
}

public static Date addHour(Date date, int hour) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(10, hour);
    return calendar.getTime();
}

public static Date addDay(Date date, int day) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(5, day);
    return calendar.getTime();
}

public static Date addMonth(Date date, int month) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(2, month);
    return calendar.getTime();
}

public static Date addYear(Date date, int year) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(1, year);
    return calendar.getTime();
}

使用java.time改造後

public static LocalDateTime addSecond(LocalDateTime date, int second) {
    return date.plusSeconds(second);
}

public static LocalDateTime addMinute(LocalDateTime date, int minute) {
    return date.plusMinutes(minute);
}

public static LocalDateTime addHour(LocalDateTime date, int hour) {
    return date.plusHours(hour);
}

public static LocalDateTime addDay(LocalDateTime date, int day) {
    return date.plusDays(day);
}

public static LocalDateTime addMonth(LocalDateTime date, int month) {
    return date.plusMonths(month);
}

public static LocalDateTime addYear(LocalDateTime date, int year) {
    return date.plusYears(year);
}

c. dateToWeek原來的方式

public static final String[] WEEK_DAY_OF_CHINESE = new String[]{"週日", "週一", "週二", "週三", "週四", "週五", "週六"};
public static String dateToWeek(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return WEEK_DAY_OF_CHINESE[cal.get(7) - 1];
}

使用java.time改造後

public static final String[] WEEK_DAY_OF_CHINESE = new String[]{"週日", "週一", "週二", "週三", "週四", "週五", "週六"};

public static String dateToWeek(LocalDate date) {
    DayOfWeek dayOfWeek = date.getDayOfWeek();
    return WEEK_DAY_OF_CHINESE[dayOfWeek.getValue() % 7];
}

d. getStartOfDay和getEndOfDay原來的方式

public static Date getStartTimeOfDay(Date date) {
    if (date == null) {
        return null;
    } else {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }
}

public static Date getEndTimeOfDay(Date date) {
    if (date == null) {
        return null;
    } else {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }
}

使用java.time改造後

public static LocalDateTime getStartTimeOfDay(LocalDateTime date) {
    if (date == null) {
        return null;
    } else {
        // 獲取一天的開始時間,即00:00
        return date.toLocalDate().atStartOfDay();
    }
}

public static LocalDateTime getEndTimeOfDay(LocalDateTime date) {
    if (date == null) {
        return null;
    } else {
        // 獲取一天的結束時間,即23:59:59.999999999
        return date.toLocalDate().atTime(LocalTime.MAX);
    }
}

e. betweenStartAndEnd原來的方式

public static Boolean betweenStartAndEnd(Date nowTime, Date beginTime, Date endTime) {
    Calendar date = Calendar.getInstance();
    date.setTime(nowTime);
    Calendar begin = Calendar.getInstance();
    begin.setTime(beginTime);
    Calendar end = Calendar.getInstance();
    end.setTime(endTime);
    return date.after(begin) && date.before(end);
}

使用java.time改造後

public static Boolean betweenStartAndEnd(Instant nowTime, Instant beginTime, Instant endTime) {
    return nowTime.isAfter(beginTime) && nowTime.isBefore(endTime);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章