我原本希望打印 1970-01-01-00:00:00 ,但会打印 1970-12-31-19:00:00 < / p>
我怎么误解了Date的计算方式?这是一年假。我在带有JDK 1.6的Windows 7上运行它
System.out.println(new SimpleDateFormat("YYYY-MM-dd-HH:mm:ss").format(new Date(0)));
答案 0 :(得分:19)
我怎么误解了Date的计算方式?
new Date(0)
是1970年1月1日 UTC。您的时区不是UTC。
这是一年假。
不,不是。打印价值仅落后5个小时。让我猜一下 - 你在the eastern part of the US的某个地方?
答案 1 :(得分:19)
这不仅仅是时区 - 它使用时区和混合使用YYYY
表示周年而不是年(自Java 7起)。将其更改为yyyy
,您将看到1969年。
为WEEK_OF_YEAR字段计算的值范围为1到53.日历年的第一周是从getFirstDayOfWeek()开始的最早的七天时段,该时间段至少包含该年的getMinimalDaysInFirstWeek()天。因此,它取决于getMinimalDaysInFirstWeek(),getFirstDayOfWeek()和1月1日的星期几的值。一年的第1周和第二年的第1周之间的周(不包括)从2到52顺序编号或者53(参与Julian-Gregorian过渡的年份除外)。
在构造GregorianCalendar时,使用依赖于语言环境的资源初始化getFirstDayOfWeek()和getMinimalDaysInFirstWeek()值。当getFirstDayOfWeek()为MONDAY且getMinimalDaysInFirstWeek()为4时,周确定与ISO 8601标准兼容,这些值用于首选标准的语言环境中。可以通过调用setFirstDayOfWeek()和setMinimalDaysInFirstWeek()来显式设置这些值。
周年与WEEK_OF_YEAR周期同步。第一周和最后一周(包括)之间的所有周都具有相同的周年值。因此,一周中的第一天和最后一天可能具有不同的日历年值。
所以问题是1969年“正常年份”的最后一天实际上是1970年的“一周”。
你应该明确地使用yyyy
来避免混淆 - 一周相对很少有用,很容易引起混淆,正如我们所见:)
SimpleDateFormat
in 1.6没有提到它......也许你正在编译1.6但在7中运行?
答案 2 :(得分:9)
要总结关于YYYY
与yyyy
的正确答案以及时区处理,以下是产生预期输出的代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(0))); //1970-01-01-00:00:00
答案 3 :(得分:0)
答案 4 :(得分:0)
做* 1000L
System.out.println(new SimpleDateFormat("YYYY-MM-dd-HH:mm:ss").format(new Date(0) * 1000L));
答案 5 :(得分:0)
我建议您使用 java.time,现代 Java 日期和时间 API,用于您的日期和时间工作。在 Java 1.6 和 1.7 上,这是通过 java.time 向后移植到那些 Java 版本,称为 ThreeTen 后向移植(底部链接)发生的。
正如评论中所讨论的,您需要决定一个时区,以便将纪元之后的 0 毫秒解释为日期和时间。就像这样的评论一样,我选择 America/New_York 时区作为示例。插入你自己的。
我正在使用这些声明:
private static final ZoneId ZONE = ZoneId.of("America/New_York");
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("uuuu-MM-dd-HH:mm:ss", Locale.ROOT);
剩下的很简单(当您知道如何操作时):
String epochString = Instant.EPOCH.atZone(ZONE).format(FORMATTER);
System.out.println(epochString);
输出为:
<块引用>1969-12-31-19:00:00
如前所述,在 UTC 时间 1970 年 1 月 1 日,地球西半部(包括美洲和太平洋的大部分地区)仍然是 1969 年 12 月 31 日。
模式字母 uuuu
?使用 java.time,您可以使用 yyyy
表示时代(总是正数)或 uuuu
表示签名年份。通常建议使用后者,这样您就可以确保在您(无论预期与否)遇到共同时代之前一年的情况下看到差异。 Java 中的 uuuu
格式化模式代码中的 yyyy
与 DateTimeFormatter
问题? 链接到下面广泛涵盖了差异。
java.time 至少需要 Java 6。
org.threeten.bp
导入日期和时间类。java.time
。java.time
向后移植到 Java 6 和 7(JSR-310 的 ThreeTen)。uuuu
versus yyyy
in DateTimeFormatter
formatting pattern codes in Java?