欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java日期格式化如何避免YYYY引發(fā)的時(shí)間異常

 更新時(shí)間:2023年11月16日 10:31:15   作者:myprince003  
在編程中,日期格式化是一個(gè)常見(jiàn)的任務(wù),使用不同的格式化選項(xiàng)可能會(huì)導(dǎo)致一些意外的結(jié)果,下面我們就來(lái)學(xué)習(xí)一下Java如何避免YYYY引發(fā)的時(shí)間異常吧

在編程中,日期格式化是一個(gè)常見(jiàn)的任務(wù)。使用不同的格式化選項(xiàng)可能會(huì)導(dǎo)致一些意外的結(jié)果。最近遇到一個(gè)問(wèn)題,就是使用YYYY格式化選項(xiàng)會(huì)導(dǎo)致時(shí)間異常。

public static void main(String[] args) throws ParseException {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdf2 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
   
    String time = "2023-12-31 23:59:59";
    System.out.printf("yyyy-MM-dd HH:mm:ss: %s\n",sdf.format(sdf.parse(time)));
    System.out.printf("YYYY-MM-dd HH:mm:ss: %s\n",sdf2.format(sdf2.parse(time)));

    System.out.println("======================================");
    String time2 = "2023-11-31 23:59:59"; //11月沒(méi)有31號(hào)
    System.out.printf("yyyy-MM-dd HH:mm:ss: %s\n",sdf.format(sdf.parse(time2)));
    System.out.printf("YYYY-MM-dd HH:mm:ss: %s\n",sdf2.format(sdf2.parse(time2)));

    System.out.println("======================================");
    String time3 = "2023-10-31 23:59:59";
    System.out.printf("yyyy-MM-dd HH:mm:ss: %s\n",sdf.format(sdf.parse(time3)));
    System.out.printf("YYYY-MM-dd HH:mm:ss: %s\n",sdf2.format(sdf2.parse(time3)));
}

輸出結(jié)果

yyyy-MM-dd HH:mm:ss: 2023-12-31 23:59:59
YYYY-MM-dd HH:mm:ss: 2023-01-01 23:59:59
======================================
yyyy-MM-dd HH:mm:ss: 2023-12-01 23:59:59
YYYY-MM-dd HH:mm:ss: 2023-01-01 23:59:59
======================================
yyyy-MM-dd HH:mm:ss: 2023-10-31 23:59:59
YYYY-MM-dd HH:mm:ss: 2023-01-01 23:59:59

網(wǎng)上查閱說(shuō)大寫(xiě)的YYYY表示一個(gè)基于周的年份,它是根據(jù)周計(jì)算的年份,而不是基于日歷的年份。通常情況下,兩者的結(jié)果是相同的,但在跨年的第一周或最后一周可能會(huì)有差異。但這里發(fā)現(xiàn)無(wú)論怎么調(diào)整時(shí)間,YYYY-MM-dd HH:mm:ss格式化后一直是2023-01-01 23:59:59,不僅僅是在跨年的時(shí)候出現(xiàn)問(wèn)題,具體原因尚不清楚

如何避免

定義通用的格式類,所有使用日期格式的地方都引用這個(gè)類,這個(gè)類中就定義好yyyy-MM-dd格式即可,這樣就不會(huì)出現(xiàn)有人手誤給大家埋雷了。

public class LocalDateUtils {

    /**
     * 顯示年月日時(shí)分秒,例如 2023-10-31 09:51:53.
     */
    public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 僅顯示年月日,例如 2023-10-31.
     */
    public static final String DATE_PATTERN = "yyyy-MM-dd";

    private static final String YEAR = "year";
    private static final String MONTH = "month";
    private static final String WEEK = "week";
    private static final String DAY = "day";

    /**
     * 將日期轉(zhuǎn)換為字符串,格式為:yyyy-MM-dd HH:mm:ss
     */
    public static String getLocalDateTimeStr(LocalDateTime localDateTime) {
        return format(localDateTime, DATETIME_PATTERN);
    }

    /**
     * 將日期轉(zhuǎn)換為字符串,格式為:yyyy-MM-dd
     */
    public static String getLocalDateStr(LocalDateTime localDateTime) {
        return format(localDateTime, DATE_PATTERN);
    }


