odd行为

ny6fqffe  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(295)

我正在尝试将在美国东部时区打印的日期转换为在gmt/utc打印的日期

package com.stefano;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class MainEntry {

/**
 * @param args
 * @throws ParseException 
 */

public static void main(String[] args) throws ParseException {

    String dateTime = "1307011200"; //12:00PM 01 July 2013
    System.out.println("Input -> " + dateTime);
    SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm");
    format.setTimeZone(TimeZone.getTimeZone("EST"));
    Date date = format.parse(dateTime);
    System.out.println("Intermediate -> " + date);
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    System.out.println("Output -> " + format.format(date));

    }

}

它的输出是:

Input -> 1307011200
Intermediate -> Mon Jul 01 17:00:00 BST 2013
Output -> 1307011600

尽管美国东部时间和格林威治标准时间之间的时差总是5,但不知何故,它与英国夏令时有关。
我不能利用乔达的时间。

trnvg8h3

trnvg8h31#

佐维茨的回答是正确的。

美国东海岸偏移

如果 EST 你指的是美国东海岸(和加拿大部分地区),那么你的说法呢 the time difference between EST and GMT is always 5 不正确。对于夏令时(dst),偏移量可以是-05:00或-04:00。事实上,您指定的日期时间确实有dst生效。

避免使用3-4个字母的时区代码

这三个或四个字母的时区代码既不是标准的,也不是唯一的。避开他们。使用正确的时区名称,其中大部分是大陆+城市。

与乔达时间的比较

为了比较,这里有一些joda时间示例代码。与java捆绑在一起的java.util.date&.calendar类非常麻烦,以至于每个java程序员都应该使用joda time或新的Java8java.time包(受joda time的启发,由JSR310定义)。
虽然java.util.date似乎有时区,但实际上没有,请注意,joda time datetime确实知道自己分配的时区。
joda time使用iso8601标准作为默认值。您也可以使用其他格式,如montré下面是一个例子。

示例代码

String input = "1307011200"; //12:00PM 01 July 2013
DateTimeFormatter formatterSmooshed = DateTimeFormat.forPattern( "yyMMddHHmm" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = formatterSmooshed.withZone( timeZoneNewYork ).parseDateTime( input );
DateTime dateTimeUtc = dateTimeNewYork.withZone( DateTimeZone.UTC );
String outputMontréal = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH ).print( dateTimeNewYork );
String outputSmooshed = formatterSmooshed.print( dateTimeNewYork ); // Expect same as input.

转储到控制台…

System.out.println( "input: " + input );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "outputMontréal: " + outputMontréal );
System.out.println( "outputSmooshed: " + outputSmooshed );

运行时…

input: 1307011200
dateTimeNewYork: 2013-07-01T12:00:00.000-04:00
dateTimeUtc: 2013-07-01T16:00:00.000Z
outputMontréal: lundi 1 juillet 2013 12 h 00 EDT
outputSmooshed: 1307011200
ej83mcc0

ej83mcc02#

parse(string)方法的javadoc引用parse(string,parseposition)方法,即:
此解析操作使用日历生成日期。因此,日历的日期时间字段和时区值可能已被覆盖,具体取决于子类实现。以前通过调用settimezone设置的任何时区值可能需要还原以进行进一步的操作。
因此,您不能使用此方法来告诉simpledateformat给定日期所在的时区。您可以这样修复此方法:

String dateTime = "1307011200"; // 12:00PM 01 July 2013
dateTime += " EST"; // append the timezone information to the input string
System.out.println("Input -> " + dateTime);
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm z"); // tell the formatter to look for the timezone info
Date date = format.parse(dateTime);
System.out.println("Intermediate -> " + date);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("Output -> " + format.format(date));

这也将使用本地时区打印date对象,但它显示了一种使用给定时区解析datetime字符串的方法。

相关问题