如何用Ruby计算毫秒的毫秒数?

时间:2014-08-22 08:47:38

标签: java ruby date milliseconds gregorian-calendar

我可以使用以下Ruby片段计算时间(以毫秒为单位):

$ irb
> require 'date'
 => true 
> Date.new(2014,9,5).to_time
 => 2014-09-05 00:00:00 +0200
> Date.new(2014,9,5).to_time.to_i * 1000
 => 1409868000000

1409868000000是理想的结果 如何用Java获得相同的结果?我将时区设置为CEST,因为它似乎与Ruby一起工作。所以我尝试了这个:

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("CEST"));
calendar.set(2014, 9, 5);
System.out.println("" + calendar.getTimeInMillis());
// Returns: 1412498241422

4 个答案:

答案 0 :(得分:8)

您当前的代码存在三个问题:

  • " CEST"不是Java认可的时区。请改为Europe/Paris,作为欧洲时区
  • java.util.Calendar使用0个月(是的,它很可怕)
  • 您尚未清除Calendar的时间部分,因此它会在当天为您提供当天的当前时间

这有效:

import java.util.*;

public class Test {
    public static void main(String[] args) throws Exception {
        TimeZone zone = TimeZone.getTimeZone("Europe/Paris");
        Calendar calendar = new GregorianCalendar(zone);
        // Month 8 = September in 0-based month numbering
        calendar.set(2014, 8, 5, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        System.out.println(calendar.getTimeInMillis());
    }
}

如果您提前知道月份,则可以改为使用常量:

calendar.set(2014, Calendar.SEPTEMBER, 5, 0, 0, 0);

但是,如果您可以转而使用Java 8中的Joda Timejava.time,则这些API会更清晰。

例如,在Joda Time:

import org.joda.time.*;

class Test {
    public static void main(String[] args) {
        DateTimeZone zone = DateTimeZone.forID("Europe/Paris");
        // Look ma, a sensible month numbering system!
        LocalDate date = new LocalDate(2014, 9, 5);
        DateTime zoned = date.toDateTimeAtStartOfDay(zone);
        System.out.println(zoned.getMillis());
    }
}

答案 1 :(得分:2)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并改用 2014 年 3 月发布的 modern Date-Time API*

此外,下面引用的是 Home Page of Joda-Time 处的通知:

<块引用>

请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。

使用 java.time(现代日期时间 API)的解决方案:

import java.time.LocalDate;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {    

        long millis = LocalDate.of(2014, 9, 5)
                                .atStartOfDay(ZoneId.of("Europe/Paris"))
                                .toInstant()
                                .toEpochMilli();
        
        System.out.println(millis);
    }
}

输出:

1409868000000

ONLINE DEMO

避免使用两个/三个/四个字母的缩写作为时区名称。使用约定的地区/城市,例如Europe/Paris。您可以使用 ZoneId.getAvailableZoneIds() 获取时区名称列表。

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 2 :(得分:0)

您可以使用System.currentTimeMillis()来获取自纪元开始以来的毫秒时间。

如果要转换为与Ruby使用的基线相同的基线,那么就像添加一些固定偏移一样简单(即使用System.currentTimeMillis() + DELTA)。您应该能够通过在某个固定日期在Ruby和Java中尝试来计算DELTA以查看其中的差异。

你确定Ruby的计​​算不依赖于语言环境吗?如果它经常使用CEST,那将是奇怪的(更不用说几乎可信)。

答案 3 :(得分:0)

calendar.set(2014, 8, 5, 0, 0, 0);
System.out.println("" + (calendar.getTimeInMillis() / 1000) * 1000);

请参阅http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#set(int,%20int,%20int,%20int,%20int)