    /**
     * 將字符串轉(zhuǎn)換為日期,格式為:yyyy-MM-dd HH:mm:ss
     */
    public static LocalDateTime parseLocalDateTime(String localDateTimeStr) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATETIME_PATTERN);
        return LocalDateTime.parse(localDateTimeStr, dateTimeFormatter);
    }

    /**
     * 將字符串轉(zhuǎn)換為日期,格式為:yyyy-MM-dd
     */
    public static LocalDate parseLocalDate(String localDateStr) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
        return LocalDate.parse(localDateStr, dateTimeFormatter);
    }


    /**
     * 將字符串轉(zhuǎn)日期成Long類型的時(shí)間戳
     */
    public static Long convertLocalDateTimeToLong(String time) {
        LocalDateTime parse = parse(time, DATETIME_PATTERN);
        return LocalDateTime.from(parse).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 將字符串轉(zhuǎn)日期成Long類型的時(shí)間戳
     */
    public static Long convertLocalDateToLong(String time) {
        LocalDateTime parse = parse(time, DATE_PATTERN);
        return LocalDateTime.from(parse).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    public static LocalDateTime parse(String time, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(time, dateTimeFormatter);
    }


    /**
     * 將Long類型的時(shí)間戳轉(zhuǎn)換成String 類型的時(shí)間格式
     */
    public static String getLocalDateTimeStr(Long time) {
        return format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()), DATETIME_PATTERN);
    }

    /**
     * 將Long類型的時(shí)間戳轉(zhuǎn)換成String 類型的時(shí)間格式,時(shí)間格式為:yyyy-MM-dd
     */
    public static String getLocalDateStr(Long time) {
        return format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()), DATE_PATTERN);
    }

    /**
     * 獲取日期時(shí)間字符串
     */
    public static String format(TemporalAccessor temporal, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return dateTimeFormatter.format(temporal);
    }


    /**
     * 取本月第一天
     */
    public static LocalDate firstDayOfThisMonth() {
        LocalDate today = LocalDate.now();
        return today.with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 取本月第N天
     */
    public static LocalDate dayOfThisMonth(int n) {
        LocalDate today = LocalDate.now();
        return today.withDayOfMonth(n);
    }

    /**
     * 取本月最后一天
     */
    public static LocalDate lastDayOfThisMonth() {
        LocalDate today = LocalDate.now();
        return today.with(TemporalAdjusters.lastDayOfMonth());
    }


    /**
     * 獲取指定日期時(shí)間加上指定數(shù)量日期時(shí)間單位之后的日期時(shí)間.
     */
    public static LocalDateTime plus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.plus(num, chronoUnit);
    }

    /**
     * 獲取指定日期時(shí)間減去指定數(shù)量日期時(shí)間單位之后的日期時(shí)間.
     */
    public static LocalDateTime minus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.minus(num, chronoUnit);
    }

    /**
     * 根據(jù)ChronoUnit計(jì)算兩個(gè)日期時(shí)間之間相隔日期時(shí)間
     */
    public static long getChronoUnitBetween(LocalDateTime start, LocalDateTime end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }

    /**
     * 根據(jù)ChronoUnit計(jì)算兩個(gè)日期之間相隔年數(shù)或月數(shù)或天數(shù)
     */
    public static long getChronoUnitBetween(LocalDate start, LocalDate end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }


    /**
     * 切割日期。按照周期切割成小段日期段。例如: <br>
     *
     * @param startDate 開(kāi)始日期(yyyy-MM-dd)
     * @param endDate   結(jié)束日期(yyyy-MM-dd)
     * @param period    周期(天,周,月,年)
     * @return 切割之后的日期集合
     * <li>startDate="2023-10-27",endDate="2023-10-31",period="day"</li>
     * <li>結(jié)果為:[2023-10-27, 2023-10-28, 2023-10-29, 2023-10-03,2023-10-31]</li><br>
     * <li>startDate="2023-10-27",endDate="2023-10-31",period="week"</li>
     * <li>結(jié)果為:[2023-10-27,2023-10-31]</li><br>
     * <li>startDate="2023-10-27",endDate="2023-10-31",period="month"</li>
     * <li>結(jié)果為:[2023-10-27,2023-10-31]</li><br>
     * <li>startDate="2023-10-27",endDate="2023-10-31",period="year"</li>
     * <li>結(jié)果為:[2023-10-27,2023-10-31]</li><br>
     */
    public static List<String> listDateStrs(String startDate, String endDate, String period) {
        List<String> result = new ArrayList<>();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
        LocalDate end = LocalDate.parse(endDate, dateTimeFormatter);
        LocalDate start = LocalDate.parse(startDate, dateTimeFormatter);
        LocalDate tmp = start;
        switch (period) {
            case DAY:
                while (start.isBefore(end) || start.isEqual(end)) {
                    result.add(start.toString());
                    start = start.plusDays(1);
                }
                break;
            case WEEK:
                while (tmp.isBefore(end) || tmp.isEqual(end)) {
                    if (tmp.plusDays(6).isAfter(end)) {
                        result.add(tmp.toString() + "," + end);
                    } else {
                        result.add(tmp.toString() + "," + tmp.plusDays(6));
                    }
                    tmp = tmp.plusDays(7);
                }
                break;
            case MONTH:
                while (tmp.isBefore(end) || tmp.isEqual(end)) {
                    LocalDate lastDayOfMonth = tmp.with(TemporalAdjusters.lastDayOfMonth());
                    if (lastDayOfMonth.isAfter(end)) {
                        result.add(tmp.toString() + "," + end);
                    } else {
                        result.add(tmp.toString() + "," + lastDayOfMonth);
                    }
                    tmp = lastDayOfMonth.plusDays(1);
                }
                break;
            case YEAR:
                while (tmp.isBefore(end) || tmp.isEqual(end)) {
                    LocalDate lastDayOfYear = tmp.with(TemporalAdjusters.lastDayOfYear());
                    if (lastDayOfYear.isAfter(end)) {
                        result.add(tmp.toString() + "," + end);
                    } else {
                        result.add(tmp.toString() + "," + lastDayOfYear);
                    }
                    tmp = lastDayOfYear.plusDays(1);
                }
                break;
            default:
                break;
        }
        return result;
    }
}

