You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中获取非UTC时区(Asia/Kolkata)的月份起止时间问题

问题排查与解决方案

问题根源

你的代码核心错误出在时间戳转换步骤:

return Timestamp.valueOf(istDateTime.toLocalDateTime()).getTime();

istDateTime.toLocalDateTime()会剥离时区信息,得到印度时区的本地时间(比如2023-09-01T00:00),但Timestamp.valueOf()方法会将这个LocalDateTime视为JVM默认时区的时间来转换为时间戳。当机器时区是UTC时,它会把2023-09-01T00:00当成UTC时间处理,自然得到错误的时间戳。

修正后的代码

直接将ZonedDateTime转换为Instant(UTC时间戳的标准表示),再获取毫秒级时间戳,完全不受机器时区影响:

import java.time.*;

public class MonthTimestampUtil {
    public static Long getStartTimeStampOfMonth(Month month, Year year) {
        LocalDate startDate = LocalDate.of(year.getValue(), month, 1);
        LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
        ZonedDateTime istDateTime = startDateTime.atZone(ZoneId.of("Asia/Kolkata"));
        // 直接转换为Instant并获取时间戳
        return istDateTime.toInstant().toEpochMilli();
    }

    public static Long getEndTimeStampOfMonth(Month month, Year year) {
        LocalDate startDate = LocalDate.of(year.getValue(), month, 1);
        LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());
        LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
        ZonedDateTime istDateTime = endDateTime.atZone(ZoneId.of("Asia/Kolkata"));
        return istDateTime.toInstant().toEpochMilli();
    }
}

优化简化方案

使用YearMonth类可以更简洁地处理年月逻辑,避免手动计算月末日期:

import java.time.*;

public class MonthTimestampUtil {
    public static Long getStartTimeStampOfMonth(Month month, Year year) {
        YearMonth yearMonth = YearMonth.of(year.getValue(), month);
        // 直接生成印度时区的月初零时ZonedDateTime
        ZonedDateTime startZoned = yearMonth.atDay(1).atStartOfDay(ZoneId.of("Asia/Kolkata"));
        return startZoned.toInstant().toEpochMilli();
    }

    public static Long getEndTimeStampOfMonth(Month month, Year year) {
        YearMonth yearMonth = YearMonth.of(year.getValue(), month);
        // 获取月末日期并生成印度时区的最后一刻ZonedDateTime
        ZonedDateTime endZoned = yearMonth.atEndOfMonth().atTime(LocalTime.MAX).atZone(ZoneId.of("Asia/Kolkata"));
        return endZoned.toInstant().toEpochMilli();
    }
}

结果验证

  • 2023年9月起始时间(Asia/Kolkata 2023-09-01 00:00:00)对应的时间戳为1693506600000
  • 2023年9月结束时间(Asia/Kolkata 2023-09-30 23:59:59.999)对应的时间戳为1696098599999
    完全符合预期,且不受机器时区影响。

内容的提问来源于stack exchange,提问作者Sanjay Prajapat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:32:47