【问题标题】:Timestamps of start and end of month in javajava中开始和结束的时间戳
【发布时间】:2014-05-08 09:11:23
【问题描述】:

我想要一个程序,其中我给出月份和年份,并且程序应该返回月份的开始和结束时间戳。

例如,如果我将 2011 年 1 月和 2011 年传递给它将返回的方法 开始=1293840000 结束 = 1296518400

有没有办法做到这一点。

【问题讨论】:

  • 你想要什么时区?还是没有时区偏移 (UTC)?

标签: java datetime unix-timestamp java-time


【解决方案1】:

乔达时间

使用Joda-Time 库,这种工作要容易得多。

时区

您应该指定一个时区,而不是依赖 JVM/主机的默认值。似乎您想要 UTC(无时区偏移),因此您的代码应该明确说明。

半开

此外,在一天的最后一刻度过难关。理论上,在第二天开始之前总会有另一个可整除的秒数。当您想要解析为秒(Unix 项)时,两个常见的 Java 库(java.util.Date/.Calendar 和 Joda-Time)使用毫秒,而 Java 8 中的新 java.time 库解析为纳秒。相反,日期时间工作通常使用“半开放”方法完成,其中定义时间跨度,开始是包含,结束是独占 .所以“一月”从first moment of January 1 运行到first moment of February 1

示例

这是 Joda-Time 2.3 中的一些示例代码。

DateTimeZone timeZone = DateTimeZone.UTC;
DateTime start = new DateTime( 2011, DateTimeConstants.JANUARY, 1, 0, 0, 0, timeZone).withTimeAtStartOfDay();
DateTime stop = start.plusMonths( 1 );

您可能会发现 Interval 类对相关工作很感兴趣。

Interval january2011 = new Interval( start, stop ); 

从毫秒转换为秒。

long secondsStart = start.getMillis()/1000L;
long secondsStop = stop.getMillis()/1000L;

【讨论】:

    【解决方案2】:

    你可以这样做

    long startDate;
    long endDate;
    
    private void calculateMonthStartAndEndTime(int month, int year){
    //create the first date of month
    Calendar mycal = new GregorianCalendar(year,month, 1);
    startDate = mycal.getTimeInMillis();
    
    // Get the number of days in that month which actually gives the last date.
    int lastDate = mycal.getActualMaximum(Calendar.DAY_OF_MONTH);
    mycal = new GregorianCalendar(year, month, lastDate);
    endDate = mycal.getTimeInMillis();
    }
    

    【讨论】:

    • 与 OP 的示例相比,这有一个“out by one”错误。最好只增加一个月,而不是使用getActualMaximum
    • 而且还差一个(也就是说,它给出了 30 天的间隔,而不是 1 月的 31 天);它没有正确考虑时区,因此除非您的时区是 UTC,否则即使在月初,您也不会得到与 OP 示例相同的答案。
    • 这个答案忽略了时区的问题。您的结果会因计算机而异,甚至在更改时区设置的情况下在一台计算机上也会有所不同,或者即使在一个 JVM 中,默认时区也会被任何其他正在运行的 Java 代码重置。
    【解决方案3】:
    【解决方案4】:

    使用 Java 8 答案更新

    (Java 8 包含一个基于 JodaTime 的新时间库):

        ZoneId timeZone = ZoneId.of("US/Eastern");
        //ZoneId timeZone = ZoneOffset.UTC;
    
        LocalDate march1985 = LocalDate.of(2017, Month.MARCH, 1);
        long beginningOfMarch = march1985.atStartOfDay(timeZone)
                .toInstant()
                .toEpochMilli();
    
        LocalDate april1985 = march1985.plus(1, ChronoUnit.MONTHS);
        long endOfMarch = april1985.atStartOfDay(timeZone)
                .toInstant()
                .toEpochMilli();
    

    时区

    “月初”是时区的函数,所以在这种情况下,我已经展示了如何在东部时间进行。这些 java.time 类自动处理 DST,因此,例如,如果您使用 2017 年而不是 1985 年,您会发现差异是 743 小时而不是 744 小时,因为 1985 年发生了 DST四月。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 2012-10-29
      • 2020-02-22
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多