以上就是Java日期格式化如何避免YYYY引發(fā)的時(shí)間異常的詳細(xì)內(nèi)容,更多關(guān)于Java日期格式化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring AOP使用@Aspect注解 面向切面實(shí)現(xiàn)日志橫切的操作

    Spring AOP使用@Aspect注解 面向切面實(shí)現(xiàn)日志橫切的操作

    這篇文章主要介紹了Spring AOP使用@Aspect注解 面向切面實(shí)現(xiàn)日志橫切的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java注解如何基于Redission實(shí)現(xiàn)分布式鎖

    Java注解如何基于Redission實(shí)現(xiàn)分布式鎖

    這篇文章主要介紹了Java注解如何基于Redission實(shí)現(xiàn)分布式鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 查看Java所支持的語(yǔ)言及相應(yīng)的版本信息

    查看Java所支持的語(yǔ)言及相應(yīng)的版本信息

    Java語(yǔ)言作為第一種支持國(guó)際化的語(yǔ)言,在Internet從一開(kāi)始就具有其他語(yǔ)言無(wú)與倫比的國(guó)際化的本質(zhì)特性,查看Java所支持的語(yǔ)言及相應(yīng)的版本信息可以采用以下代碼進(jìn)行查詢
    2014-01-01
  • java截取圖片示例

    java截取圖片示例

    這篇文章主要介紹了java截取圖片示例,把代碼中的圖片路徑改成自己的圖片,運(yùn)行就可以看到效果了,需要的朋友可以參考下
    2014-03-03
  • Spring(一):IOC如何推導(dǎo)和理解

    Spring(一):IOC如何推導(dǎo)和理解

    下面小編就為大家?guī)?lái)一篇詳談Spring對(duì)IOC的理解(推薦篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-07-07
  • Springboot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)代碼實(shí)例

    Springboot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)代碼實(shí)例

    這篇文章主要介紹了Springboot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)代碼實(shí)例,任務(wù)是有可能并發(fā)執(zhí)行的,若Scheduler直接使用Job,就會(huì)存在對(duì)同一個(gè)Job實(shí)例并發(fā)訪問(wèn)的問(wèn)題,而JobDetail?&?Job方式,Scheduler都會(huì)根據(jù)JobDetail創(chuàng)建一個(gè)新的Job實(shí)例,這樣就可以規(guī)避并發(fā)訪問(wèn)問(wèn)題
    2023-09-09
  • java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能詳解

    java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能詳解

    這篇文章主要介紹了java基于Des對(duì)稱加密算法實(shí)現(xiàn)的加密與解密功能,結(jié)合實(shí)例形式詳細(xì)分析了Des加密算法的功能、原理、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-01-01
  • Java開(kāi)發(fā)環(huán)境配置教程(win7 64bit)

    Java開(kāi)發(fā)環(huán)境配置教程(win7 64bit)

    這篇文章主要為大家詳細(xì)介紹了win7 64bit下Java開(kāi)發(fā)環(huán)境的配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • SpringBoot3.4.0無(wú)法找到StringRedisTemplate?bean的問(wèn)題Consider?defining?a?bean?of?type?‘org.springframework

    SpringBoot3.4.0無(wú)法找到StringRedisTemplate?bean的問(wèn)題Consider?def

    本文主要介紹了SpringBoot3.4.0無(wú)法找到StringRedisTemplate?bean的問(wèn)題Consider?defining?a?bean?of?type?‘org.springframework,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • mybatis和mybatis-plus同時(shí)使用的坑

    mybatis和mybatis-plus同時(shí)使用的坑

    本文主要介紹了mybatis和mybatis-plus同時(shí)使用的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評(píng)論