从毫秒返回1970年1月的日期时失去一小时

Mea*_*ell 4 java date milliseconds date-formatting

我有以下代码,它采用一个毫秒的字符串(将来自RSS源,因此将是一个字符串,下面的示例是一个快速测试程序)并将这些毫米转换为Date对象.

public static void main(String[] args) {
    String ms = "1302805253";
    SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(Long.parseLong(ms));

    try {
        String dateFormat = dateFormatter.format(calendar.getTime());
        System.out.println("Date Format = " + dateFormat);

        Date dateParse = dateFormatter.parse(dateFormatter.format(calendar.getTime()));
        System.out.println("Date Parse  = " + dateParse);
    } catch (ParseException e) {
        // TODO: handle exception
    }
}


Output:
    Date Format = Fri, 16 Jan 1970 02:53:25 GMT
    Date Parse  = Fri Jan 16 03:53:25 GMT 1970
Run Code Online (Sandbox Code Playgroud)

如您所见,在日历对象的格式化和解析生成的String之间,一小时正在丢失.此外,输出的格式已更改.任何人都可以帮我解释为什么会发生这种情况,以及如何解决这个问题?我希望Date对象的格式与"Date Format"输出的格式相同.

Jon*_*eet 8

我相信这种情况正在发生,因为英国在1970年实际上没有使用GMT,而且Java有一个错误......它将在1970年格式化一个日期,好像英国正在使用GMT,但没有实际改变偏移量.简单的例子:

Date date = new Date(0);
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss zzz");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(sdf.format(date));
Run Code Online (Sandbox Code Playgroud)

结果:

01 Jan 1970 01:00:00 GMT
Run Code Online (Sandbox Code Playgroud)

请注意,它声称它是格林尼治标准时间凌晨1点......这是不正确的.这在欧洲/伦敦时间凌晨1点,但欧洲/伦敦没有观察GMT.

Joda Time得到了这个权利,它打印出BST - 但Joda Time不喜欢用时区缩写解析值.但是,您可以使用时区offets来代替它:

import org.joda.time.*;
import org.joda.time.format.*;

public class Test {
    public static void main(String[] args) throws Exception {
        DateTime date = new DateTime(0, DateTimeZone.forID("Europe/London"));

        DateTimeFormatter formatter = DateTimeFormat.forPattern(
            "dd MMM yyyy HH:mm:ss Z");

        String text = formatter.print(date); // 01 Jan 1970 01:00:00 +0100
        System.out.println(text);

        DateTime parsed = formatter.parseDateTime(text);
        System.out.println(parsed.equals(date)); // true
    }
}
Run Code Online (Sandbox Code Playgroud)