Java - 毫秒到月/年(不仅仅是当前时间)

时间:2014-05-05 15:29:08

标签: java calendar milliseconds

假设我在Java中有一个算法,我希望每月根据与每个对象相关的时间做一些事情。

例如,如果Object a有时间long t,而t自纪元以来以毫秒为单位,我怎么知道t是03年的时间/ 2014?

作为第二个问题,我如何能够在几个月内倒退 - 所以如果我从2014年5月1日开始,我怎样才能准确地回到4月,3月,2月等,而不用担心整个问题一个月有28-31天?我正在考虑使用Calendar类,但我不确定是否可以更新MONTH变量并让它给我一个正确的毫秒值。比如,如果它是3月31日,我将这个月更新到2月,然后它突然认为它是2月31日?

4 个答案:

答案 0 :(得分:2)

最简单的方法是使用您在问题中提到的java.util.Calendar类。您可以使用

轻松获取实例
//use whatever time zone your milliseconds originiate from
//there is another getter that takes a Locale, which may be useful depending on your context
Calander c = Calendar.getInstance(TimeZone.getDefault());

然后您可以使用

设置时间
c.setTimeInMillis(t);

为了找出这是什么时候,您可以使用DateFormat对象打印出结果

DateFormat df = DateFormat.getInstance(DateFormat.SHORT);
System.out.println(df.format(c.getTime());

要浏览月份(或任何其他时间单位),您可以使用月份字段“添加”到日历中:

c.add(Calendar.MONTH, -2);

好消息是,您可以将add()方法用于任何其他时间单位,Calendar课程将按照您的预期方式(根据需要)正确调整日期。由Locale的{​​{1}}定义的文化上适当的方式。

最后,您可以使用

将其恢复为毫秒
Calendar

答案 1 :(得分:1)

我认为您的第一个问题已在此处java convert milliseconds to time format

得到解答

您只需要创建一个新的Date对象并将时间戳传递给构造函数。然后,您可以根据需要格式化日期。

答案 2 :(得分:0)

java.time中使用Java 8 API,您可以执行以下操作:

import java.time.Instant;
import java.time.Month;
import java.time.MonthDay;
import java.time.OffsetDateTime;

public static void main(String[] args) {
    long ms_since_epoch = 1_500_000_000_000L;
    Instant instant = Instant.ofEpochMilli(ms_since_epoch);

    // convert milliseconds in UTC to date
    OffsetDateTime dateUTC = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);

    // convert milliseconds in EST (UTC-0500) to date
    OffsetDateTime dateEST = OffsetDateTime.ofInstant(instant, ZoneOffset.ofHours(-5));
    // note: this is 2017-07-14 at 2:40

    // create a MonthDay from the date in EST
    MonthDay monthDay = MonthDay.of(dateEST.getMonth(), dateEST.getDayOfMonth());
    // note: this is 2017-07-13 at 21:40

    // loop over the next six months, after monthDay from dateEST
    MonthDay md = monthDay;
    for (int i = 0; i < 6; ++i) {
        md = md.with(md.getMonth().plus(1));
        System.out.println(md);
        // prints 08-13 through 01-14 (August 2013 through January 2014)
    }

    // loop over the previous six months, including this month
    md = monthDay;
    for (int i = 0; i < 6; ++i) {
        System.out.println(md);
        md = md.with(md.getMonth().minus(1));
        // prints 07-13 through 02-13 (July 2013 through February 2013)
    }
}

请注意,MonthDay是不可变的,因此调用md.with(otherMonth)会返回一个月更改的新实例,它只代表一个月和一天,而不是包含年,时间和时区的完整日期。另请注意,转换时间戳的方式会产生不同的日期和时间,具体取决于时区,Calendar也是如此。

答案 3 :(得分:0)

哪个纪元?哪个时区?

你的问题忽略了关键问题:

  • epoch以来的毫秒数?有many epochs。在所有3个常见的基于Java的库(java.util.Date/Calendar,Joda-Time,java.time)中,纪元是1970年UTC中的第一个时刻(忽略闰秒)。
  • 以毫秒为单位表示什么时区? UTC或某个当地时区?

约达时间

以下是使用Joda-Time 2.3库的示例代码。

生成几毫秒。请注意使用long而不是int

long millis = new DateTime( 2014, 1, 2, 3, 4, 5, DateTimeZone.UTC ).getMillis();

通过将毫秒传递给构造函数来实例化DateTime。指定解释这些毫秒的时区。

DateTime dateTime = new DateTime( millis, DateTimeZone.UTC );

定义一个月的开头和结尾。 Interval类表示诸如此类的时间跨度。

DateTime firstOfMarchInParis = new DateTime( 2014, 3, 1, 0, 0, 0 , DateTimeZone.forID( "Europe/Paris" ) ).withTimeAtStartOfDay();
Interval marchInParis = new Interval( firstOfMarchInParis, firstOfMarchInParis.plusMonths( 1) );

比较最好通过使用&#34;半开放&#34;在日期时间工作中进行。做法。 &#34;半开放&#34;是一个数学术语,意思是开头是包容性的,结尾是排他性的。因此,从3月1日的第一个时刻开始,上面的时间间隔被定义为“#strong”,但不包括,即下个月的第一个时刻&#34;。 Joda-Time使用这个&#34;半开放&#34;方法

boolean isTargetInMarchInParis = marchInParis.contains( dateTime );

关于添加/减去月数的第二个问题,请注意Joda-Time DateTime方法plusMonthsminusMonths会给出您想要的行为。