我可以使用以下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
答案 0 :(得分:8)
您当前的代码存在三个问题:
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 Time或java.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.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
避免使用两个/三个/四个字母的缩写作为时区名称。使用约定的地区/城市,例如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 desugaring 和 How 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);